在OpenWRT上配置Shadowsocks,并通过Dnsmasq+ipset按域名翻墙

前言

之前家里的路由器一直是连着VPN翻墙的,但随着最近网络环境的日益恶劣,PPTP VPN连接不是很稳定。最近花大价钱(40RMB/月)换了一个VPN服务商,发现他们还提供Shadowsocks代理方式翻墙,所以打算在路由器上装上Shadowsocks代理,期望能有更好的翻墙效果。同时,之前在路由器中设定的是按IP地址判定走VPN还是直连,但这种方式有个比较大的缺陷:没有办法很好的判定一些IP地址经常变化的网站(比如说Instagram)。后来网上搜索了下,发现用Dnsmasq+ipset可以很好的解决此问题,可以通过域名判定是否翻墙还是直连。

在安装和配置的过程中主要参考了如下两篇文章:
shadowsocks-libev项目网址:
下载地址:

shadowsocks在openwrt上有两个版本可用,一个是官方版本,支持ss-local建立socks代理;一个是专为openwrt优化的版本shadowsocks-libev-spec。这里,我采用的是shadowsocks-libev-spec。同时,在openwrt上,shadowsocks-libev依赖的ssl库有两个选择,一个是openssl, 一个是polarssl。这里我选择的是polarssl,这个版本更省空间。所以最终我下载的ipk文件为:shadowsocks-libev-spec-polarssl_2.2.1-1_ar71xx.ipk(请根据路由器平台下载对应的版本)

然后将ipk文件通过scp或其他方式上传到路由器,进行安装。安装命令如下:
# opkg update
# opkg install libpolarssl
# opkg install shadowsocks-libev-spec-polarssl_2.2.1-1_ar71xx.ipk

当前版本的shadowsocks依赖libpolarssl.so.7,但/usr/lib目录下没有这个文件,需要执行如下命令修复此问题,不然ss-redir无法运行:
# ln -s /usr/lib/libpolarssl.so /usr/lib/libpolarssl.so.7

修改/etc/shadowsocks/config.json,配置shadowsocks 账户。
{
    "server": "yourshadowsocksaddr",
    "server_port": 1875,
    "local_port": 1080,
    "password": "yourpassword",
    "timeout": 60,
    "method": "aes-128-cfb"
}
server,server_port,method是从shadowsocks服务器地址,端口及加密方法。这里要注意的是加密方法得用小写字母,不然可能无法连接到服务器。我之前就是这里写成了大写字母,调试了好多天都没有调通。还有一个要设定的值是local_port,我这里配置的是1080,后面进行firwall设置时会用到。

修改/etc/init.d/shadowsocks的boot函数如下:
boot() {
until iptables-save -t nat | grep -q "^:zone_lan_prerouting"; do
sleep 1
done
ipset create outwall hash:ip
start
}
这里主要是在shadowsocks服务启动时创建一个名为outwall的ipset,后面是firwall和dnsmasq里会用到(名字可以随便取,只要保持一致即可)。

修改/etc/init.d/shadowsocks的start和stop函数如下:
start() {
service_start /usr/bin/ss-redir -c /etc/shadowsocks/config.json -b 0.0.0.0 -u
service_start /usr/bin/ss-tunnel -c /etc/shadowsocks/config.json -b 0.0.0.0 -l 5300 -L 8.8.4.4:53 -u
/usr/bin/shadowsocks-firewall
}
stop() {
service_stop /usr/bin/ss-redir
service_stop /usr/bin/ss-tunnel
/etc/init.d/firewall restart
}
ss-redir服务是shadowsocks代理主服务。ss-tunnel应该是udp代理转发服务,后面dnsmasq的配置,就是通过此处的5300端口转发到shadowsocks服务端进行dns解析的。

在/usr/bin目录下创建shadowsocks-firewall脚本,并使用chmod +x将其改成可执行的。该脚本主要是用来配置防火墙规则的,我的配置如下:
#!/bin/sh

# create a new chain named SHADOWSOCKS

iptables -t nat -N SHADOWSOCKS

# Ignore shadowsocks server's addresses

iptables -t nat -A SHADOWSOCKS -d 66.154.119.55 -j RETURN

# Ignore LANs IP address

iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN

# Ignore address not in outwall ipset

iptables -t nat -A SHADOWSOCKS -m set ! --match-set outwall dst -j RETURN

# Anything else should be redirected to shadowsocks's local port

iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 1080

# Apply the rules

iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS
这里,局域网连接和不在outwall ipset中的连接都会直接反回,在outwall中的连接都会重定向到1080端口。(1080端口是之前配置的shadowsocks本地代理端口) 同时注意将shadowsocks server的ip地址66.154.119.55替换成正确的地址。

dnsmasq-full安装及配置

openwrt中的dnsmasq是不带ipset功能的,所以我们得删除掉自带的dnsmasq并安装带ipset功能的dnsmasq-full。安装命令如下:
# opkg remove dnsmasq
# opkg install dnsmasq-full

创建dnsmasq.d目录,并配置需要翻墙的域名:
mkdir /etc/dnsmasq.d
echo "conf-dir=/etc/dnsmasq.d" >> /etc/dnsmasq.conf

在dnsmasq.d目录下,创建gfwlist.conf文件,并在里面配置需要翻墙的域名。配置格式如下:
server=/google.com/127.0.0.1#5300
ipset=/google.com/outwall
说明:
第一行的意思是当解析google.com时,通过本地的5300端口进行解析。这里其实是使用了之前我们通过ss-tunnel启动的shadowsocks代理,转发的shadowsocks服务端进行解析的,这样就避免了DNS污染。
第二行的意思是,将解析到的google.com的IP地址,加入到我们在shadowsocks服务启动时创建的outwall ipset中。

这里给出我的gfwlist.conf配置文件示例:
# Google
server=/googleapis.com/127.0.0.1#5300
server=/googlesource.com/127.0.0.1#5300
server=/google-analytics.com/127.0.0.1#5300
server=/googlesyndication.com/127.0.0.1#5300
server=/apis.google.com/127.0.0.1#5300
server=/plus.google.com/127.0.0.1#5300
server=/imap.google.com/127.0.0.1#5300
server=/mail.google.com/127.0.0.1#5300
server=/gstatic.com/127.0.0.1#5300
server=/googleusercontent.com/127.0.0.1#5300
server=/google.com/127.0.0.1#5300
server=/google.com.hk/127.0.0.1#5300
server=/blogspot.com/127.0.0.1#5300
server=/blogger.com/127.0.0.1#5300
ipset=/googleapis.com/outwall
ipset=/googlesource.com/outwall
ipset=/google-analytics.com/outwall
ipset=/googlesyndication.com/outwall
ipset=/apis.google.com/outwall
ipset=/plus.google.com/outwall
ipset=/imap.google.com/outwall
ipset=/mail.google.com/outwall
ipset=/gstatic.com/outwall
ipset=/googleusercontent.com/outwall
ipset=/google.com/outwall
ipset=/google.com.hk/outwall
ipset=/blogspot.com/outwall
ipset=/blogger.com/outwall

# Youtube
server=/googlevideo.com/127.0.0.1#5300
server=/youtube.com/127.0.0.1#5300
server=/youtube-nocookie.com/127.0.0.1#5300
server=/ytimg.com/127.0.0.1#5300
server=/ggpht.com/127.0.0.1#5300
server=/youtu.be/127.0.0.1#5300
ipset=/googlevideo.com/outwall
ipset=/youtube.com/outwall
ipset=/youtube-nocookie.com/outwall
ipset=/ytimg.com/outwall
ipset=/ggpht.com/outwall
ipset=/youtu.be/outwall

# Facebook
server=/facebook.com/127.0.0.1#5300
server=/fbcdn.net/127.0.0.1#5300
ipset=/facebook.com/outwall
ipset=/fbcdn.net/outwall

# Twitter
server=/twitter.com/127.0.0.1#5300
server=/twimg.com/127.0.0.1#5300
server=/t.co/127.0.0.1#5300
ipset=/twitter.com/outwall
ipset=/twimg.com/outwall
ipset=/t.co/outwall

# Instagram
server=/instagram.com/127.0.0.1#5300
server=/cdninstagram.com/127.0.0.1#5300
ipset=/instagram.com/outwall
ipset=/cdninstagram.com/outwall

# Flipboard
server=/flipboard.com/127.0.0.1#5300
ipset=/flipboard.com/outwall

# Wikipedia
server=/wikipedia.org/127.0.0.1#5300
ipset=/wikipedia.org/outwall

# Github, Bitbucket, Stackoverflow
server=/github.com/127.0.0.1#5300
server=/bitbucket.org/127.0.0.1#5300
server=/stackoverflow.com/127.0.0.1#5300
ipset=/github.com/outwall
ipset=/bitbucket.org/outwall
ipset=/stackoverflow.com/outwall

# Others
server=/dropbox.com/127.0.0.1#5300
server=/wordpress.com/127.0.0.1#5300
server=/bit.ly/127.0.0.1#5300
server=/xda-developers.com/127.0.0.1#5300
ipset=/dropbox.com/outwall
ipset=/wordpress.com/outwall
ipset=/bit.ly/outwall
ipset=/xda-developers.com/outwall

常用命令:

更改dnsmasq conf文件后,可用如下命令重启dnsmasq服务:
/etc/init.d/dnsmasq restart
打开和关闭shadowsocks服务:
/etc/init.d/shadowsocks start
/etc/init.d/shadowsocks stop
配置shadowsocks服务开机启动:
/etc/init.d/shadowsocks enable

评论

  1. 谢谢分享。

    有一个问题一直困扰我。 这样配置以后, 服务会把VPS的地址当做的IP,在BT/PT下载的时候,无法被连接。 知道tracker的地址,怎样设置才能让tracker认到我的真实IP?

    回复删除
    回复
    1. 这个我也不清楚。不好意思,我对网络部分也不是很熟悉。翻墙设置什么的,都是按照别人的教程来的。

      删除

发表评论

此博客中的热门博文

通过串口root kindle voyage,并安装koreader

U-boot移植 (v2012.04.1 S3C2440平台)