我有一个运行 Arch Linux 的 SBC,将其用作 VPN 服务器(因为它是唯一具有不受 ISP NAT 处理的全局访问 IP 地址的设备)来连接三个不同的网络。它们是 192.168.0.0/24、192.168.2.0/24 和 192.168.10.0/24,连接到 Wireguard VPN 10.11.12.0/24。每个 192.168.. 网络都通过单个 VPN“网关”(实际上是 IP 转发设置为“打开”的对等点,其中一个运行 Windows 10 Home,另外两个运行 Linux)使用 192.168..10 LAN 地址连接到 VPN和 10.11.12.2-4 VPN 地址,并且每个相应的 WAN/LAN 路由器 (192.168..1) 设置为将 10.11.12.0/24 地址作为静态路由路由到本地 VPN“网关”对等点 (192.168..10)路线。服务器的 VPN 地址为 10.11.12.1。我可以使用本地 IP 无缝连接到所有网络中的每个设备,但大多数时候,来自外部网络的数据包会被除具有公共 Web 接口(打印机、本地 Web 服务器等)之外的所有设备丢弃。
我可以理解我需要在每个 VPN 网关设备上设置 NAT,以便来自“兄弟”网络的数据包不会作为外部数据包被丢弃。我该如何以正确的方式做到这一点?
更新:添加图像是为了澄清。橙色对象可视化 VPN 通信,蓝色对象 - LAN 或 WAN 通信。
假设我在 192.168.0.20 机器上,我想访问 192.168.10.20 设备(通过 VPN 的“兄弟”网络单元)。流量如下: 192.168.0.20 -> 192.168.0.10/10.11.12.2(LAN VPN 网关) -> 10.11.12.1(VPN 服务器) -> 192.168.10.10/10.11.12.4(同级 LAN VPN 网关) -> 192.168 .10.20(目的地)。问题是数据包的源 IP 对于目标网络来说仍然是外部的,因此同级网络上的许多服务(远程访问受限的路由器 WebUI、机器上的 ssh 等)都会丢弃此类数据包。
答案1
方法:按照数据包
我将通过跟踪数据包的行程并添加该数据包继续到达其正确目的地所需的配置更改,解释必须使用 OP 给出的连接示例执行哪些操作。对路由和 WireGuard 配置的这些更改应同样复制多次(总共 2 个远程 LAN x 3 个 LAN = 6),以考虑到从三个 LAN 中的每一个到达另外两个 LAN,并且还在中央 VPN 服务器上进行了 3 次它连接的 3 个 LAN(可以存在一些简化,如尾注中所述)。
除非另有说明,否则不必在完全由 OP 控制的 (VPN) 网络上使用 NAT。这会阻碍连通性。
确保数据包在每一步都到达下一跳
起源局域网
地址为 192.168.0.20 的系统尝试通过 VPN 访问 192.168.10.20:
- 要么有通过 192.168.0.10 到达它的路由,并通过此网关发送数据包
- 或者没有路由并将其发送到 192.168.0.1,
- 要么有通过 192.168.0.10 到 192.168.10.20 的路由,并向 192.168.0.20 发送 ICMP 重定向,告诉它使用该目的地的正确网关(并缓存它),同时继续接收到的第一个数据包并继续转发它们
- 或不:数据包被路由到 ISP,并迟早会在互联网上的某个地方被丢弃或丢失:这就是如果不改变就会发生的情况。
正如OP所写,路由器上已经为 10.11.12.0/24 定义了一条添加的静态路由,可以这样做。 OP 可以而且必须在路由器上再次添加静态路由:
在路由器上添加到 192.168.10.0/24 的路由,以 192.168.0.10 作为网关。
Linux 的命令是:
ip route add 192.168.10.0/24 via 192.168.0.10 dev eth0
可选,但建议如果可能,在 LAN 中的所有系统上添加相同的路由(以避免次优 ICMP 重定向):
- 在每个系统上手动
- 或者通过配置路由器的 DHCPDHCP 选项 121+(非标准,但它是微软......)DHCP 选项 249。这需要比一般的现成家用路由器更好的功能来提供此功能。
现在可以通过在 192.168.0.10 上添加路由来将数据包路由到中央 VPN 服务器:
ip route add 192.168.10.0/24 dev wg
via 10.11.12.1
在第 3 层设备上没有用处。但不管怎么说WireGuard 还有自己的强制选择对等点的方式):要成功,AllowedIPs
相关(和单个)对等点的参数通常应更改为:
AllowedIPs = 10.11.12.0/24
到:
AllowedIPs = 10.11.12.0/24, 192.168.10.0/24
或者因为只有一个单身的WireGuard 对等点在其wg
接口上,这意味着流量应始终涉及该对等点,无论目的地(发送到对等点)或来源(从对等点接收),简单地说:
AllowedIPs = 0.0.0.0/0
这对于第三个不涉及的 LAN (192.168.2.0/24) 也有效,以后无需进行额外更改。
中央 VPN 服务器 (SBC Arch Linux)
数据包到达中央 VPN 服务器的wg
接口(更准确地说,首先作为 UDP 端口上的 UDP 数据包,WireGuard 侦听其隧道协议,然后才有机会出现在 上wg
)。
中央 VPN 服务器必须更改其 WireGuard 配置,特别是其AllowedIPs
参数,以便相关对等方与通过其到达的源 IP 地址关联。
替换该对等点的条目,通常具有:
AllowedIPs = 10.11.12.2
和:
AllowedIPs = 10.11.12.2, 192.168.0.0/24
在不更改路由的情况下,数据包将使用默认路由进一步路由到互联网(并且如果发生以下情况,数据包将立即被丢弃)rp_filter=1
出于类似原因而设置)。仍然在中央 VPN 服务器上,通过接口添加到 192.168.10.0/24 的路由wg
:
ip route add 192.168.10.0/24 dev wg
如前所述,AllowedIPs
也用于确定正确的 WireGuard 目标对等点。还要替换相关出口对等体中的条目:
AllowedIPs = 10.11.12.4
到:
AllowedIPs = 10.11.12.4, 192.168.10.0/24
数据包现在将被路由到目标 LAN
目的地局域网
目标 LAN 中的 VPN 网关 10.11.12.4 将收到 上的数据包wg
,但如果不更改 WireGuard 配置,该数据包将被丢弃。由于该节点是一个具有单个对等节点的 WireGuard 节点,与之前一样,因此可以安全地简单地说:
AllowedIPs = 0.0.0.0/0
该数据包现在被路由到最终节点 192.168.10.20,该节点在 eth0 上接收该数据包。例如,如果它是 ICMP 回显请求,则该节点现在会使用 ICMP 回显回复进行回复...并且使用反转值重复完全相同的解释:
当地址为 192.168.10.20 的系统尝试通过 VPN 访问 192.168.0.20 时:
- 要么有通过 192.168.10.10 的路由并通过此网关发送数据包
- 或者没有路由并将其发送到 192.168.10.1,
- 要么有通过 192.168.10.10 到达 192.168.0.20 的路由,并向 192.168.10.20 发送 ICMP 重定向,告诉它使用该目的地的正确网关(并缓存它),同时继续接收到的第一个数据包并继续转发它们
- 或不:数据包被路由到 ISP,并迟早会在互联网上的某个地方被丢弃或丢失:这就是如果不改变就会发生的情况。
[...]
通过像前两部分中那样在需要的地方有条不紊地更改设置,现在 192.168.0.0/24 和 192.168.10.0/24 之间存在连接。无需 NAT。
最后一个局域网
如果 LAN 被称为 LAN0、LAN2 和 LAN10,则重复从 LAN0 到 LAN2 以及从 LAN10 到 LAN2 来回跟踪数据包的过程,并且所有涉及的系统上的所有配置都将完成(至少 4 台 VPN 服务器和 3 台路由器)。
笔记
所有 3 个 LAN VPN WireGuard 服务器都需要足够的
PersistentKeepalive
选项由于 (ISP) NAT。这样他们就可以随时收到交通。如果没有它,只有在以下情况下才真正建立到中央 VPN 服务器的隧道:发送一旦没有流量并且路由器或 ISP 的路由器忘记了 UDP 流,数据包就会消失。这些数据包可能无法到达目标 LAN,因为目标 LAN 本身并未建立自己的隧道。通常为 25,如 中建议的
man wg
,或经过一些验证测试后更高:PersistentKeepalive = 25
中央 VPN 服务器不需要它。
简化
在每个站点上使用单个附加路由 192.168.0.0/16 而不是两个 192.168.x.0/24 路由效果很好:LAN 的 /24 仍优先于更通用的 /16 路由。
对于中央 VPN 服务器来说也是如此:单个 192.168.0.0/16 路由可以替代三个 /24 路由以通过接口路由该路由
wg
。当然它自己AllowedIPs
不能被简化,必须保留每个同行的准确信息。ICMP 不得被任何节点的本地防火墙丢弃:
在这种情况下,如果终端节点未在其配置中或通过 DHCP 接收其他路由,则需要 ICMP 重定向才能正确路由。
需要 ICMP 时间超出路径 MTU 发现,因为 VPN 将 MTU 减少到 1420,从而将 TCP MSS 减少。否则 TCP 连接可能会挂起。
通过在适当的位置指定 MTU 为 1420 的路由(终端节点和路由器,WireGuard 服务器不需要,但也可以在那里设置),可以不需要 PMTUD 和关联的 ICMP,就像添加到
mtu 1420
之前显示的各种路由一样,但它不值得考虑,并且不能涵盖所有情况(如果 ISP 有自己的 VPN 进一步限制 WG 的 1420 MTU 怎么办?),而且 DHCP 的无类别路由选项 121 似乎也没有提供此类 MTU 信息。
路由器自带的防火墙(如果有的话)一定不能太热心
一些数据包在 ICMP 重定向启动之前以及随后关联的缓存过期时遵循非对称路由,导致路由器只能看到单个方向的部分流量,这可能会被状态防火墙丢弃(例如:Linux 路由器/防火墙可能会这样做TCP 取决于防火墙规则和设置
net.netfilter.nf_conntrack_tcp_be_liberal
或者net.netfilter.nf_conntrack_tcp_loose
)。该方案假设未来添加的IP网络不会与现有网络发生冲突
如果将来发生此类冲突,NAT 将不可避免。使用 1:1 NAT(例如:Linuxiptables'
NETMAP
)总的来说,冲突的 LAN 仍然允许单独访问每个远程 LAN 的节点。这需要它自己的问答来了解详细信息。