两条上行链路、一台网关,以及一个流量总是出现在备用线路上的 WireGuard 对端。握手全程保持健康。正因如此,人们很容易把这一现象误读成 WireGuard 故障,而不是路由故障。

按顺序完成下面的检查。每一项都有停止条件,跳过顺序通常会得出一个自信的错误结论。

把握手与转发流量分开

加密的对端交换有一个通往服务器公网地址的端点路由。被转发的客户端流量目的地不同,可能由标记或策略规则来选择。这是共用同一接口的两个路由决策。把其中一个当作另一个的证据,是第一个错误。

一旦发现自己从握手开始推理,就立即停下。它只能证明端点路径。

读策略规则,而不是默认路由表

默认路由表只说明没有策略规则命中时会发生什么。在按源地址、标记或目的地址路由的网关上,真正起决定作用的规则在别处。普通路由表可能看起来完全合理,而真正的选择发生在它之上。

ip rule show
ip route show table main
ip -4 route get 203.0.113.9 from 10.30.8.2

读取策略规则以及它们指向的路由表,然后确认哪条规则匹配你的测试流量。一条引用已不再承载目标上行链路的接口的规则,是一个发现,而不是细节。最后那条路由查询,比读表再猜测要快得多。

把标记和转换放在一起检查

策略路由依赖链路中较早设置的报文标记。如果打标规则漏掉了你的流量,流量就会落到主路由表,并从那里的默认路由出去。被转发的报文常常跳过为本地生成的流量编写的规则链。

nft list chain inet filter prerouting
conntrack -L -s 10.30.8.2 2>/dev/null | head
ip -s link show dev eth1

转换必须与承载该流量的上行链路一致。如果规则转换到主地址,而报文却从备用线路出去,就会产生发往该流量从未使用过的接口的应答。请检查转换规则自身的接口条件。无条件规则在第二条上行链路启用前一直有效,之后便以一种看似间歇的方式失败。

观察是哪块接口承载应答

在一个请求运行时,同时在两条上行链路上抓包。记下哪块接口承载请求、哪块承载应答。非对称路径比预测容易看得多。

如果应答从错误的上行链路回来,问题就已经从 WireGuard 转移到连接跟踪或转换。任何对端配置的改动都修不好它。

只改一处,并留好回退的路

在网关上编辑策略规则之前,先保留控制台或带外访问。只做一处改动,测试同一个已授权的目标,然后重新连接,确认握手仍在走预期的端点路径。再补一个针对第二套地址族的数字测试,因为只覆盖 v4 的策略会让同样的错误继续存在。

记录每条流量用了哪条上行链路。这份记录能让下一次报告变成两分钟的检查,而不是耗掉整个下午。WireGuard 的关于命名空间与路由的说明介绍了如何有意识地把端点路径与隧道流量分开,这通常比照搬默认路由的变通做法更干净。

相关文章