在树莓派上搭建全局透明代理网关

新剁手了一个Google Home mini,需要科学上网才能正常使用,而 home 本身不支持设置代理,所以需要在网关上动手。正好一直使用树莓派当路由器,所以尝试把树莓派打造成一个带有智能转发功能的透明网关,即国内的 IP 直连,海外的 IP 走代理加速。

配置无线网络

本文关注点不在此,所以一笔带过。

可以通过一键安装脚本 pi-setup-wifi.sh 来安装和配置树莓派的无线。该脚本会创建一个名为SSID,密码为PASSWORD的无线网络,使用的网段为 192.168.68/24

启动 TCPDNS 服务来避免 DNS 污染

出于性能和速度的考虑, DNS 协议使用了 UDP 这种不可靠的协议,这使得 DNS 解析污染出现,即被中间路由截获并返回了虚假的 IP 地址,因此我们需要建立一个可靠的 DNS 解析服务。

本文所采用的是 Tcp-DNS-proxy,它对客户端而言是透明的,与上游 DNS 服务器之间的通信采用了 TCP 协议。可以用其他工具替代。

1
git clone https://github.com/henices/Tcp-DNS-proxy.git

编辑配置文件 tcpdns.json.example,把端口修改成5353,修改DNS列表,只保留8.8.8.8/8.8.4.4,因为国内的 DNS 本身就已经被污染了,即使通信可靠,结果也是不可靠的。

1
sudo mv Tcp-DNS-proxy /usr/local

修改 DNS 服务器

编辑配置文件 /etc/dnsmasq.conf,在末尾添加

1
2
no-resolv
server=127.0.0.1#5353

不同网络层之间协议转换

安装 redsocks 来把无线网卡的流量转发到 socks5 代理,这本质上是转换两个不同网络层的流量。

1
sudo apt install -y redsocks

编辑配置文件 /etc/redsocks.conf

1
2
3
4
5
6
redsocks {
local_ip = 0.0.0.0;
local_port = 12345;
ip = 127.0.0.1;
port = 1080;
}

这里假设已经有一个开放在 1080 端口的 socks5 服务,可以使用 Shadowsocks 来创建一个。

重启 redsocks 以使配置生效

1
sudo service redsocks restart

忽略国内地址

安装 ipset 来生成国内地址列表

1
2
3
4
5
6
7
8
9
10
11
12
sudo apt install -y ipset

# 下载分配给国内运营商的 IP 段
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

# 创建一个集合并把上述IP段加进去
sudo ipset create chnroute hash:net

cat chnroute.txt | sudo xargs -I ip ipset add chnroute ip

# 上一条命令执行的非常慢,所以把结果保存下来,下次直接从文件恢复
sudo ipset save chnroute > /etc/chnroute.ipset

在系统重启后,使用如下命令来恢复ipset

1
ipset restore < /etc/chnroute.ipset

使用 iptables 来转发流量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sudo iptables -t nat -N SHADOWSOCKS

# 注意这里要把 $server_IP 改成你自己的 socks5 远程IP,即你的VPS IP,不然无法正常工作
sudo iptables -t nat -A SHADOWSOCKS -d $server_IP -j RETURN

# 忽略局域网地址
sudo iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -m set --match-set chnroute dst -j RETURN

# 把流量转发到 12345 端口,即redsocks
sudo iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 12345
sudo iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS
sudo iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS

覆盖设备自身的 DNS 服务器

因为 Google Home 内置了 DNS 服务器,而不是网关分配的,所以需要把流量截获然后转发到可靠的 DNS 解析。

1
2
sudo iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5353
sudo iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 5353

至此,搭建完毕,将 Google Home 连接到 wifi 上,就可以开始欢快的使用各种服务啦^_^。

参考链接及资源

利用shadowsocks打造局域网翻墙透明网关

用树莓派打造无线中继科学上网路由器

ss-redir 透明代理

Dnsmasq 介绍与使用

利用Dnsmasq部署DNS服务

DNSmasq 安装&配置详解

请教如何修改让dns强制重定向到路由

求推荐靠谱的防 dns 污染方案

dnsforwarder

Tcp-DNS-proxy

dns-over-https

https_dns_proxy

Pcap_DNSProxy