Linux代理路由设置
socks5 代理转发
由于我们VPS上部署的是一个 socks5 代理,相应的我们需要一个 socks5 的客户端。寻寻觅觅,终于让我找到了:redsocks。
redsocks – transparent TCP-to-proxy redirector
This tool allows you to redirect any TCP connection to SOCKS or HTTPS proxy using your firewall, so redirection may be system-wide or network-wide.
详细的功能与说明可以在 Github 上查看,我们直接把它 git clone 下来:
git clone git@github.com:darkk/redsocks.git
由于编译需要依赖到 libevent,我们先安装一下:
sudo apt install gcc libevent-dev
然后就可以开始编译 redsocks:
cd redsocks make
注意:
- 虽然我们也可以直接用 github 上 release 的版本,不过尽量使用最新的代码避免一些bug;
- 之前在 OpenWrt 上测试,无奈默认的 ipk 版本是 0.4 ,bug比较多无法正常使用,而自己也不想折腾着去编译 openwrt 版本的 ipk,故放弃了;
配置文件也比较简单,参考目录下的 redsocks.conf.example,主要修改:
base { log_debug = on; # 打开debug log,出现问题容易排查 log_info = on; log = stderr; daemon = off; redirector = iptables; # 我们后面将使用 iptables 来转发tcp流量 } redsocks { local_ip = 0.0.0.0; # 这个需要绑定到全部接口 local_port = 12345; ip = your socks5 proxy server; port = your socks5 proxy port; type = socks5; }
然后就可以开始运行:
./redsocks -c redsocks.conf
设置 iptables
参考官方的示例,添加 iptables 规则:
# Create new chain root# iptables -t nat -N REDSOCKS # Ignore LANs and some other reserved addresses. root# iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN root# iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN root# iptables -t nat -A REDSOCKS -d 100.64.0.0/10 -j RETURN root# iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN root# iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN root# iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN root# iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN root# iptables -t nat -A REDSOCKS -d 198.18.0.0/15 -j RETURN root# iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN root# iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN # Anything else should be redirected to port 12345 root# iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345 # 这里假设我们使用的wifi网卡接口是 wlan0 # 将 wlan0 的 tcp 流量转发到 redsocks root# iptables -t nat -A PREROUTING -i wlan0 -p tcp -j REDSOCKS
这时候,如果我们手机连接上这个 wifi 热点,那么所有的请求流量都会转发到 redsocks,再转发到我们的 socks5 代理服务器。
DNS 污染
通过上面的配置之后,虽然流量已经走 socks5 代理服务器了,然而我们很大概率会发现 google 仍然打不开。
What the f**k?(黑人问号)
仔细观察后我们便发现了,redsocks 虽然转发了流量,但是在 socks5代理服务器的日志中请求的 ip 却似乎有点问题,也就是说本地的 DNS 域名解析存在猫腻。
这便是所谓的 DNS污染,又称DNS投毒(总有刁民想害朕系列……)
对于DNS污染的问题,我们可以通过自建DNS服务器来解决,网上也有比较多的文章介绍,这里便不再重复了。需要注意的是,如果自建DNS服务器,不能使用境外的VPS,否则经过GFW的数据包回来之后大概率又中毒了。
不过,在这里我们可以更加简单地解决这个问题,因为我们树莓派搭建wifi热点的时候,使用的是 dnsmasq,它本身就是一个DNS服务器,所以我们可以直接配置 ChinaDNS 来解决。
ChinaDNS
从 github 下载它的 release 源码,然后解压并编译:
wget https://github.com/shadowsocks/ChinaDNS/releases/download/1.3.2/chinadns-1.3.2.tar.gz tar -zxvf chinadns-1.3.2.tar.gz cd chinadns-1.3.2 ./configure && make # 编译后的二进制文件在 src 目录中 cd src
然后我们需要更新一下 chnroute,获取国内的ip地址段。如果通过 114 DNS(114.114.114.114)解析后得到的是国内ip,则可直接使用;否则应该使用OpenDNS(208.67.222.222:443)解析的结果:
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
然后运行 chinadns(这里我们将本地DNS服务监听在15353,避免跟dnsmasq冲突):
./chinadns -v -p 15353 -m -c chnroute.txt -s 114.114.114.114,208.67.222.222:443
然后修改一下 dsnmasq 的配置:
sudo vim /etc/dnsmasq.conf # 添加配置 no-resolv server=127.0.0.1#15353
然后重启一下 dnsmasq:
sudo service dnsmasq restart
至此,我们应该就可以成功 google 啦(撒花~
区分国内外流量
虽然我们已经成功达到了最开始的目标,不过目前看来还有一点小小的遗憾:连上这个wifi热点之后,所有的流量都会经过 socks5 代理。这样子访问国内的网站却反而变慢了,毕竟出国旅游回来绕了一大圈啊!
这个问题可以通过 iptables 来解决,我们前面已经获取到国内的ip地址段 chnroute.txt,直接全部添加到 iptables :
cat chnroute.txt |sudo xargs -I % iptables -t nat -A REDSOCKS -d % -j RETURN
这下子终于完美解决了~
#######################################
目录
- [安装redsocks]
- [配置iptables]
- 设置白名单
- 添加ssrstart ssrclose等便捷命令
- [sock5代理服务器运维]
- 令iptables永久生效,及安装pdnsd以DNS污染的解决办法
redsocks
首先安装redsocks并配置好socks5服务,将socket连接通过iptables重定向到redsocks监听的本地端口上时,redsocks能够实现透明代理
iptables
设置iptables,我们需要在nat表上新建一个链,命名为SSR
然后在SSR链上将所有TCP流量重定向到redsocks监听的本地端口上,并在OUTPUT链上将所有tcp流量跳转到SSR链上
sudo iptables -t nat -F # 清空nat表规则
sudo iptables -t nat -N SSR # 新建SSR链
sudo iptables -t nat -A SSR -j REDIRECT -p tcp --to-ports 12345 -m comment --comment 'redsocks全局SSR代理'
sudo iptables -t nat -A OUTPUT -j SSR -p tcp -m comment --comment '跳转到redsocks全局SSR代理'
现在我们来验证一下设置是否正确,如果可以telnet任何IP的任何端口就证明tcp流量被重定向到了redsocks程序,
kasumi@kasumi:~$ telnet google.com 80
Trying 172.217.24.14...
Connected to google.com.
Escape character is '^]'.
GET / HTTP/1.1
Host: google.com
^]
telnet> quit
Connection closed.
不过现在它不会返回我们任何数据,此时,系统内部发生了错误,因为发生了无限循环的重定向
kasumi@kasumi:~$ sudo service redsocks status
● redsocks.service - Redsocks transparent SOCKS proxy redirector
Loaded: loaded (/lib/systemd/system/redsocks.service; enabled; vendor preset: enabled)
Active: active (running) since 一 2019-11-11 12:08:52 CST; 2h 41min ago
Process: 1210 ExecStart=/usr/sbin/redsocks -c ${CONFFILE} (code=exited, status=0/SUCCESS)
Process: 1192 ExecStartPre=/usr/sbin/redsocks -t -c ${CONFFILE} (code=exited, status=0/SUCCESS)
Main PID: 1213 (redsocks)
CGroup: /system.slice/redsocks.service
└─1213 /usr/sbin/redsocks -c /etc/redsocks.conf
11月 11 14:47:41 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 10797 ms: Too many open files
11月 11 14:47:52 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 21279 ms: Too many open files
11月 11 14:48:13 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 24326 ms: Too many open files
11月 11 14:48:38 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 26179 ms: Too many open files
11月 11 14:49:04 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 692 ms: Too many open files
11月 11 14:49:04 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 605 ms: Too many open files
11月 11 14:49:05 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 5462 ms: Too many open files
11月 11 14:49:10 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 15419 ms: Too many open files
11月 11 14:49:26 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 7611 ms: Too many open files
11月 11 14:49:34 kasumi redsocks[1213]: accept: out of file descriptors, backing off for 45675 ms: Too many open files
我们要做的就是放行局域网和socks5代理服务器IP,此处我们往OUTPUT链里设置,设置到SSR链也可以,不过最好用SSR链专门来设置白名单
Chain_SSR="OUTPUT"
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 0.0.0.0/8
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 10.0.0.0/8
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 100.64.0.0/10
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 127.0.0.0/8
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 169.254.0.0/16
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 172.16.0.0/12
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 192.168.0.0/16
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 198.18.0.0/15
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 224.0.0.0/4
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 240.0.0.0/4
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment 'socks5代理服务器放行' -d 47.95.255.46
恭喜,现在可以全局了
设置白名单
release_domain="cip.cc"
sudo iptables -t nat -I SSR -j RETURN -m comment --comment '白名单域名:'"$release_domain" -d $release_domain
由于这个操作很频繁,所以我写了一行交互式的脚本
read -p 请输入要设置白名单的域名: release_domain && sudo iptables -t nat -I SSR -j RETURN -m comment --comment '白名单域名:'"$release_domain" -d $release_domain && sudo iptables -t nat -nvL --line-number
查看SSR链规则
kasumi@kasumi:~$ sudo iptables -t nat -nvL SSR --line-number
Chain SSR (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 RETURN all -- * * 0.0.0.0/0 122.51.162.249 /* 白名单域名:cip.cc */
2 346 20760 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* redsocks全局SSR代理 */ redir ports 12345
添加 ssrstart ssrclose 等自定义命令
在.bashrc中添加alias别名,从而提供一键启用/关闭代理的命令
alias ssrclose="sudo iptables -t nat -j RETURN -m comment --comment 临时关闭代理 -I SSR"
alias ssrstart="sudo iptables -t nat -j RETURN -m comment --comment 临时关闭代理 -D SSR"
alias ssrstatus="sudo iptables -t nat -nvL SSR --line-number"
function ssradd() {
read -p 请输入要设置白名单的域名: release_domain && sudo iptables -t nat -I SSR -j RETURN -m comment --comment '白名单域名:'"$release_domain" -d $release_domain && sudo iptables -t nat -nvL --line-number
}
socks5
使用国内服务器启用ssr client, 连接国外ssr server, 从而提供socks5服务
令iptables永久生效,及安装pdnsd以DNS污染的解决办法
- 什么是pdnsd
p dns d -> Proxy DNS Daemon
安装pdnsd执行tcp查询,主要配置如下
官方文档
62 server {
63 label = "root-servers";
64 root_server=on;
65 ip = 8.8.8.8;
66 timeout = 5;
67 uptest = query;
68 interval = 30m; // Test every half hour.
69 ping_timeout = 300; // 30 seconds.
70 purge_cache = off;
71 exclude = .localdomain;
72 policy = included;
73 preset = off;
74 }
启动本地DNS服务:
sudo pdnsd --tcp -mto -d
为了开机启动pdnsd,编辑 /etc/default/pdnsd
文件,修改下列行:
START_DAEMON=yes
接下来修改/etc/resolv.conf,将DNS改为127.0.0.1即可
见Github项目https://github.com/develon2015/mysocks5
END