树莓派实现透明代理

性能不是太好,以下内容仅供参考

目标

希望连接到路由器的手机、电脑可以在不做任何配置的情况下,实现智能代理。为了实现这个目标,我们需要让所有的流量经过树莓派,由它来做处理,当识别为国内的流量,直接转发,国外网站的流量转发到Shadowsocks服务器上。

硬件准备

  1. 树莓派
  2. USB有线网卡
  3. 路由器
  4. 海外Shadowsocks服务器

连接方式

可以上网的网线接到树莓派上,树莓派接USB网卡,USB网卡接路由器上

配置转发功能

USB有线网卡插到树莓派上之后,使用ifconfig命令就会看到多出一个eth1的栏目,这个eth1就代表USB有线网卡

内核中启动NAT

# 开启ipv4数据包转发功能
sudo sysctl -w net.ipv4.ip_forward=1

# 开启NAT功能
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# 将来自eth1的包转发到eth0, 反向也要配置下(下面这两个命令试了试,貌似不敲也行)
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT

See also: 如何开启Linux双网卡的转发功能_linux 两个网卡转发数据包_kangear的博客-CSDN博客

eth1配置

我们计划给 eth1分配个 10.0.0.0/24的网段

文件/etc/dhcpcd.conf末尾增加两行

interface eth1
static ip_address=10.10.0.1/24

使用命令 service networking reload重新加载配置,使用ifconfig eth1查看是否生效。

dhcpd服务

这个时候手机连上路由器,发现并不能上网,连DNS都没有。所以我们要在树莓派上跑一个dhcpd服务。

https://mehmetburakeker.com/2017/06/05/raspberry-pi-dhcp-server/

See also:

sudo apt-get install isc-dhcp-server -y

修改 /etc/default/isc-dhcp-server 最后两行修改为

INTERFACESv4="eth1"
INTERFACESv6=""

一定不要把eth1写成eth0,不然连接的网络就会出现两个dhcp服务,造成严重的网路故障

/etc/dhcp/dhcpd.conf 增加

subnet 10.0.0.0 netmask 255.255.255.0 {
 range 10.0.0.10 10.0.0.30;
 option routers 10.0.0.1;
 option domain-name-servers 202.141.162.123;
}

202.141.162.123为华中科大的DNS(无污染)。可以使用dig @202.141.162.123 www.google.com测试下

使用命令sudo service isc-dhcp-server start启动服务,sudo service isc-dhcp-server status检查是否OK

这个时候手机连接上路由器,国内的网站应该可以连上了

配置Shadowsocks

安装Go, 从这个地方下载 https://golang.org/dl

go get -v github.com/shadowsocks/go-shadowsocks2

安装完之后,使用go-shadowsocks2启动一个 redir (Netfliter TCP redirect)服务

用命令启动redir服务,监听端口1082

shadowsocks2 -c 'ss://AEAD_CHACHA20_POLY1305:your-password@[server_address]:8488' -redir :1082

配置iptables

sudo -s # 切换到root

apt-get install -y ipset # 安装ipset

# 新建一个IP集,存放国内IP.
ipset -N chnroute hash:net maxelem 65536

# 获取中国IP段,并设置为跳过代理.如果Pi经常重启,还是不要每次拉了,我反正只是偶尔重启,而IP段归属是有可能变动的.
curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-extended-latest' | grep ipv4 | grep CN | awk -F\\| '{ printf("%s/%d\\n", $4, 32-log($5)/log(2)) }' > /tmp/chnroute.txt
for ip in $(cat '/tmp/chnroute.txt'); do
  echo ipset add chnroute $ip
  ipset add chnroute $ip
done

# 创建SHADOWSOCKS表
iptables -t nat -N SHADOWSOCKS

# 国内IP不走代理
iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set chnroute dst -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

# eth1的流量转发到1082端口
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT -i eth1 --to-ports 1082

# 转发路由
iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS

See also: 树莓派用作透明代理 – TaterLi 个人博客