我有一个在我的私有 LAN 中运行的服务器,它使用 Wireguardlanserver
连接到公共服务器。使用 iptables规则通过 Wireguard 连接将 TCP 连接转发到某些端口。publicserver
publicserver
lanserver
DNAT
在 上lanserver
,Wireguard 设置为 NetworkManager 连接。它通过 Wireguard 使用AllowedIPs = 0.0.0.0/0, ::/0
. 这会导致设置以下 ip 规则lanserver
:
[root@lanserver ~]# ip rule show
0: from all lookup local
31100: from all lookup main suppress_prefixlength 0
31101: not from all fwmark 0xcb2e lookup 52014
32766: from all lookup main
32767: from all lookup default
[root@lanserver ~]# ip route show table 52014
default dev wg0 proto static scope link metric 50
此设置工作正常。使用 iptables 规则将传入的 TCP 连接publicserver
转发到。由于 ip 规则与之匹配,因此lanserver
将响应发回。publicserver
31101
有一个例外:当我尝试publicserver
从我的个人计算机打开 TCP 连接以使用 IPv6 时pc
,它也位于我的私有 LAN 中,它不起作用。问题似乎是两者在同一个公共子网pc
中lanserver
都有一个 IPv6 地址。publicserver
成功转发连接lanserver
,但响应不是通过 Wireguard 连接路由回,而是直接pc
由于 ip rule 31100
。
如何确保通过 Wireguard 接口进入的连接的所有响应lanserver
也通过 Wireguard 接口发回,无论它们的源 IP 是否在本地子网中?
我可以从以下几个方向思考解决方案:
- 在 上禁用 IPv6
lanserver
,导致它与 不在同一子网中pc
。不是一个很好的解决方案。 - 用于端口转发
SNAT
。publicserver
不是一个可接受的解决方案,因为转发端口后面的一些服务需要知道真正的源 IP。 AllowedIPs
在 Wireguard 对等体中明确提及本地 IPv6 子网。这不起作用,因为 IPv6 子网每 24 小时更改一次。- 添加一个自定义 IP 规则,该规则以某种方式匹配所有传入的连接
wg0
并为它们使用路由表52014
。我不确定如何准确指定这样的规则。此外,问题在于每次重新启动 Wireguard 连接时,路由表的数量都会发生变化。创建此类规则的正确位置可能是PostUp
脚本,但 NetworkManager 似乎不允许指定一个。
在尝试了不同的选项后,我决定停止使用 NetworkManager,而是直接使用 wg-quick。在 Fedora 服务器上,这非常简单,我只需要使用删除 NetworkManager 连接
nmcli con del wg0
并启用 wg-quick 服务systemctl enable --now wg-quick@wg0
(它从 读取配置/etc/wireguard/wg0.conf
)。切换到 wg-quick 有以下优点:PostUp
命令来配置更复杂的路由设置51820
,即使我找不到任何关于此的文档。这使得设置自定义 ip 规则变得更加容易。然后我使用
PostUp
命令wg0.conf
设置额外的 ip 规则,以确保任何 Wireguard 流量也将通过 Wireguard 响应。有两种选择可以实现这一点:选项 1:源 IP 匹配
ip 规则根据 Wireguard 包的源 IP 地址(自动设置为请求最初传入的 IP 地址)匹配 Wireguard 包:
选项 2:fwmark
一些 iptables 规则配置为
mark
在通过以下方式传入的包上设置wg0
:然后
mark
通过 IP 规则匹配:可以在此处找到有关此解决方案的更多详细信息。