利用shadowsocks实现OpenWRT路由器的自动翻墙

方案基于shadowsocks-libev的ss-redir功能,根据网上获取的一个路由表作为判定条件,将访问国外IP的流量转发至代理服务器。 不过ss-redir只支持TCP的转发,UDP的是不行的,因此要解决DNS问题,因为DNS默认是UDP。

要解决DNS解析问题,确保国内站点利用国内DNS解析,国外站点转发至代理服务器解析。显然在客户端完美实现比较困难,于是乎有个退而求其次的判断方法,同时对国内DNS和国外DNS(走代理)发起DNS请求,根据返回的IP地址判断采用哪个的结果(也就是我们用到的ChinaDNS用的方法):

1、国内DNS返回结果为国内IP,国外DNS返回结果同样为国内IP或者返回失败,则采用国内DNS解析结果;

2、国外DNS返回结果为国外IP,国内DNS返回结果同样为国外IP或者返回失败,则采用国外DNS解析结果;

3、国内DNS返回国内IP,国外DNS返回国外IP,则如果国内IP不在黑名单列表(GFW的DNS污染IP黑名单)中,采用国内IP,否则采用国外IP;

4、不符合上述结果的,返回失败。

另外对于某些客户端软件可能会使用UDP方式进行一些通讯,比如说外服游戏的客户端,这类软件,如果是PC上你还是老老实实用Proxifier之类的软件转发至本地的shadowsocks客户端吧,如果是手机上还是要老老实实开shadowsocks软件,并且要使用VPN方式。不过这类比较非常少见,大部分情况,被墙的服务还是采用TCP的。

介绍完以上需要预先了解的内容后 让我们开始正题。

首先,准备好相应软件的ipk包,源码可以在这两个地方下载到(注意这里用到的shadowsocks不是官方版本):

https://github.com/aa65535/openwrt-shadowsocks

https://github.com/aa65535/openwrt-chinadns

预编译好的版本在这里(上面两个页面也有链接):

http://sourceforge.net/projects/openwrt-dist/files/shadowsocks-libev/

http://sourceforge.net/projects/openwrt-dist/files/chinadns-c/

里面可能有多个文件夹,是不同版本的,找到最新版本的文件夹点进去,然后根据自己路由器CPU的类型,选择相应的包下载。

以水星4530R为例,CPU类型是AR71XX,

ChinaDNS-C里面找到:

ChinaDNS-C_1.1.4_ar71xx.ipk

shadowsocks-libev里面找到:

shadowsocks-libev_1.4.6-3_ar71xx.ipk

不过上面的shadowsocks的包去掉了ss-tunnel功能,这个功能我们要用到,于是我们还要下载它正上方那个extra包:

shadowsocks-libev-extra_1.4.6-3_ar71xx.ipk

总共这三个包,先下载下来,放到路由器的/tmp下面

(PS:这里的shadowsocks版本用的是libopenssl,如果想用libpolarssl的可以下载对应的另外两个包)

SSH连接路由器,cd到/tmp目录,分别输入下面每行代码并回车等待每项的安装完成:

opkg install ChinaDNS – C_1 . 1.4_ar71xx.ipk

opkg install shadowsocks – libev_1 . 4.6 – 3_ar71xx.ipk

opkg — force – overwrite install shadowsocks – libev – extra_1 . 4.6 – 3_ar71xx.ipk

显示安装成功后,我们需要进行一些配置。

首先配置shadowsocks的config.json文件,格式就不多说了,如果不懂,建议还是先了解下shadowsocks再看这篇文章,请阅读官网shadowsocks.org的说明,以及各位作者在github上的readme,还可以参考这篇:

{

“server” : “X.X.X.X” ,

“server_port” : “443” ,

“password” : “password” ,

“local_port” : “1080” ,

“method” : “aes-256-cfb” ,

“timeout” : “600”

}

接下来,更改DNS功能。

先启动shadowsocks:

/ etc / init .d / shadowsocks enable

/ etc / init .d / shadowsocks start

此时,ss-redir的TCP转发功能开启,同时又有ss-tunnel建立了一个隧道,会将5353端口的udp通讯通过shadowsocks转发至8.8.8.8:53上。

然后在LUCI的DHCP/DNS配置中,填入127.0.0.1#5353,将dnsmasq收到的DNS请求转发至shadowsocks。

luci-dns

同时,在wan接口的配置中,一定要把“使用端局通告的DNS服务器”的勾去掉,并且下面的框留空。

wan-dns

最后我们更改ChinaDNS的端口,打开/etc/init.d/chinadns,将其中start()和stop()两个函数部分修改,修改后结果如下,修改过的行已经高亮标出:

start ( )

{

if [ – f $PIDFILE ]

then

echo “already started: $PIDFILE exists”

exit 1

fi

chinadns \

– l / etc / chinadns_iplist .txt \

– c / etc / chinadns_chnroute .txt \

– p 5050 \

– s 114.114.114.114 , 127.0.0.1 \

1 > / tmp / log / chinadns .log \

2 > / tmp / log / chinadns .err .log &

echo $ ! > $PIDFILE

iptables – t nat – A PREROUTING – p udp — dport 53 – j REDIRECT — to – ports 5050

}

stop ( )

{

iptables – t nat – D PREROUTING – p udp — dport 53 – j REDIRECT — to – ports 5050

kill cat $PIDFILE

rm $PIDFILE

}

可以看到,我们是把默认的5353端口改成了5050,然后通过iptables配置入站的53端口udp通讯转发至自己的5050端口,当然也可以凭你自己爱好改成别的。除此之外下面这行参数是我们添加的,目的是国内DNS用114,国外则转发到路由器本身的dnsmasq:

– s 114.114.114.114 , 127.0.0.1
这样,就形成了这么一条DNS查询链:

国外:Client—ChinaDNS—dnsmasq—shadowsocks—代理服务器—GoogleDNS

国内:Client—ChinaDNS—114DNS

为什么这样改呢?ChinaDNS默认对国外DNS查询是直接查询Google DNS和OpenDNS,并非走代理服务器,而Google DNS和OpenDNS都是根据查询源的IP给出结果,也就是,得到的结果依然是按照你在中国来给的,这就导致了一下情况:假设你的代理服务器在美国,你访问google.com,而此时DNS解析的结果可能给出的是香港服务器的IP,这样就饶了一个大圈。我们应该让这个查询走代理服务器,这样DNS查询的发起者就是你的代理服务器,这样才合理。

全部修改完成后,启动ChinaDNS即可:

/ etc / init .d / chinadns enable

/ etc / init .d / chinadns start

Enjoy~~ 4MB小水管U2B 720P视频速度测试:

u2bspeed

PS:chnroute需要定期更新,可以使用下面的命令(需要libcurl和curl两个包):

curl ‘http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest’ | awk – F \ | ‘/CN|ipv4/ { printf(“%s/%d\n”, $4, 32-log($5)/log(2)) }’ > / etc / shadowsocks / ignore .list 当然你也可以重新下载新版的shadowsocks重新安装。

PS2:路由器运行shadowsocks不如PC机稳定,性能也差很多,如有异常请重启服务试试