基本结构

在图示的环境中,路由器Router管理着10.12.0.1/16的子网,Local WireGuard Client作为WireGuard客户端,想要与Proxy Node 2建立隧道以及10.0.0.0/24的子网,并作为Router的上游。然而由于一些ISP的原因,Node 2无法与Client建立牢固的UDP连接,这时候需要引入Node 1中转流量。理想状态下,配置完成后在PC进行traceroute,应该会得到以下输出:

traceroute 1.1.1.1
1 10.12.0.1
2 10.12.0.4
3 10.0.0.1
4 10.0.0.3
...Node2 ISP
6 1.1.1.1

现在我们从Node 1开始逐级配置。

配置流程

配置Node 1

本文假设已经配置了WireGuard子网中各Peer节点的基本配置,使各个Peer能相互连接。

首先要开启IPv4转发:

sysctl net.ipv4.ip_forward=1

然后在/etc/iproute2/rt_tables中插入1 mid来创建名为mid的路由表:

插入完成后效果如下:

cat /etc/iproute2/rt_tables
#
# reserved values
#
255 local
254 main
253 default
0 unspec
1 mid
#
# local
#
#1 inr.ruhep

再给mid路由表添加下一跳并启用路由表:

ip route add 0.0.0.0/0 via 10.0.0.3 table mid

再配置IP Rule让指定源IP通过mid路由表,这里我们需要配置10.12.0.0/16子网:

ip rule add from 10.12.0.0/16 lookup mid

此时还需要配置Node 2对应Peer的allowed-ips:

wg set wg0 peer {Node2_Public_Key} allowed-ips 0.0.0.0/0

此时来自10.12.0.0/16的流量都会发往Node 2。

配置Node 2

首先要开启IPv4转发:

sysctl net.ipv4.ip_forward=1

在nftables配置NAT规则:

cat /etc/nftables
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
chain input {
type filter hook forward priority 0; policy accept;
}
chain forward {
type filter hook forward priority 0;
iifname "wg0" accept
}
chain output {
type filter hook output priority 0;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 0; policy accept;
oifname "eth0" ip saddr 10.12.0.0/16 masquerade
oifname "eth0" ip saddr 10.0.0.0/24 masquerade
}
}

同时还需要在WireGuard配置文件中配置对端Peer的AllowedIPs:

[Peer]
PublicKey = {Public_Key}
AllowedIPs = 10.0.0.1/24, 10.12.0.0/16

启动WireGuard并应用nftables规则:

wg-quick up wg0 && systemctl restart nftables

此时代理链配置完成,进行traceroute测试:

traceroute 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 64 hops max, 52 byte packets
1 10.12.0.1 (10.12.0.1)
2 10.12.0.4 (10.12.0.4)
3 10.0.0.1 (10.0.0.1)
4 10.0.0.3 (10.0.0.3)
...{Node2 ISPs}
8 one.one.one.one (1.1.1.1)

其他场景

image-20231208171703625

有可能会出现一些特殊场景,比如在Node 1另外接入一台Node 3,并根据源地址进行分流,一部分地址走Node 2,一部分走Node 3。

此时Client与Node 1、Node 2建立了10.0.0.0/24的子网,Node 3想要接入Node 1并作为分流节点,就不能加入10.0.0.0/24的子网。假设Node 1连接10.0.0.0/24子网所用的网卡是wg0,需要在Node 1 上建立新的WireGuard配置文件命名为wg1,子网可以设成10.0.1.0/24,之后就可以重复上面的步骤:添加新的路由表,为路由表添加下一跳,设置IP Rule等。此时下一跳为Node 3。

不能让Node 3加入10.0.0.0/24再指定下一跳的原因是:在一个Wireguard配置文件里(如wg0),即使有多个Peer,Allowed-IPs为0.0.0.0/0的Peer有且只能有一个,下一跳指定为wg0的IP后,Wireguard会把流量重定向到Allowed-IPs为0.0.0.0/0的Peer。

所以上面设置IP route 的步骤也可以直接指定网卡,效果是一样的:

ip route add 0.0.0.0/0 dev wg0 table mid