x86 软路由透明代理构建方案
基本架构
网络配置:
双网卡 + NAT(iptable)+ DHCP
DNS 解析防污染:
overture(解析)+ dnsmasq(缓存)
代理:
shadowsocks(普通 Python 版即可)+ redsocks
透明代理:
iptable + ipset(国内 IP 段)
网络环境
主机是安装了 Ubuntu 14.04 的 x86 机器。双网卡分别是对接外网的网卡 p2p1,分配 IP 是 2.3.3.3(瞎说的);接内网的网卡 eth0,分配的 IP 是 192.168.3.1,也就是后面的 192.168.3.0/24 的子网的网关。
网络配置
开启双网卡
首先是装上双网卡肯定的。确保在系统里新装的网卡已经启用了,在 ifconfig 里能看到两个网卡。顺便记住并记牢接内外网的网卡的名字,我这里是内网 eth0,外网 p2p1。
接内网的网卡 eth0 可以自己配置静态 IP,这里不说了,网上一堆教程,无非就是在 /etc/network/interfaces
改配置。改完之后不知道怎么生效的就直接重启机器吧。
DHCP
先安装 DHCP 的服务器 sudo apt-get install isc-dhcp-server
。然后配置 DHCP 网卡 /etc/default/isc-dhcp-server
将INTERFACES=""
配置为对应内网网卡。
配置 /etc/dhcp/dhcpd.conf
更新 DHCP 服务器相关参数:
1 | subnet 192.168.3.0 netmask 255.255.255.0 { |
重新启动 DHCP 服务 sudo service isc-dhcp-server restart
NAT
首先,修改配置文件 /etc/sysctl.conf
里的net.ipv4.ip_forward=1
。要么取消注释,要么新加一行,然后 sysctl -p
让修改生效。
然后开始要动 iptables 了。iptables 这个东西很魔幻,遇到奇怪的坑很正常。
建议先 sudo apt-get install iptables-persistent
安装 iptables-persistent
来 save/reload/restart/restore 保存/重新加载/重启 iptable/重新加载配置。基本用法就是形如 sudo service iptables-persistent save
。玩溜了之后就开始搞 NAT。规则如下:
1 | EXTIF="p2p1" |
上面的 EXTIF 就是外网网卡,INTIF 就是内网网卡,不要搞错了。
正常情况下,save 配置并重启 iptables 之后,在 192.168.3.0/24 的子网里应该就可以连通外网了。
DNS 解析防污染
接下来要解决 DNS 解析结果被污染的问题。这里的坑不多。
overture
overture 是一个 Go 写的 DNS 解析器,支持中国特色社会主义的 DNS 解析。坑不大,到 github 上下载对应系统和架构的二进制包,解压出来就行了。然后把二进制程序丢到 /usr/local/bin
里面,顺便创建一个配置文件目录 /etc/overture
,然后把解压出来的其他文件放到配置文件目录里去。
我们的配置文件是让 overture 监听在 54 端口上,用来做 dnsmasq 的上游。
1 | { |
上面在 /etc/overture 的文件名自己对应修改。
至于 overture 怎么跑起来就见仁见智了。可以做 service 启动项,只不过我习惯用 supervisor 开机启动,因为配置文件简单好写。
到这里可以通过命令 dig @127.0.0.1 -p 54 www.google.com
看 overture 好使不。
dnsmasq
dnsmasq 我这里仅仅用来做缓存了,没有用其他功能。
先安装,sudo apt-get install dnsmasq
。然后到 /etc/dnsmasq.conf
里改一发配置:
1 | # 不读取 /etc/resolv.conf或者其他文件,取消注释即可,这样就可以在本文件里配置上游服务器 |
重启 sudo service dnsmasq restart
这里就可以简单的通过 dig www.facebook.com
选择一个以前没解析过的域名来看缓存生效么,第一次应该一两百毫秒,第二次开始就应该是 1-2 毫秒了。
代理
shadowsocks
之所以选择 shadowsocks(Python版) 而不是 C语言版的 shadowsocks-libev,一个是 x86 机器性能不是问题;二是 shadowsocks-libev 3.0 版以后在密码库的依赖上越走越远,导致各种依赖、编译特别麻烦;三是我这里用 redsocks 来做 tcp 到 sockv5 的转换,所以用不到 ss-redir 之类的东西。
这里没什么好说的,启动一个 sslocal 就好了,也像上面一样在 supervisor 里启动。但是有个坑,似乎 DNS 的解析逻辑有问题,最好 shadowsocks 的配置文件的 server 写 IP 地址,不要写域名。
redsocks
redsocks 是用来把普通的 tcp 流量转成 sockv5 的一个东西,承接 tcp 流量,转到 sslocal 里,功能和 ss-redir 一样的。
先安装,sudo apt-get install redsocks
。
然后改配置文件 /etc/redsocks.conf
,把 redsocks 部分里面的 port 改成你 sslocal 监听的地址,一般是 1080 吧。如果有奇怪的问题,可以把里面的 ip 和 local_ip 改成 0.0.0.0。
UPDATE:
使用过程中遇到一个问题,用着用着莫名其妙的翻不了了。看系统日志发现 redsocks 的 fd 用完,于是修改 /etc/init.d/redsocks
文件,在里面添加一条 ulimit -n 51200
。并且重启 redsocks 就好了。
透明代理
我的透明代理策略是国内 IP 不走代理,国外 IP 不管墙不墙都走代理。
ipset
ipset 是用来建立一个 IP 地址段的集合。用来存国内 IP 段的。
先把国内 IP 段搞出来,最新版可以这么搞来
1 | curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > chnroute.txt |
然后创建 ipset 并添加国内的 IP 段
1 | sudo ipset create chnroute hash:net |
iptable
接下来就要把流量做相应的转发了。
不要无脑粘贴,看一下注释。
1 | iptables -t nat -N SHADOWSOCKS |
然后还是用 iptables-persistent 保存配置并重启 iptables。
至此就应该 OK 了,要是还有什么坑,就没法管了。
至于效果嘛,现在路由翻墙可以跑满我们家百兆带宽了。