轉: 配置一台基于openWRT的路由器使用shadowsocks并智能穿墙

2014/06/06

原文鏈接: http://hong.im/2014/03/16/configure-an-openwrt-based-router-to-use-shadowsocks-and-redirect-foreign-traffic/


配置一台基于openWRT的路由器使用shadowsocks并智能穿墙


本文中使用的路由器为 TP-LINK WR841N(D)V7
openwrt 版本为官方源中的 12.09 稳定版。
在路由器上使用 shadowsocks 的优势
  1. 尼玛 SS 真心快啊!我做过的不严谨测试貌似比 ipsec,PPTP 效率都要高一些。
  2. 因为 shadowsocks 是无状态的,所以相对来说也比较稳定。
  3. 服务器端和客户端的配置都相对来说比较简单,不容易出错。
  4. 路由器下面的所有设备都可以0 配置自动穿墙,你懂的。
  5. 要求的包都很小,我的渣 WR841ND 都能装下。不需要动手编译那么倒腾。
劣势
  1. 在路由器上无差别的对流量进行重定向,可能对某些用 NAS 挂 BT 的人不是很友好(符合规则的 P2P 流量也会被导向 shadowsocks 服务器),相对来说没有区分应用程序的代理“智能”。
  2. 目前为止似乎还不是很稳定,隔一段时间会挂掉一次。

在 openwrt 上安装相关的包

其中 shadowsocks 我们使用 shadowsocks-libev-polarssl(openssl 的 lib 比较大,塞不下……),可以从这里: http://buildbot.sinaapp.com下载,请注意选择符合您路由器 CPU 平台的包下载,这里我使用的是:shadowsocks-libev-polarssl_1.4.5_ar71xx.ipk
注:直接使用 wget 从站点下载会返回 403 Forbidden。目前原因未知。推荐先在电脑上下载下来,然后通过 winscp 等上传到路由器。
然后在路由器端刷新 opkg 缓存包并安装 shadowsocks:
opkg update
opkg install shadowsocks-libev-polarssl_1.4.5_ar71xx.ipk
我们需要编辑 shadowsocks 的配置信息 /etc/config/shadowsocks.json(新版默认的配置文件移动到了 /etc/shadowsocks.json 不过在后面启动的时候指定就好了,无影响。):
格式如下:
{
    "server":"[服务器 IP 地址]",
    "server_port":[服务器端口],
    "local_port":[本地端口, 稍后 iptables 会用到],
    "password":"[密码]",
    "timeout":600,
    "method":"[加密方式]"
}
在 12.09 上 shadowsocks 会因为缺少 libpolarssl.so.3 而无法启动,我们需要“欺骗”一下 shadowsocks:
注:我目前一切切换到 trunk 版本,不知道新版是否还存在这个 BUG,请自行测试能否启动。
ln -s /usr/lib/libpolarssl.so /usr/lib/libpolarssl.so.3
我们还需要安装额外的包,其中我们使用pdnsd(如果后面直接配置 dnsmasq 转发请求给 opendns 则不需要)来净化部分国外域名解析,用iptables-mod-nat-extra实现 iptables 流量转发到端口的功能:
opkg update
opkg install pdnsd  
opkg install pdnsd  iptables-mod-nat-extra

配置 pdnsd 对某些域名进行净化

我采用的基本思路是通过 pdnsd 使用 TCP 协议向国外的上级 DNS 查询而避过 DNS 污染,然后在本地提供一个 1053 端口的 DNS 供 dnsmasq 使用。如果全局使用 pdnsd 转发的国外 DNS 会导致国内某些网站或者服务访问较慢,不推荐。
另外一个思路是使用非标准端口查询,那么就可以不需要配置 pdnsd,直接在 dnsmasq 配置中将相关域名查询请求转发给支持非标准端口的 DNS 就行了,目前已知的是 opendns 支持 5353 端口和 443 端口。(即在 dnsmasq 段配置将 127.0.0.1#1053 替换为 208.67.222.222#5353 或 208.67.222.222#443 注意:未测试,仅理论分析)。
提醒一下:因为目前对 youtube 的封锁没有精确到 IP,只是 DNS 污染和关键字检测,所以一旦配置好 dns 净化,就已经可以通过https://www.youtube.com 访问 youtube 了。直连什么的,1080P 毫无鸭梨。而且不存在区域访问限制,很多挂 goagent 看不了的视频可以直接观看 OYE。
修改 pdnsd 的配置文件 /etc/pdnsd.conf
注意关注中文注释部分,其他部分如果您需要,再自行修改:
# 这一段全局配置需要修改:

global {
    # debug = on;          
    perm_cache=1024;
    cache_dir="/var/pdnsd";
    run_as="nobody";
    server_port = 1053;    # !!!使用 1053 作为 dns 端口, 默认是 53,一定要修改否则会跟默认 dnsmasq 冲突
    server_ip = 127.0.0.1;  # 我们只需要处理本机转发的 DNS 查询,所以不需要更改
    status_ctl = on;
    query_method=tcp_only; # !!!最重要的配置, 只使用 tcp 查询上级 dns
    min_ttl=15m;
    max_ttl=1w;
    timeout=10;
}

#……

# 自行增加下面这一段,pdnsd 默认是没有提供上游 DNS 服务器的(默认配置文件中用各种注释方式把自带的……):

server {
    label= "googledns";           # 这个 label 随便写
    ip = 8.8.8.8; # 这里为上级 dns 的 ip 地址,要求必须支持 TCP 查询,相关说明见后文注解
    root_server = on;        # 设置为 on。
    uptest = none;           # 不去检测 dns 是否无效.
}
        # …… 后面不需要修改的就不贴出来了。
注:DNS 地址如果不愿意倒腾可以使用 Google Public DNS。如果需要使用其他 DNS,请参考:http://public-dns.tk/ ,目前我使用的是台湾 TFN 的 DNS,解析出的地址比默认的 74 开头 IPping 值高一些但是访问很稳定(我猜是没有受到某的干扰。)。
启用 pdnsd,并设置为开机启动:
/etc/init.d/pdnsd enable
/etc/init.d/pdnsd start
设置 dnsmasq 对特定域名使用本地的 pdnsd 进行解析:
为了保持配置文件整洁,建议在 /etc/dnsmasq.conf 最后加入:
conf-dir=/etc/dnsmasq.d
然后新建目录 /etc/dnsmasq.d ,在里面加入一个 conf,名字任选。譬如 /etc/dnsmasq.d/fuckgfw.conf , 下面是我的文件内容,你可以按自己需要整理自己的:
#Google and Youtube
server=/.google.com/127.0.0.1#1053
server=/.google.com.hk/127.0.0.1#1053
server=/.gstatic.com/127.0.0.1#1053
server=/.ggpht.com/127.0.0.1#1053
server=/.googleusercontent.com/127.0.0.1#1053
server=/.appspot.com/127.0.0.1#1053
server=/.googlecode.com/127.0.0.1#1053
server=/.googleapis.com/127.0.0.1#1053
server=/.gmail.com/127.0.0.1#1053
server=/.google-analytics.com/127.0.0.1#1053
server=/.youtube.com/127.0.0.1#1053
server=/.googlevideo.com/127.0.0.1#1053
server=/.youtube-nocookie.com/127.0.0.1#1053
server=/.ytimg.com/127.0.0.1#1053
server=/.blogspot.com/127.0.0.1#1053
server=/.blogger.com/127.0.0.1#1053

#FaceBook
server=/.facebook.com/127.0.0.1#1053
server=/.thefacebook.com/127.0.0.1#1053
server=/.facebook.net/127.0.0.1#1053
server=/.fbcdn.net/127.0.0.1#1053
server=/.akamaihd.net/127.0.0.1#1053

#Twitter
server=/.twitter.com/127.0.0.1#1053
server=/.t.co/127.0.0.1#1053
server=/.bitly.com/127.0.0.1#1053
server=/.twimg.com/127.0.0.1#1053
server=/.tinypic.com/127.0.0.1#1053
server=/.yfrog.com/127.0.0.1#1053

配置 iptables 对流量进行智能转发

为了减少篇幅,直接给出成品的流量脚本吧。如果需要额外的解释,请看这里:https://github.com/haohaolee/shadowsocks-openwrt
我目前的策略是使亚洲的所有流量直接穿透,你也可以配置其他类型的路由表,请参考https://github.com/ashi009/bestroutetb
脚本地址:
http://codepad.org/WSC50Uzf
备用:
http://pastebin.com/2aZre9xL
我的做法是保存在usr/bin/ 里面,并命名为 ss-start.sh。当然命名这种事情随意啦。
启动服务器并重定向流量:
# 设置路由:
/usr/bin/ss-start.sh 
# 启动 shadowsocks
/usr/bin/ss-redir -c /etc/config/shadowsocks.json &
注意: 配置文件中的YOUR-SERVERS-IP-ADDRESS务必换成你的 shadowsocks 服务器的 IP 地址,否则一定会出问题。

其他问题

查看 iptables 的 NAT 表来检查路由表是否已经成功加载:
iptables -t nat --list
停止服务器:
killall ss-redir  # 关闭 shadowsocks。
/etc/initd.t/firewall restart # 清除流量重定向配置。
参考文章:
openwrt 上通过 pdnsd 和 dnsmasq 解决 dns 污染
https://github.com/haohaolee/shadowsocks-openwrt
更新历史:2014-05-25 小幅修正某些说法,话说乃们在 twitter 上收藏那么多吓到我了。
如果配置有问题请留言提出。

Related Posts