一直计划把自己所用的翻墙方式写出来,一方面方便有共同爱好的人一起研究,还有一方面就是给自己做个记录。N年前就开始用路由器自动翻墙,从刚开始的Openvpn,到后来Openvpn+各种混淆防屏蔽。再到后来Shadowsocks的出现,Shadowsocks是我个人用得最久的一个翻墙工具,也是最稳定和最有效率的。如果有时间的话我打算把这个教程写成一个系列,因为翻墙可以有各种不同的方式,今天这个第一篇是我认为目前来说最有效率的一种,也是我自己在用的方案。
先说说路由自动翻墙的几种方式,第一种是通过iptables geoip模块来区分国内和国外的IP,国内直连,国外走Shadowsocks,通过这个geoip模块可以大大节省规则载入时间,规则载入到完成一般只需要几秒钟,这个也是本篇要介绍的内容。第二种,是通过chnroute把国内的IP通过iptables规则设置为直连,国外IP走Shadowsocks,这种方式效果跟第一种基本一样,但在路由器上执行几千条的iptables规则需要花3~10分钟(不同配置的路由器所需的执行时间不同),也就是说路由器开机要等好几分钟才能正常使用。第三种,通过ipset和dnsmasq建立一个gfwlist,把被gfw认证的IP添加到gfwlist中,走Shadowsocks,其他正常的网站全部直连。前面两种方式的好处是不会有盲点,所有国外网站都走Shadowsocks,如果你的服务器够快,甚至在一定程度上可以加速国外网站的访问。第三种方式适合服务器流量小需要节省流量的用户,通过黑名单走Shadowsocks,其他全部走直连,好处是节省服务器流量,缺点是会有盲点,目前来说没有一个100%完整或者说相对完整的gfwlist,有些网站被认证了或者刚刚得到此认证殊荣却不在现成的gfwlist中,所以还是会遇到不能访问的情况,遇到不能访问的网站只能手动来添加规则。
前面是闲聊,现在开始说正事,搭建环境需要以下两个条件:
- 一台能刷入Openwrt的路由器。(推荐配置:64M内存、32M Rom以上,最好带USB接口可插入U盘或移动硬盘把系统直接运行在外置的U盘或移动硬盘上。)
**20171025更新
如没有合适的路由器也可使用虚拟机来跑Openwrt,具体方案看这里**。
一个稳定的Shadowsocks账号 (推荐配置:一台国外的服务器或VPS,用于搭建翻墙所需要的Shadowsocks服务器、DNS转发服务等。)
服务器环境的搭建参考:
ShadowsocksR服务器搭建教程以及一键安装脚本
Openwrt上解决域名污染问题
服务器环境的搭建不再赘述,参考上述两篇就差不多解决了,下面重点来讲讲路由器上的设置。
如果环境许可的话建议上ShadowsocksR,相比Shadowsocks的话多了混淆,实际效率也相对更高些。
路由器上大概需要以下几个软件:
- Shadowsocks客户端
- dnsmasq-full (这个在本篇教程中非必需,自带的dnsmasq也够用)
- unbound
原版Shadowsocks推荐使用Shadowsocks-libev,可以从这个网址下载最新版:
https://sourceforge.net/projects/openwrt-dist/files/shadowsocks-libev/
也可以用opkg官方源直接安装,官方源中的版本我没用过,不清楚具体是什么版本,通常如果用原版协议我都是用libev版。
opkg install shadowsocks-client
ShadowsocksR只能自己编译了,编译教程参见:
编译 Openwrt ShadowsocksR
ramips架构的路由器可从上面直接下载我编译好的ipk,上面的ipk不定期会更新。
opkg update
opkg install iptables-mod-geoip iptables-mod-nat-extra
opkg remove dnsmasq && opkg install dnsmasq-full unbound
opkg install http://down.0066.in/openwrt/shadowsocksr/ramips/shadowsocksr-libev_2.4.5-6pre_ramips_24kec.ipk
/etc/init.d/shadowsocksr enable
dns污染的解决,参考前面提到的Openwrt上解决域名污染问题,这里就不再具体说明了。
首先修改一下shadowsocks的启动脚本,我通常的习惯是运行redir和local,redir主要是用来自动翻墙,local是做一个单独的socks5代理,如果没有需要的话就不用运行local,下面是我修改的shadowsocks启动脚本。
- /etc/init.d/shadowsocksr
#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org
START=95
SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1
start() {
service_start /usr/bin/ssr-local -c /etc/config/ssr-local.json -b 0.0.0.0
service_start /usr/bin/ssr-redir -c /etc/config/ssr-redir.json -b 0.0.0.0
# service_start /usr/bin/ssr-tunnel -c /etc/config/ssr-tunnel.json -b 0.0.0.0 -L 8.8.8.8:53 -u
}
stop() {
service_stop /usr/bin/ssr-local
service_stop /usr/bin/ssr-redir
# service_stop /usr/bin/ssr-tunnel
}
如果你需要使用Shadowsocks的UDP转发来解决dns问题,去掉上面的ssr-tunnel的#,使用ssr-tunnel的话就不需要unbound了。如果你不需要ssr-local可以在ssr-local所在的行首加#注释掉。
上述对应的配置样本我一并贴下。
/etc/config/ssr-redir.json
{ "server":"12.34.56.78", "server_port":443, "local_port":7070, "password":"FucKGFW", "timeout":600, "method":"chacha20", "protocol": "auth_sha1", "protocol_param":"", "obfs": "tls1.2_ticket_auth", "obfs_param": "", "redirect": "", "dns_ipv6": false, "fast_open": true }
/etc/config/ssr-local.json
{ "server":"12.34.56.78", "server_port":443, "local_port":1080, "password":"FucKGFW", "timeout":600, "method":"chacha20", "protocol": "auth_sha1", "protocol_param":"", "obfs": "tls1.2_ticket_auth", "obfs_param": "", "redirect": "", "dns_ipv6": false, "fast_open": true }
/etc/config/ssr-tunnel.json
{ "server":"12.34.56.78", "server_port":443, "local_port":5353, "password":"FucKGFW", "timeout":600, "method":"chacha20", "protocol": "auth_sha1", "protocol_param":"", "obfs": "tls1.2_ticket_auth", "obfs_param": "", "redirect": "", "dns_ipv6": false, "fast_open": true }
我用的是ShadowsocksR,如果你用的是原版自行修改相关的配置,至于fastopen,需要客户端和服务器的内核都在3.6以上同时服务器要开启相应的设置才能支持,如果不支持的话直接改false就可以了,如果支持的话推荐开起来,能提高不少效率。更多关于fastopen可参阅: https://zh.wikipedia.org/wiki/TCP快速打开
Shadowsocks的配置大概就这样了,下面说说iptables的配置。
首先需要先生成GeoIP的数据文件,数据的生成参考这篇:Debian下制作GeoIP数据库,下面提供现成的数据文件。
如果你不能确定你的路由器架构是BE还是LE,你可以同时下载两个,如果能确定BE/LE你只要下载一个就够了。
在路由器上直接下载数据文件:
mkdir -p /usr/share/xt_geoip/LE
mkdir -p /usr/share/xt_geoip/BE
wget http://down.0066.in/openwrt/geoip/LE/CN.iv4 -O /usr/share/xt_geoip/LE/CN.iv4
wget http://down.0066.in/openwrt/geoip/BE/CN.iv4 -O /usr/share/xt_geoip/BE/CN.iv4
上面的数据文件我会定期更新,随时可以下载到最新的版本。接下来编辑防火墙自定义规则。
- /etc/firewall.user
iptables -N fuckgfw -t nat
iptables -F fuckgfw -t nat
iptables -A fuckgfw -t nat -p tcp -s 192.168.1.7 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 12.34.56.78 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 10.0.0.0/8 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 127.0.0.0/8 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 169.254.0.0/16 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 172.16.0.0/12 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 192.168.0.0/16 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 224.0.0.0/4 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 240.0.0.0/4 -j RETURN
iptables -A fuckgfw -t nat -p tcp -d 17.0.0.0/8 --dport 5223 -j RETURN
iptables -A fuckgfw -t nat -p tcp --dport 1723 -j RETURN
iptables -A fuckgfw -t nat -p tcp -j REDIRECT --to-port 7070
iptables -A prerouting_rule -t nat -m geoip -p tcp ! --destination-country CN -j fuckgfw
说明一下,上面规则中192.168.1.7是我局域网中某个设备,我不需要它自动翻墙,所以单独把它排除了。12.34.56.78是Shadowsocks服务器的IP地址,其他的就是一些局域网内部地址了。
然后重启防火墙。
/etc/init.d/firewall restart
至此,所有步骤都完成,一台自动翻墙的路由诞生了!测试是否生效很简单,分别访问http://1212.ip138.com/ic.asp和http://down.0066.in/ip.address看提示的IP是什么,正常情况下第一个是你本地ISP的IP,第二个应该显示的是你Shadowsocks服务器的IP。
参考资料:http://blog.ch3n2k.com/posts/xin-de-ji-yu-openwrt-lu-you-qi-de-bu-wan-quan-zi-dong-fan-qiang-fang-an.html
添加最后一条规则时出现以下错误,请问如何解决
iptables -A prerouting_rule -t nat -m geoip -p tcp ! --destination-country CN -j fuckgfw
iptables: No chain/target/match by that name.
我的系统版本是OpenWrt Barrier Breaker 14.07 / LuCI Trunk (0.12+svn-r10530)
@Kronos 抱歉,太久没打理博客,回复晚了,确认一下iptables的模块安装是否完整,我刚刚自己通过上面的步骤部署了一台新的路由器,没有问题,不过我使用的版本是15.05.1,你用的版本老了一点,而且是trunk的分支,建议更换15.05.1稳定版。
最近用pcap_dnsproxy非常还用,博主可以试试,一直在你这里学习怎么编译ss的。
@zasl 谢谢推荐,看起来好像挺强大的,有时间再折腾下,我大概看了下,也是实现类似unbound的功能,不过pcap_dnsproxy支持协议更多些。
现在我只下载的是预编译的,版本有些老,在我的路由器上有崩溃的现象,除此之外用起来的效果还是非常不错的,但是自己小白,无法编译出来最新的版本,麻烦博主是否可以出个详细一些的教程来编译这个软件,非常感谢。
@zasl 我看了下,github上已经有比较详细编译的教程了,可以参考这里 : https://github.com/wongsyrone/openwrt-Pcap_DNSProxy/blob/master/README.md 应该不难的,编译都是大同小异的。
按照博主的文章部署成功~
现在还有一个守护进程没有做,可不可以增加一下呢?
哪个守护进程?ss有也自启动了,防火墙开机也会自动加载,还需要什么守护进程?
就是SSR-Watchdog,有时候ssr连不上网,手动重启一下就好了…
所以想做一个自动检测脚本,如果连不通就重启。但是不会写…
我编译的包里应该有,我不确定是哪个,可能是那个gfwlist的,我没装过,很少用到,我一般都写个手动切换的脚本,终端平常都开着,换服务器就运行下切换脚本。
cat >/etc/config/ssr-redir.json<<eof
{
xxxxxx
}
eof
killall ssr-redir
sleep 2s
/usr/bin/ssr-redir -c /etc/config/ssr-redir.json -b 0.0.0.0 &
多谢!
确实是在gfwlist那个包里面有watchdog.
我也搞不清楚为什么会出现连不上的问题,只能用重启大法了。。