Wireguard 使用一个客户端作为另一个客户端的网关

Wireguard 使用一个客户端作为另一个客户端的网关

我有一个 Wireguard VPN 设置,基本上如下所示:

P1 ---- S ---- P2 --- Internet

IP 地址: P1 = 10.200.1.5 S = 10.200.1.1 P2 = 10.200.1.3

allowedIps = 0.0.0.0/0我通过在 P1 的客户端配置中指定将 P1 的所有流量重定向到 S。

现在我希望 S 将流量路由到 P2。我在 S 上尝试了以下操作:

 ip rule add from 10.200.1.5 lookup 200
 ip route add default via 10.200.1.3 dev wg0 table 200
 sysctl -w net.ipv4.ip_forward=1

但是,当我在 P2 上运行 tcpdump 时,我看不到任何流入的流量。此外,P1 也没有任何互联网连接。

编辑:通过以下方式测试 S 上的自定义路由表

ip route get 8.8.8.8 from 10.200.1.5 iif wg0

给出以下响应

8.8.8.8 from 10.200.1.5 via 10.200.1.3 dev wg0 table 200
    cache iif wg0

这看起来不错,但是

tcpdump -nn -i wg0

显示S无法访问,如下所示

09:58:22.207251 IP 10.200.1.5.9134 > 8.8.8.8.53: 36555+ A? play.googleapis.com. (37)
09:58:22.207270 IP 10.200.1.1 > 10.200.1.5: ICMP host 8.8.8.8 unreachable, length 73

答案1

WireGuard 是第 3 层接口,因此声明via 10.200.1.3没有效果,因为它将用于链路层协议(通常是 ARP)来解析此处不存在的第 2 层地址。

所以

ip route add default via 10.200.1.3 dev wg0 table 200

可以重写为:

ip route add default dev wg0 table 200

这有助于记住,这部分不是选择数据包前往 P1 或 P2 的部分:WireGuard 也有自己的内部路由:密钥路由,这可以通过在每个对等点的配置中正确设置来完成AllowedIPs。有一个重要的限制:与标准路由相反,AllowedIPs不支持任何重叠地址。如果尝试这样做(例如在服务器 S 上AllowedIPs = 0.0.0.0/0为对等点 P2 设置),这将自动删除其他对等点上的冲突地址(例如AllowedIPs = 10.200.1.5从对等点 P1 中删除,因为与0.0.0.0/0其他任何地址重叠)并且连接将受到影响(S 不会将任何东西加密路由到 P1:不再有连接)。

有两种方法可以解决这个问题:

  • 使用两个不同的 WireGuard 接口

    先前的限制是针对每个 WireGuard 接口的。使用第二个接口可以避免此类冲突,但会使路由更加复杂。现在可能需要在路由表 200 和/或主表中添加多个条目:一个用于左侧接口,一个(默认)用于右侧接口。

  • 对冲突的范围进行集合减法

    可能确实有一些工具能够计算集合 0.0.0.0/0 和集合 10.200.1.5 之间的差异,但我不知道。还有一个方便的工具叫做netmask(主页:https://github.com/tlby/netmask) 通过将范围转换为最小的网络掩码集来提供帮助:

    $ netmask 0.0.0.0:9.255.255.255 10.200.1.3 11.0.0.0:255.255.255.255
            0.0.0.0/5
            8.0.0.0/7
         10.200.1.3/32
           11.0.0.0/8
           12.0.0.0/6
           16.0.0.0/4
           32.0.0.0/3
           64.0.0.0/2
          128.0.0.0/1
    

    这些是服务器 S 上应该为 Peer P2 使用的值(以逗号分隔),AllowedIPs因此加密密钥路由将在那里路由除 10.0.0.0/8 之外的任何内容,其中只有 10.200.1.3 将在 P2 端定义,而 P1 端已​​定义的 10.200.1.5 保持不变:不再重叠。P1 发送到 Internet 的数据包现在应该继续发送到 P2 进行进一步路由。

答案2

如果你想

P1 <--> S <--> P2 <--> Internet

其中 S 是“Wireguard 服务器”,P1 和 P2 是 Wireguard 对等体(假设位于 NAT 后面且未配置端口转发),“连接”到 S,P2 充当 P1 的互联网网关,首先需要进行以下基本设置:

P1 Wireguard 配置

[Interface]
PrivateKey = ...
Address = 10.200.1.5/32

[Peer] # S
PublicKey = ...
Endpoint = ...:51820
AllowedIPs = 0.0.0.0/0

S Wireguard 配置

[Interface]
ListenPort = 51820
PrivateKey = ...
Address = 10.200.1.1/32

[Peer] # P1
PublicKey = ...
AllowedIPs = 10.200.1.5

[Peer] # P2
PublicKey = ...
AllowedIPs = 0.0.0.0/0

P2 Wireguard 配置

[Interface]
PrivateKey = ...
Address = 10.200.1.3/32

[Peer] # S
PublicKey = ...
Endpoint = ...:51820
PersistentKeepalive = 25    # allows S to reach P2
AllowedIPs = 10.200.1.0/24

此外,确保在 S 和 P2 上启用了 IP 转发,并且当从 S1 转发的数据包在其面向互联网的网络接口上离开 P2 时,P2 执行必要的 NAT/伪装。

这应该已经奏效了,因为 P1 的互联网流量被转发到 P2。但是,现在 S 的互联网访问通过 P2。这可能是不理想的。例如,您将无法通过互联网通过 SSH 进入 S,因为 S 会尝试通过 P2 进行响应(沿途使用 NAT 的非对称路由)。如果您不希望 S 本身使用 P2 作为网关,您可以像这样在 S 上手动配置基于策略的路由:

具有自定义基于策略的路由的配置

[Interface]
ListenPort = 51820
PrivateKey = ...
Address = 10.200.1.1/32
Table = 123  # <-- AllowedIPs-based routes end up here
PostUp = ip rule add from 10.200.1.0/24 table 123
PreDown = ip rule del from 10.200.1.0/24 table 123

[Peer] # P1
PublicKey = ...
AllowedIPs = 10.200.1.5

[Peer] # P2
PublicKey = ...
AllowedIPs = 0.0.0.0/0

这使得将基于的路由wg-quick添加AllowedIPs到自定义路由表(table 123)并有条件地根据使用源 IP 地址“启用”此路由表ip rule

您可能还想在 S 上添加一些防火墙规则,例如,确保通过 Wireguard 传入的流量不会逃逸到任何地方,而只是转发到同一设备。您可以通过添加

PostUp = iptables -I FORWARD -i %i ! -o %i -j REJECT
PreDown = iptables -D FORWARD -i %i ! -o %i -j REJECT

到 S' 配置。

相关内容