如果你不想光为了透明代理而单独买一个可刷OpenWRT固件的路由器, 同时你在局域网内有至少一台linux机器(可虚拟机),那以下内容可以帮助你在不需要设置路由的情况下实现透明代理(当然本质上就是把那台机器当成路由来用)。
首先你需要一台linux桌面系统的机器,ubuntu/debian/centos等均可,能编译ss-libev/使用iptables(于是不能centos7,我不会调教那个firewall)。你可以使用真实机器(如树莓派)或虚拟机。如果使用虚拟机,网络类型需要设置为桥接到物理网络,如果是VMware,不要对“复制物理网络连接状态”打钩。我建议使用虚拟机或性能不差的真实机器,这样网速不会受到性能上的限制。
接下来,安装操作系统、安装编译依赖包、git clone ss-libev、configure、make等这里就不说了,网上说明有很多(虽然大多数是过时了)。
编译好后,如果你clone的是ssr的libev版本: https://github.com/shadowsocksr-backup/shadowsocksr-libev,里面自带了一个ssrlink.py,可以通过此脚本快速生成一个客户端使用的配置文件,例如执行:
python ssrlink.py ssr://MTkyLjE2OC4xLjI6MTA4MDphdXRoX2FlczEyOF9tZDU6YWVzLTEyOC1jZmI6dGxzMS4yX3RpY2tldF9hdXRoOk1USXpORFUyLz9vYmZzcGFyYW09ZEdWemRDNWpiMjAmZ3JvdXA9ZEdWemRB > config.json
即可生成一个配置好了的config.json
东西都准备好了,现在开始配置。首先是开启ipv4转发,编辑/etc/sysctl.conf,解除net.ipv4.ip_forward = 1的注释,或直接添加这么一行,保存文件,并执行sysctl -p使修改立即生效。然后,设置IP为静态的,例如你的路由器地址为192.168.0.1,那么你可以设置为192.168.0.2,具体设置方法参考linux文档。设置好以后,在需要全局代理的机器上,把网关地址改为192.168.0.2,测试能不能正常上网(现在还没有通过代理),如果不能,那检查防火墙配置,或尝试重启它再测试。能正常上网后再进行后面的配置。
然后,创建一个ipt.sh文件,文件内容如下:
#!/bin/bash
subnet="192.168.0.0/16" # your subnet config
localaddr="192.168.0.2" # this server ip (must be subnet ip)
boardcastaddr="192.168.0.255"
listenport=1080 # local listen port (tcp)
udplistenport=0 # set it if not the same udp port
NAT_OUTPUT=0 # if 0: do not need to set server ip
if [ $NAT_OUTPUT -eq 1 ]; then
serverip="100.86.100.10" # ss server ip (tcp)
serverip_udp="" # ss server ip (for udp), keep empty if the same
fi
iptables -t nat -D PREROUTING -p tcp -j SHADOWSOCKS
if [ $NAT_OUTPUT -eq 1 ]; then
iptables -t nat -D OUTPUT -p tcp -j SHADOWSOCKS
fi
iptables -t nat -F SHADOWSOCKS
iptables -t nat -X SHADOWSOCKS
iptables -t mangle -D PREROUTING -p udp -j SHADOWSOCKS
iptables -t mangle -F SHADOWSOCKS
iptables -t mangle -X SHADOWSOCKS
ip rule del fwmark 0x01/0x01 table 100
ip route del local 0.0.0.0/0 dev lo table 100
if [ $udplistenport -eq 0 ]; then
udplistenport=`expr $listenport`
fi
iptables -t nat -N SHADOWSOCKS
iptables -t nat -I PREROUTING -p tcp -j SHADOWSOCKS
if [ $NAT_OUTPUT -eq 1 ]; then
iptables -t nat -I OUTPUT -p tcp -j SHADOWSOCKS
fi
ip rule add fwmark 0x01/0x01 table 100
ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -N SHADOWSOCKS
iptables -t mangle -A SHADOWSOCKS -d ${boardcastaddr} -j RETURN
iptables -t mangle -A SHADOWSOCKS -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp --dport 137 -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp --dport 138 -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp -d ${localaddr} -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp -s ${localaddr} -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp -s ${subnet} -j TPROXY --on-port ${udplistenport} --tproxy-mark 0x01/0x01
iptables -t mangle -I PREROUTING -p udp -j SHADOWSOCKS
if [ $NAT_OUTPUT -eq 0 ]; then
iptables -t nat -A SHADOWSOCKS -d ${localaddr} -j RETURN
iptables -t nat -A SHADOWSOCKS -s ${localaddr} -j RETURN
else
iptables -t nat -A SHADOWSOCKS -d ${serverip} -j RETURN
iptables -t nat -A SHADOWSOCKS -s ${serverip} -j RETURN
if [ -z $serverip_udp ]; then
iptables -t nat -A SHADOWSOCKS -d ${serverip} -j RETURN
iptables -t nat -A SHADOWSOCKS -s ${serverip} -j RETURN
fi
fi
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d ${subnet} -j RETURN
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports ${listenport}
注意你应该按你的本地设定修改前四行的配置,一般你也只需要修改前四行的配置项就行了,然后保存并执行。执行后,它可以重定向你所有的出网TCP和UDP包。
最后,运行ss-redir:./ss-redir -c config.json -u
此时便应该是全局,可以愉快地玩耍了
注意的一点:UDP包如果不能成功转发,可能是被GFW拦截,那么这时只能更换服务器了。而这可能导致DNS查询失败,可以先把DNS设置为路由的DNS地址以便于排查问题。
ipt.sh参数说明:
listenport 应该与你的ss配置文件所配置的local_port一致
localaddr 你的这台linux机器的静态IP地址
subnet 你的局域网网络地址段
boardcastaddr 你的局域网的广播地址(地址段中最大的地址,由网络掩码决定)
其它说明:如果你不需要全局代理,你可以在ipt.sh中模仿以下指令
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
在此后面添加你不需要代理的地址段即可.
首先你需要一台linux桌面系统的机器,ubuntu/debian/centos等均可,能编译ss-libev/使用iptables(于是不能centos7,我不会调教那个firewall)。你可以使用真实机器(如树莓派)或虚拟机。如果使用虚拟机,网络类型需要设置为桥接到物理网络,如果是VMware,不要对“复制物理网络连接状态”打钩。我建议使用虚拟机或性能不差的真实机器,这样网速不会受到性能上的限制。
接下来,安装操作系统、安装编译依赖包、git clone ss-libev、configure、make等这里就不说了,网上说明有很多(虽然大多数是过时了)。
编译好后,如果你clone的是ssr的libev版本: https://github.com/shadowsocksr-backup/shadowsocksr-libev,里面自带了一个ssrlink.py,可以通过此脚本快速生成一个客户端使用的配置文件,例如执行:
python ssrlink.py ssr://MTkyLjE2OC4xLjI6MTA4MDphdXRoX2FlczEyOF9tZDU6YWVzLTEyOC1jZmI6dGxzMS4yX3RpY2tldF9hdXRoOk1USXpORFUyLz9vYmZzcGFyYW09ZEdWemRDNWpiMjAmZ3JvdXA9ZEdWemRB > config.json
即可生成一个配置好了的config.json
东西都准备好了,现在开始配置。首先是开启ipv4转发,编辑/etc/sysctl.conf,解除net.ipv4.ip_forward = 1的注释,或直接添加这么一行,保存文件,并执行sysctl -p使修改立即生效。然后,设置IP为静态的,例如你的路由器地址为192.168.0.1,那么你可以设置为192.168.0.2,具体设置方法参考linux文档。设置好以后,在需要全局代理的机器上,把网关地址改为192.168.0.2,测试能不能正常上网(现在还没有通过代理),如果不能,那检查防火墙配置,或尝试重启它再测试。能正常上网后再进行后面的配置。
然后,创建一个ipt.sh文件,文件内容如下:
#!/bin/bash
subnet="192.168.0.0/16" # your subnet config
localaddr="192.168.0.2" # this server ip (must be subnet ip)
boardcastaddr="192.168.0.255"
listenport=1080 # local listen port (tcp)
udplistenport=0 # set it if not the same udp port
NAT_OUTPUT=0 # if 0: do not need to set server ip
if [ $NAT_OUTPUT -eq 1 ]; then
serverip="100.86.100.10" # ss server ip (tcp)
serverip_udp="" # ss server ip (for udp), keep empty if the same
fi
iptables -t nat -D PREROUTING -p tcp -j SHADOWSOCKS
if [ $NAT_OUTPUT -eq 1 ]; then
iptables -t nat -D OUTPUT -p tcp -j SHADOWSOCKS
fi
iptables -t nat -F SHADOWSOCKS
iptables -t nat -X SHADOWSOCKS
iptables -t mangle -D PREROUTING -p udp -j SHADOWSOCKS
iptables -t mangle -F SHADOWSOCKS
iptables -t mangle -X SHADOWSOCKS
ip rule del fwmark 0x01/0x01 table 100
ip route del local 0.0.0.0/0 dev lo table 100
if [ $udplistenport -eq 0 ]; then
udplistenport=`expr $listenport`
fi
iptables -t nat -N SHADOWSOCKS
iptables -t nat -I PREROUTING -p tcp -j SHADOWSOCKS
if [ $NAT_OUTPUT -eq 1 ]; then
iptables -t nat -I OUTPUT -p tcp -j SHADOWSOCKS
fi
ip rule add fwmark 0x01/0x01 table 100
ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -N SHADOWSOCKS
iptables -t mangle -A SHADOWSOCKS -d ${boardcastaddr} -j RETURN
iptables -t mangle -A SHADOWSOCKS -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp --dport 137 -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp --dport 138 -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp -d ${localaddr} -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp -s ${localaddr} -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp -s ${subnet} -j TPROXY --on-port ${udplistenport} --tproxy-mark 0x01/0x01
iptables -t mangle -I PREROUTING -p udp -j SHADOWSOCKS
if [ $NAT_OUTPUT -eq 0 ]; then
iptables -t nat -A SHADOWSOCKS -d ${localaddr} -j RETURN
iptables -t nat -A SHADOWSOCKS -s ${localaddr} -j RETURN
else
iptables -t nat -A SHADOWSOCKS -d ${serverip} -j RETURN
iptables -t nat -A SHADOWSOCKS -s ${serverip} -j RETURN
if [ -z $serverip_udp ]; then
iptables -t nat -A SHADOWSOCKS -d ${serverip} -j RETURN
iptables -t nat -A SHADOWSOCKS -s ${serverip} -j RETURN
fi
fi
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d ${subnet} -j RETURN
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports ${listenport}
注意你应该按你的本地设定修改前四行的配置,一般你也只需要修改前四行的配置项就行了,然后保存并执行。执行后,它可以重定向你所有的出网TCP和UDP包。
最后,运行ss-redir:./ss-redir -c config.json -u
此时便应该是全局,可以愉快地玩耍了
注意的一点:UDP包如果不能成功转发,可能是被GFW拦截,那么这时只能更换服务器了。而这可能导致DNS查询失败,可以先把DNS设置为路由的DNS地址以便于排查问题。
ipt.sh参数说明:
listenport 应该与你的ss配置文件所配置的local_port一致
localaddr 你的这台linux机器的静态IP地址
subnet 你的局域网网络地址段
boardcastaddr 你的局域网的广播地址(地址段中最大的地址,由网络掩码决定)
其它说明:如果你不需要全局代理,你可以在ipt.sh中模仿以下指令
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
在此后面添加你不需要代理的地址段即可.
from https://breakwa11.blogspot.com/2016/11/blog-post.html
-------
ss-redir配合ipset转发TCP+UDP
想要使用ss-redir代理所有非中国大陆的UDP流量(用于打游戏),需要将ss的项目脚本稍作修改。本文提出一种修改后的脚本方案,可以支持代理不仅仅是53端口的UDP流量,而是所有境外IP的UDP流量。
我的电脑是Ubuntu 18.04,现假设ss的服务器IP为
123.123.123.123
,本地ss-redir端口为12345
(下文同)
广告:推荐使用搬瓦工(BandwagonHost),一键部署shadowsocks,轻松切换机房,点我直达购买搬瓦工!
要想代理UDP流量,首先要在服务端开启UDP转发(这不是废话)。ss-server启动参数带上
-u
即可。最简单的例子
在shadowsocks-libev项目主页上的ss-redir例子是如下
iptables -t nat -N SHADOWSOCKS
iptables -t mangle -N SHADOWSOCKS
iptables -t nat -A SHADOWSOCKS -d 123.123.123.123 -j RETURN
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
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 12345
ip route add local default dev lo table 100
ip rule add fwmark 1 lookup 100
iptables -t mangle -A SHADOWSOCKS -p udp --dport 53 -j TPROXY --on-port 12345 --tproxy-mark 0x01/0x01
iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS
iptables -t mangle -A PREROUTING -j SHADOWSOCKS
ss-redir -u -c /etc/config/shadowsocks.json -f /var/run/shadowsocks.pid
项目主页的这个例子,可以实现TCP全局代理,UDP只代理53端口。
代理分流(启动)
我们可以借鉴luci-app-shadowsocks项目的ss-rules脚本实现TCP+UDP代理。
更新中国大陆的路由表
wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | awk -F\| '/CN\|ipv4/ { printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > ~/route.txt
为了减少路由表的体积,可以使用cidrmerge精简合并(可选步骤,实测体积减少20KB左右)
给出完整的启动脚本
#! /bin/bash
ss_server_ip=123.123.123.123
ss_redir_port=12345
ss_redir_pid=/var/run/shadowsocks.pid
ss_config_file=/etc/config/shadowsocks.json
chnroute_file="~/route.txt"
# 开启redir
ss-redir -u -c $ss_config_file -f $ss_redir_pid
# IP内网地址
BYPASS_RESERVED_IPS=" \
0.0.0.0/8 \
10.0.0.0/8 \
127.0.0.0/8 \
169.254.0.0/16 \
172.16.0.0/12 \
192.168.0.0/16 \
224.0.0.0/4 \
240.0.0.0/4 \
"
ipset create ss_bypass_set hash:net
# 添加内网地址到ipset
for line in $BYPASS_RESERVED_IPS; do
ipset add ss_bypass_set $line
done
# 添加ss地址到ipset
ipset add ss_bypass_set $ss_server_ip
# 添加chinaroute到ipset
if [ -f $chnroute_file ]; then
IPS=`which ipset`
$IPS -! restore <<-eof --match-set="" --on-port="" --set-mark="" --to-ports="" --tproxy-mark="" -a="" -e="" -j="" -m="" -n="" -p="" -t="" -v="" 0x01="" 100="" 1="" add="" apply="" chnroute_file="" code="" default="" dev="" does="" dst="" echo="" egrep="" else="" eof="" exist="" fi="" for="" fwmark="" hina="" ip="" iptables="" is="" lo="" loaded="" local="" lookup="" mangle="" mark="" nat="" not="" output="" prerouting="" redirect="" return="" route="" rule="" s="" sed="" set="" shadowsocks_tcp="" shadowsocks_udp="" shadowsocks_udp_mark="" ss-redir="" ss_bypass_set="" ss_redir_port="" table="" tcp="" tproxy="" udp="" was="" x01="">-eof>
接着设定Ubuntu的DNS为8.8.8.8,或者使用各种抗DNS污染的方案,清理DNS缓存后就能实现TCP+UDP分流
如何验证UDP转发是有效的呢?可以在ss-redir启动时候使用
-v
参数调试。代理分流(关闭)
开启代理分流后,如何恢复为启动ss-redir前的iptables规则呢?
给出完整的关闭脚本
#! /bin/bash
ss_redir_pid=/var/run/shadowsocks.pid
# TCP规则
iptables -t nat -D OUTPUT -p tcp -j SHADOWSOCKS_TCP
iptables -t nat -F SHADOWSOCKS_TCP
iptables -t nat -X SHADOWSOCKS_TCP
# UDP规则
iptables -t mangle -D PREROUTING -p udp -j SHADOWSOCKS_UDP
iptables -t mangle -D OUTPUT -p udp -j SHADOWSOCKS_UDP_MARK
iptables -t mangle -F SHADOWSOCKS_UDP
iptables -t mangle -X SHADOWSOCKS_UDP
iptables -t mangle -F SHADOWSOCKS_UDP_MARK
iptables -t mangle -X SHADOWSOCKS_UDP_MARK
ip route del local default dev lo table 100
ip rule del fwmark 1 lookup 100
# 删除ipset
ipset destroy ss_bypass_set >/dev/null 2>&1
# 杀死进程
kill -9 `cat $ss_redir_pid`
echo "ss-redir is stopped"
最后修改为正常的运营商DNS即可。
另一种方法,是启动ss-redir前使用iptables-save备份,使用完毕后iptables-restore还原。
参考文章
--------------------
利用shadowsocks打造局域网翻墙透明网关
如果手上仍然有树莓派又希望能利用上的,我个人有个更好一些的想法,就是将树莓派刷上lede,然后将其作为透明网关,原理和本文下面所述其实是一样的,只不过用lede和shadowsocks插件来取代下面这些繁琐的linux命令行配置
利用shadowsocks科学上网有很长时间了,一开始是在每个手机电脑客户端上都装ss,后来希望能在全家免配置翻墙,于是在路由器上面刷了梅林。不过毕竟支持刷固件的路由器有限,要是哪一天想换支持mesh的路由器就头疼了,于是想到了自建透明网关,这样无论用什么路由器只要能允许手动设置内网网关和DNS服务器那么无需依赖梅林固件也可达到局域网内所有设备自动科学上网的目的
大体思路是:
- dnsmasq+China DNS+ss-tunnel解决DNS污染的问题
- ss-redir配合iptables和ipset来分流国内流量和国外流量,这样国内的网站直连,而国外网站则走ss-redir
顺便提一下网关,网关其实含义非常丰富,在本文中所谓网关,可以是树莓派,可以是家庭服务器中的一个虚拟机,也可以是一台独立的PC,由于网关即为路由中的下一跳,所以局域网内所有的数据都会首先被发送到这台网关上,由它再来判断是直接发给目标地址,还是走ss。
如下分别是透明网关的物理结构图和数据流逻辑图
网关方案解析:
- dnsmasq主要起到DNS缓存作用,DNS请求会被发送给ChinaDNS,ChinaDNS会将请求同时发送给国内的DNS服务器和ss-tunnel,ss-tunnel负责relay给ss服务器,由于ss在国外不会被GFW污染,因此ChinaDNS会得到两个回复并判断其结果是否被污染,最终dnsmasq将得到未被污染的DNS应答
- iptables配合ipset负责区分国内和国外流量
网关硬件:
如前所述,可以是树莓派,可以是家庭服务器中的一个虚拟机,也可以是一台独立的PC
网关软件:
Ubuntu 14.04 (如果是树莓派可以是 Raspbian)
安装配置dnsmasq
- 安装dnsmasq
sudo apt-get install dnsmasq
2. 修改配置文件 /etc/dnsmasq.conf
no-resolv
server=127.0.0.1#5354
3. 启动dnsmasq
sudo service dnsmasq start
安装配置ChinaDNS
参考ChinaDNS的官方文档
- 下载ChinaDNS, 链接
- 编译
./configure && make
src/chinadns -m -c chnroute.txt
3. 编译后,将会在src目录里生成可执行文件chinadns,将其拷贝至 /usr/local/bin里面
sudo cp ./src/chinadns /usr/local/bin/
4. 在/etc/init.d/下创建名为chinadns的文件,将如下代码复制进去,记得执行
sudo chmod +x /etc/init.d/chinadns
以使其可执行#!/bin/sh ### BEGIN INIT INFO # Provides: chinadns # Required-Start: $network $local_fs $remote_fs $syslog # Required-Stop: $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start ChinaDNS at boot time ### END INIT INFO### Begin Deploy Path # Put this file at /etc/init.d/ ### End Deploy PathDAEMON=/usr/local/bin/chinadns DESC=ChinaDNS NAME=chinadns PIDFILE=/var/run/$NAME.pidtest -x $DAEMON || exit 0case "$1" in start) echo -n "Starting $DESC: " $DAEMON \ -c /etc/chinadns/chnroute.txt \ -m \ -p 5354 \ -s 114.114.114.114,127.0.0.1:5300 \ 1> /var/log/$NAME.log \ 2> /var/log/$NAME.err.log & echo $! > $PIDFILE echo "$NAME." ;; stop) echo -n "Stopping $DESC: " kill `cat $PIDFILE` rm -f $PIDFILE echo "$NAME." ;; restart|force-reload) $0 stop sleep 1 $0 start ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|force-reload}" >&2 exit 1 ;; esacexit 0
5. 启动/重启/停止 chinadns
sudo service chinadns start #启动chinadns
sudo service chinadns restart #重启chinadns
sudo service chinadns stop #停止chinadns
安装配置shadowsocks-libev(含有ss-redir以及ss-tunnel)
- 详细过程参见官方文档
- 如果是Ubuntu 14.04, 执行如下代码
sudo apt-get install software-properties-common -y
sudo add-apt-repository ppa:max-c-lv/shadowsocks-libev -y
sudo apt-get update
sudo apt install shadowsocks-libev
3. 配置/etc/shadowsocks-libev/config.json, 注意,111.111.111.111自己请替换为自己的VPS Server地址,密码“password”请自行修改
{
"server":"111.111.111.111",
"server_port":8388,
"local_address":"0.0.0.0",
"local_port":1080,
"password":"password",
"timeout":60,
"method":"aes-256-cfb",
"mode": "tcp_and_udp"
}
4. 启动ss-tunnel 与ss-redir,注意替换VPS IP和ss的密码password
nohup ss-redir -c /etc/shadowsocks-libev/config.json &
nohup ss-tunnel -s 111.111.111.111 -p 8388 -b 0.0.0.0 -l 5300 -k password -m aes-256-cfb -L 8.8.8.8:53 -u &
开启转发
- 修改 /etc/sysctl.conf, 取消注释:
net.ipv4.ip_forward=1
2. 执行命令使其生效
sysctl -p
配置iptables和ipset
- 生成国内IP地址的ipset
curl -sL http://f.ip.cn/rt/chnroutes.txt | egrep -v '^$|^#' > cidr_cn
sudo ipset -N cidr_cn hash:net
for i in `cat cidr_cn`; do echo ipset -A cidr_cn $i >> ipset.sh; done
chmod +x ipset.sh && sudo ./ipset.sh
rm -f ipset.cidr_cn.rules
sudo ipset -S > ipset.cidr_cn.rules
sudo cp ./ipset.cidr_cn.rules /etc/ipset.cidr_cn.rules
2. 配置iptables
iptables -t nat -N shadowsocks# 保留地址、私有地址、回环地址 不走代理 iptables -t nat -A shadowsocks -d 0/8 -j RETURN iptables -t nat -A shadowsocks -d 127/8 -j RETURN iptables -t nat -A shadowsocks -d 10/8 -j RETURN iptables -t nat -A shadowsocks -d 169.254/16 -j RETURN iptables -t nat -A shadowsocks -d 172.16/12 -j RETURN iptables -t nat -A shadowsocks -d 192.168/16 -j RETURN iptables -t nat -A shadowsocks -d 224/4 -j RETURN iptables -t nat -A shadowsocks -d 240/4 -j RETURN# 以下IP为局域网内不走代理的设备IP iptables -t nat -A shadowsocks -s 192.168.2.10 -j RETURN# 发往shadowsocks服务器的数据不走代理,否则陷入死循环 # 替换111.111.111.111为你的ss服务器ip/域名 iptables -t nat -A shadowsocks -d 111.111.111.111 -j RETURN # 大陆地址不走代理,因为这毫无意义,绕一大圈很费劲的 iptables -t nat -A shadowsocks -m set --match-set cidr_cn dst -j RETURN# 其余的全部重定向至ss-redir监听端口1080(端口号随意,统一就行) iptables -t nat -A shadowsocks ! -p icmp -j REDIRECT --to-ports 1080# OUTPUT链添加一条规则,重定向至shadowsocks链 iptables -t nat -A OUTPUT ! -p icmp -j shadowsocks iptables -t nat -A PREROUTING ! -p icmp -j shadowsocks
设置网关的默认网关
透明网关需要设置默认的下一跳地址,也就是说,网关在决定了数据包的路由之后应该把数据包送到哪里去,在我们的家庭局域网环境中这个下一跳就是路由器的地址
请留意,192.168.2.1应该是路由器的地址,有的是192.168.0.1,有的是192.168.1.1,需要查看具体的设置
p2p1是网卡,有时候可能是eth0,请自行通过
ifconfig
查看自己的网卡代号route del default
route add default gw 192.168.2.1 p2p1
设置路由器的DNS和DHCP网关
- 假设透明网关的IP地址是192.168.2.2,那么将路由器的DNS也设为192.168.2.2
- 在路由器的DHCP子项下面将路由器的内网网关设为192.168.2.2
参考文章
- https://junnan.org/2017/05/transparent-proxy-server-using-raspberrypi.html
- https://yuln.com/thread-30-1-1.html
- https://icymind.com/learn-from-gfw/
- https://github.com/yqsy/linux_script
from https://medium.com/@oliviaqrs/%E5%88%A9%E7%94%A8shadowsocks%E6%89%93%E9%80%A0%E5%B1%80%E5%9F%9F%E7%BD%91%E7%BF%BB%E5%A2%99%E9%80%8F%E6%98%8E%E7%BD%91%E5%85%B3-fb82ccb2f729
----------
在路由器上部署透明proxy
----------
在路由器上部署透明proxy
注意:以下内容在Netgear R7000 xwrt-merlin上经过测试。openwrt类似,还有更易用的LuCI图形化配置
思路:chinadns作为dnsmasq的上游,通过ss-tunnel查询国外dns服务器分辨投毒。利用iptables分流请求,ipset中储存国内IP地址与本地和保留地址,符合条件的直连,其余通过ss-redir转发至VPS
1. 配置entware环境
准备一个U盘,格式化为ext3(R7k merlin不支持ext4)。打开路由器的jffs。打开路由器的SSH,登录后:
entware-setup.sh
更新:
opkg update
opkg upgrade
安装sftp服务器便于文件传输:
opkg install openssh-sftp-server
安装lsof用于查看占用端口:
opkg install lsof
安装所需软件:
opkg install shadowsocks-libev-ss-redir
opkg install shadowsocks-libev-ss-tunnel
opkg install simple-obfs
opkg install chinadns
opkg install rng-tools // *obfs插件若提示收集不到足够的随机数,可安装rng-tools包
2. 配置SS与chinadns
测试redir是否能够正常工作:
ss-redir -s [VPS的IP地址] -p [服务器端口号,e.g. 8086] -b 0.0.0.0 -l [本地端口号,e.g. 1080] -k [密码,e.g. pass.123] -m chacha20-ietf-poly1305 -t 60 -u --plugin obfs-local --plugin-opts "obfs=tls;obfs-host=cloudfront.net"
redir启动脚本:
安装后默认生成配置文件 S22shadowsocks 于 /opt/etc/init.d 目录下,编辑其中内容
PROCS=ss-local 改为 PROCS=ss-redir
redir配置json:
{
"server": "[VPS的IP地址]",
"server_port": "[服务器端口号,e.g. 8086]",
"local_address": "0.0.0.0",
"local_port": "[本地端口号,e.g. 1080]", // 此处监听端口是转发流量的,记作portA
"password": "[密码,e.g. pass.123]",
"method": "chacha20-ietf-poly1305",
"timeout": 60,
"mode": "tcp_and_udp",
"plugin": "obfs-local",
"plugin_opts": "obfs=tls;obfs-host=cloudfront.net"
}
tunnel启动脚本:
直接复制一份 S22shadowsocks 的脚本,编辑其中内容
PROCS=ss-redir 改为 PROCS=ss-tunnel
tunnel配置json:
{
"server": "[VPS的IP地址]",
"server_port": "[服务器端口号,e.g. 8086]",
"local_address": "0.0.0.0",
"local_port": "[本地端口号,e.g. 1088]", // 此处监听端口是为chinadns服务的,记作portB
"password": "[密码,e.g. pass.123]",
"method": "chacha20-ietf-poly1305",
"tunnel_address": "8.8.8.8:53",
"mode": "tcp_and_udp",
"plugin": "obfs-local",
"plugin_opts": "obfs=tls;obfs-host=cloudfront.net"
}
chinadns启动脚本:
安装后默认生成配置文件 S56chinadns 于 /opt/etc/init.d 目录下,编辑其中内容
在 ARGS= 的后面追加 -s 114.114.114.114,127.0.0.1:[portB] ,114可更换任意国内可用的dns
并记下这里 -p 后的端口号,记作portC
更新chnroute:
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)) }' > /opt/etc/chinadns_chnroute.txt
3. 配置iptables分流,储存ipset列表
*可以用bestroutetb生成一个优化过chnroute,这个步骤需要在本地主机或者VPS上进行:
apt-get install npm
npm install -g bestroutetb
bestroutetb -p custom --rule-format=$'%prefix/%length\n' --group-header=$'---%name-start\n' --group-footer=$'---%name-end\n' --group-gateway -f -o /tmp/chnroutes.txt
sed -e '/---vpn-start/,/---vpn-end/d' -e '/^---/d' /tmp/chnroutes.txt > /tmp/tb.txt
生成的tb.txt备用
在ipset中生成两个直连的列表:
ipset create loprivate hash:net
ipset add loprivate 0.0.0.0/8
ipset add loprivate 10.0.0.0/8
ipset add loprivate 127.0.0.0/8
ipset add loprivate 169.254.0.0/16
ipset add loprivate 172.16.0.0/12
ipset add loprivate 192.168.0.0/16
ipset add loprivate 224.0.0.0/4
ipset add loprivate 240.0.0.0/4
以及:
ipset create chnip hash:net
while read rule; do (ipset add chnip $rule); done < /opt/etc/chinadns_chnroute.txt // *或者tb.txt
并保存:
ipset save > /opt/etc/saved.ipset
配置iptables:
iptables -t nat -N SHADOWSOCKS
iptables -t nat -A SHADOWSOCKS -d [VPS的IP地址] -j RETURN
iptables -t nat -A SHADOWSOCKS -m set --match-set loprivate dst -j RETURN
iptables -t nat -A SHADOWSOCKS -m set --match-set chnip dst -j RETURN
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports [portA]
4. 启动服务
使用脚本:
/opt/etc/init.d/[ss-redir脚本] start
/opt/etc/init.d/[ss-tunnel脚本] start
/opt/etc/init.d/[chinadns脚本] start
然后分别检查一下是否报错:
/opt/etc/init.d/[脚本] check
如果显示dead,一般是PROCS中名称有误,或者是端口被占用需要更换,也可能是配置文件语法错(漏了逗号?)
检查端口:
lsof -i |grep [端口号]
配置dnsmasq:
编辑 /etc/dnsmasq.conf
最后添加两行:
no-resolv
server=127.0.0.1#[portC]
并重启dnsmasq
使更改生效:
iptables -t nat -A PREROUTING -p tcp --dport 21:5000 -j SHADOWSOCKS
至此已实现分流与转发
5. 配置路由器的重启自动恢复
在 /jffs/scripts/ 下的 service-start 脚本最后添加内容:
ipset restore < /opt/etc/saved.ipset
iptables -t nat -N SHADOWSOCKS
iptables -t nat -A SHADOWSOCKS -d [VPS的IP地址] -j RETURN
iptables -t nat -A SHADOWSOCKS -m set --match-set loprivate dst -j RETURN
iptables -t nat -A SHADOWSOCKS -m set --match-set chnip dst -j RETURN
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports [portA]
iptables -t nat -A PREROUTING -p tcp --dport 21:5000 -j SHADOWSOCKS
新建 dnsmasq.postconf ,内容:
#!/bin/sh
CONFIG=$1
source /usr/sbin/helper.sh
pc_append "no-resolv" $CONFIG
pc_append "server=127.0.0.1#[portC]" $CONFIG
并赋予权限:
chmod a+rx /jffs/scripts/*
Reference:
https://icymind.com/learn-from-gfw/
https://gist.github.com/wen-long/8644243
https://blog.microdog.me/2016/06/28/Speed-Up-Network-Accessing-To-Overseas-Services-On-Your-Server/
http://www.q2zy.com/articles/2015/11/04/router-configuration-3/
https://xufooo.ml/2016/06/zybo%e5%bc%80%e5%8f%91%e6%9d%bflinux%e4%b8%8b%e9%80%8f%e6%98%8e%e4%bb%a3%e7%90%86fq%e4%bb%a5%e5%8f%8a%e5%8e%bb%e5%9b%bd%e5%86%85%e5%b9%bf%e5%91%8a/
https://zzz.buzz/zh/gfw/2016/02/16/deploy-shadowsocks-on-routers/
https://cokebar.info/archives/664
https://github.com/goodbest/Merlin-SS-config
https://github.com/YtnbFirewings/asus-merlin-cross-the-gfw
https://www.bjwf125.com/?p=9
https://fooy.github.io/blog/2016/06/18/setup-transparent-proxy-on-r7000/
No comments:
Post a Comment