我的私有局域网中运行着一台服务器lanserver
,该服务器使用 Wireguard 连接到公共服务器publicserver
。使用 iptables 规则publicserver
将 TCP 连接lanserver
通过 Wireguard 连接转发到某些端口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
此设置正常工作。传入的 TCP 连接使用 iptables 规则publicserver
转发lanserver
。响应被发回,publicserver
因为 ip 规则31101
匹配它。
有一个例外:当我尝试publicserver
从我的个人计算机pc
(也在我的私有 LAN 内)使用 IPv6 打开到 的 TCP 连接时,它不起作用。问题似乎是和都pc
在lanserver
同一个公共子网中拥有 IPv6 地址。成功publicserver
将连接转发到,但由于 ip 规则,lanserver
响应不会通过 Wireguard 连接路由回 ,而是直接路由到。pc
31100
如何确保通过 Wireguard 接口进入的所有连接的响应lanserver
也通过 Wireguard 接口发送回来,无论它们的源 IP 是否在本地子网中?
我可以从以下几个方向想到解决方案:
- 禁用 上的 IPv6
lanserver
,导致其与 不在同一子网pc
。这不是一个好的解决方案。 - 使用
SNAT
onpublicserver
进行端口转发。这不是一个可接受的解决方案,因为转发端口背后的某些服务需要知道真正的源 IP。 - 在 Wireguard 对等体中明确提及本地 IPv6 子网
AllowedIPs
。这不起作用,因为 IPv6 子网每 24 小时就会发生变化。 - 添加自定义 IP 规则,该规则以某种方式匹配所有传入的连接
wg0
并使用路由表52014
。我不确定如何指定这样的规则。此外,问题是每次重新启动 Wireguard 连接时,路由表的编号都会发生变化。创建此类规则的正确位置可能是脚本PostUp
,但 NetworkManager 似乎不允许指定一个。
答案1
在尝试了不同的选项后,我决定停止使用 NetworkManager,而是直接使用 wg-quick。在 Fedora Server 上,这非常简单,我只需使用 删除 NetworkManager 连接nmcli con del wg0
并使用 启用 wg-quick 服务systemctl enable --now wg-quick@wg0
(从 读取配置/etc/wireguard/wg0.conf
)。切换到 wg-quick 具有以下优势:
- 我可以指定自定义
PostUp
命令来配置更复杂的路由设置 51820
尽管我找不到有关此内容的任何文档,但Wireguard 路由表的数量似乎恒定为。这使得设置自定义 IP 规则变得更加容易。
然后,我使用PostUp
命令wg0.conf
设置了其他 IP 规则,以确保任何 Wireguard 流量也将通过 Wireguard 响应。有两种方法可以实现这一点:
选项 1:源 IP 匹配
ip 规则根据源 IP 地址(自动设置为请求最初进入的 IP 地址)与 Wireguard 包进行匹配:
[Interface]
Address = 10.139.192.4/24
Address = fd52:30a4:f9e7:647a::4/64
PostUp = ip -4 rule add from 10.139.192.4 lookup 51820
PreDown = ip -4 rule del from 10.139.192.4 lookup 51820
PostUp = ip -6 rule add from fd52:30a4:f9e7:647a::4 lookup 51820
PreDown = ip -6 rule del from fd52:30a4:f9e7:647a::4 lookup 51820
选项 2:fwmark
一些 iptables 规则配置用于mark
对通过以下方式进入的包进行设置wg0
:
iptables -t mangle -A INPUT -j CONNMARK -i wg0 --set-mark 1
ip6tables -t mangle -A INPUT -j CONNMARK -i wg0 --set-mark 1
iptables -t mangle -A OUTPUT -j CONNMARK -m connmark --mark 1 --restore-mark
ip6tables -t mangle -A OUTPUT -j CONNMARK -m connmark --mark 1 --restore-mark
然后mark
与 IP 规则匹配:
PostUp = ip -4 rule add fwmark 1 lookup 51820
PreDown = ip -4 rule del fwmark 1 lookup 51820
PostUp = ip -6 rule add fwmark 1 lookup 51820
PreDown = ip -6 rule del fwmark 1 lookup 51820
关于此解决方案的更多详细信息请参见这里。