使用ShadowSocks搭建局域网翻墙网关(含DNS及路由优化)

出于业务需求,公司需要经常访问Google和Facebook服务,之前使用的各种VPN(PPTP)均不稳定,且速度很慢。经过一番研究,决定试用ShadowSocks(后面简称SS)。

整个环境搭建包括三步,分别是在境外服务器安装SS Server、在局域网网关服务器安装shadowsocks-libev及配置IPTABLES。

以下假设密码使用”password”
本日志描述过程均基于Ubuntu系统

1 在境外服务器安装SS Server

首先,修改系统配置以提升最大连接数量。
修改 /etc/security/limits.conf ,添加或修改如下项目:

1
2
3
4
root soft nofile 999999
root hard nofile 999999
* soft nofile 999999
* hard nofile 999999

编辑 /etc/pam.d/common-sessioncommon-session-noninteractive ,添加如下内容:

1
session required pam_limits.so

修改 /etc/sysctl.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
net.ipv4.ip_local_port_range=1024 65000
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=15
net.core.netdev_max_backlog=4096
net.core.rmem_max=16777216
net.core.somaxconn=4096
net.core.wmem_max=16777216
net.ipv4.tcp_max_syn_backlog=20480
net.ipv4.tcp_max_tw_buckets=400000
net.ipv4.tcp_no_metrics_save=1
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_syn_retries=2
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_wmem=4096 65536 16777216
vm.min_free_kbytes=65536

重启机器。
然后安装SS Server:

1
2
apt-get install python-pip
pip install shadowsocks

启动服务 (并添加至 /etc/rc.local):

1
/usr/local/bin/ssserver -p 443 -k password -m "aes-256-cfb" -d start

2 在网关服务器安装并配置 shadowsocks-libev 和 IPTABLES

注意:以下步骤可能需要翻墙才能访问 -_-
若无法翻墙,可根据网站指示从源码编译 https://github.com/shadowsocks/shadowsocks-libev

1
2
3
4
wget -O- http://shadowsocks.org/debian/1D27208A.gpg | sudo apt-key add -
echo "deb http://shadowsocks.org/debian wheezy main" >> /etc/apt/sources.list
apt-get update
apt-get install shadowsocks-libev

编辑 /etc/shadowsocks.json:

1
2
3
4
5
6
7
8
9
{
"server":"server_ip",
"server_port":443,
"password":"password",
"local_address": "0.0.0.0",
"local": "0.0.0.0",
"timeout":15,
"method": "aes-256-cfb"
}

停止安装的 /etc/init.d/shadowsocks-libev 服务并禁用。

使用以下命令启动redir服务及tunnel服务 (并添加至 /etc/rc.local):

1
2
nohup /usr/bin/ss-redir -c /etc/shadowsocks.json -l 12345 &>> /var/log/ss-redir.log &
nohup /usr/bin/ss-tunnel -c /etc/shadowsocks.json -l 15353 -u -L 8.8.8.8:53 &>> /var/log/ss-tunnel.log &

ss-redir 用于网络流量转发(配合IPTABLES,见下)
ss-tunnel 用于配合DNSKeeper进行DNS请求转发(见下节),如果本地有其他DNS服务的话,请先停止并禁用

3 DNS Keeper

DNS Keeper为一个DNS代理服务器,大致工作原理是根据关键字判断查询的域名是国内还是国外,然后分别查询不同的上游DNS服务器(国外的通过上述15353端口经shadowsocks查询境外DNS服务器)。

DNS Keeper的安装配置方法参见 https://github.com/billtt/dnskeeper

在配置的时候,记得将production.json配置文件的foreignServer设置为本机地址及15353端口,以确保经过shadowsocks。

4 网关服务器上配置IPTABLES

编辑IPTABLES配置文件 (save/restore 文件), 在nat表中添加如下内容

A 表示网关服务器出口(对外)子网地址段
B 表示局域网内网地址段

1
2
3
4
5
6
7
8
9
10
11
12
-N SHADOWSOCKS
-A SHADOWSOCKS -d A -j RETURN
-A SHADOWSOCKS -d B -j RETURN
-A SHADOWSOCKS -d server_ip/32 -j RETURN
-A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
-A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN

# 中国区IP地址段

-A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 12345
-A PREROUTING -p tcp -j SHADOWSOCKS
-A OUTPUT -p tcp -j SHADOWSOCKS

其中 # 中国区地址段 用以下生成的内容替换,以跳过中国区的流量(不走海外服务器):

1
curl http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest | grep 'apnic|CN|ipv4' | awk -F\| '{ printf("-A SHADOWSOCKS -d %s/%d -j RETURN\n", $4, 32-log($5)/log(2)) }' > cn_rules.conf

以上命令的执行结果保存在文件cn_rules.conf中。

5 多远端管理

如果你像我一样有多个境外服务器(或IP地址),平时经常需要根据服务状况来切换的话,可以安装如下服务以实现在Web快捷切换:

https://github.com/billtt/catapult