WireGuard 是一个高性能、极简且易于配置的开源虚拟组网协议。本文实际演示如何使用 WireGuard 进行网络代理与国内外流量分流。
开启代理
现在客户端与服务端下生成各自密钥对
wg genkey | tee privatekey | wg pubkey > publickey
服务端
对服务端下的 /etc/wireguard/wg0.conf 配置文件进行编辑:
[Interface]
PrivateKey = <服务端私钥>
Address = 10.0.0.1/24
ListenPort = 51820
# 服务监听于 51820 端口
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# 开启 NAT 转发
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = <客户端公钥>
AllowedIPs = 10.0.0.2/32
启动隧道并开机自启:
sudo wg-quick up wg0
# 将 wg0 加入开机自启
sudo systemctl enable wg-quick@wg0
客户端
对服务端下的 /etc/wireguard/wg0.conf 配置文件进行编辑:
[Interface]
PrivateKey = <客户端私钥>
Address = 10.0.0.2/32
DNS = 8.8.8.8
# 为防止 DNS 污染,使用谷歌DNS进行解析
PostUp = ip route add <服务端公网IP> via <默认网关IP> dev eth0
# 保证使用全局代理时发送到服务器的数据使用默认网关
PostDown = ip route del <服务端公网IP> via <默认网关IP> dev eth0
[Peer]
PublicKey = <服务端公钥>
Endpoint = <服务端公网IP>:51820
AllowedIPs = 0.0.0.0/0
# 开启全局代理(ipv4)
PersistentKeepalive = 25
# 确保 NAT 存活
启动隧道并开机自启:
sudo wg-quick up wg0
# 将 wg0 加入开机自启
sudo systemctl enable wg-quick@wg0
注意:为避免环路,当设置 AllowedIPs = 0.0.0.0/0 时,WireGuard 并不会直接执行 ip route add 0.0.0.0/0 dev wg0 ,把所有流量添加到主表,而是使用以下命令:
# 1. 给 WireGuard 接口发出的包打上防火墙标记 51820
wg set wg0 fwmark 51820
# 2. 添加一条策略路由规则:所有没有标记 51820 的包,查找路由表 51820
ip rule add not fwmark 51820 table 51820
# 3. 添加另一条规则:对于主表(main),抑制所有前缀长度为 0 的默认路由(即默认路由),同时保证具体的直连路由仍然可用
ip rule add table main suppress_prefixlength 0
# 4. 在路由表 51820 中添加默认路由(走 wg0 接口)
ip route add 0.0.0.0/0 dev wg0 table 51820
如果希望直接把代理规则加入到主表中,我们可以修改AllowedIPs:
[Peer]
AllowedIPs = 0.0.0.0/1, 128.0.0.0/1
设置分流
刚才的配置文件中,我们使用了全局代理,我们希望仅设置国外的流量使用代理,为此我们需要在客户端的路由表中添加规则。
由于 Linux 会优先匹配掩码最小的的路由规则,因此,我们的想法是,获取所有的国内网段,将这些网段使用物理网卡的规则写入路由表中,以下脚本实现了这一点:
# 下载国内IP表
wget -O /tmp/cn_routes.txt https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
# 生成添加国内路由的命令文件
while read -r ip; do
# 这里假设物理网卡出口设备是eth0,需根据实际情况替换
echo "ip route add $ip dev eth0"
done < /tmp/cn_routes.txt > /tmp/add_cn_routes.sh
# 赋予执行权限并执行
chmod +x /tmp/add_cn_routes.sh
sudo /tmp/add_cn_routes.sh
# 清理
rm /tmp/cn_routes.txt /tmp/add_cn_routes.sh
当我们不需要时,执行以下脚本删除添加的路由规则:
# 下载国内IP表
wget -O /tmp/cn_routes.txt https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
# 生成删除国内路由的命令文件
while read -r ip; do
# 这里假设物理网卡出口设备是eth0,需根据实际情况替换
echo "ip route del $ip dev eth0"
done < /tmp/cn_routes.txt > /tmp/del_cn_routes.sh
# 赋予执行权限并执行
chmod +x /tmp/del_cn_routes.sh
sudo /tmp/del_cn_routes.sh
# 清理
rm /tmp/cn_routes.txt /tmp/del_cn_routes.sh
我们可以编辑 wg0.conf,并添加PostUp/PostDown来自动在开启/关闭时执行这两个脚本:
[Interface]
...
PostUp = /bin/bash <执行添加的脚本地址>.sh
PostDown = /bin/bash <执行删除的脚本地址>.sh
下一步
下一步可以做:
- 搭建旁路由为设备下的所有设备提供代理
- 编写自动化脚本自动添加新设备