WireGuard 源 IP 地址"漂移"问题的前因后果
在现代网络架构中,VPN(虚拟专用网络)技术的应用越来越广泛。本文将探讨在我司 IDC 中,使用 WireGuard 实现的 VPN 连接中遇到的一个有趣现象。
场景描述
我司在 IDC 中有一台运行 Debian 的服务器 L1,有两个上联口:E-a 和 E-b,分别连接到运营商 I-a 和 I-b。IP 地址为 ip-a 和 ip-b。L1 上的策略路由很简单:
- 源地址为 ip-a 的数据包通过 E-a 口走 I-a
- 其他数据包则通过默认出口 E-b 走 I-b(源地址自然是 ip-b)
此外,L1 还通过网口 E-c 连接内网,IP 地址为 ip-c。L1 上运行 WirGuard,绑定 0.0.0.0 的 udp 端口 12345。
在办公室,我司还有一台运行 Debian 的机器 L2。由于 L2 位于内网中,没有公网 IP。L2 上也运行着 WireGuard,绑定在 0.0.0.0 的(udp)端口 12345。同时,我在办公室的路由器上做了端口映射,将 udp 12345 端口映射到 L2(虽然这完全没什么用)。
L2 的 WireGuard 配置中,peer 的 endpoint 指定为 L1 的 IP 地址 ip-a。由于 L2 没有公网地址且出口地址不固定,因此在 L1 的 WireGuard 配置中并没有指定 L2 的 IP 地址。就这样,L1 和 L2 上的 WireGuard 的连接顺利建立,一切都如预期般正常运行。
异常现象
其实,L2 上还运行着一个 SmokePing,监测着 ip-a、ip-b 和 ip-c,当然也还有其他,不过那些跟这里没啥关系,也就不提了。
某天我在 Smokeping 监控中发现,ping ip-c 的(时间)值明显高于 ping ip-a 的值,且与 ping ip-b 的相近。这一现象让我感到困惑,因为到 ip-c 的数据包走的逻辑链路(通过 WireGuard 隧道)实际上应该与到 ip-a 的物理链路完全相同,所以 ping ip-c 的数据应该跟 ping ip-a 的几乎一样才对。
我的第一反应是,可能是办公室的网络接入商或 I-a 对 UDP 包进行了 QoS 限速,因为 WireGuard 使用的是 UDP 协议。经过与客服的沟通,确认并没有针对 UDP 包的限速策略。
接着,我使用 iperf3
在 L1 和 L2 之间进行了测速,发现走 UDP 和走 TCP 的测试结果数据引并没有显著差别,这表明问题并不在于 UDP 包有被干扰。随后,我在 L2 上使用 tcpdump
监听 WireGuard 的数据包,结果让我大吃一惊:所有的数据包都是与 ip-b 的端口 12345 进行交互,而不是预期中的 ip-a!这也解释了为什么 ping ip-c 的延迟与 ping ip-b 的延迟相近,因为数据实际上是通过到 ip-b 的物理链路进行的。
深入分析
面对这一现象,我感到百思不得其解。于是,我记录下当前的状况,并重启了 L2 上的 WireGuard,结果一切又都恢复正常:WireGuard 的数据交互对端 IP 变回了 ip-a,ping ip-c 的延迟也降到了与 ping ip-a 相同的水平。
进一步查阅资料后,我发现 WireGuard 具有 endpoint 自动更新的机制。虽然 L1 上没有 L2 端的 endpoint 数据,但 L2 上有 L1 的数据。当 L2 第一次连接 L1 时,L1 会记录下 L2 的 endpoint 数据。如果 L2 使用了不同的 IP 地址连接 L1,L1 会更新 L2 的 endpoint IP 地址。反之亦然。这意味着,当 L1 从 E-b 口以 ip-b 作为源地址连接 L2 时,L2 也会更新 L1 的 endpoint IP 地址。
最终,我意识到问题的根源在于 L1 突然使用源 IP 为 ip-b 从 E-b 口发送 WireGuard 数据包给 L2。期间,我发现办公网的网络曾经闪断过几分钟。真相逐渐浮出水面:当 L2 的上联公网链路断开时,L1 由于长时间未收到来自 L2 的 WireGuard 数据包,可能出于某种原因主动向 L2 发送 WireGuard 包,查找 L2 的 endpoint IP 和端口数据。此时,由于源地址未定,数据包直接通过 E-b 口发送,源地址被设为 ip-b。这些数据包持续发送到 L2,直到 L2 的上联网络恢复。L2 收到来自 ip-b 的 L1 的 WireGuard 数据包后,触发了更新 L1 的 endpoint 数据,从而开始与 L1 的 ip-b 进行 WireGuard 数据交互。
结论
通过这一系列的分析,整个逻辑变得自洽了。这一现象不仅揭示了 WireGuard 的灵活性和自动化特性,也提醒我们在设计网络架构时,需考虑到各种可能的网络状态变化。希望这篇文章能为您在使用 WireGuard 或其他 VPN 技术时提供一些启示。