你添加了一个 VPN 地址,本以为请求会使用它,但服务器记录的仍是旧前缀。隧道本身没有出问题;主机在你盯着看的那条路由被查询之前,就已经做出了源地址选择。IPv6 源地址选择是主机候选地址之间一场独立且有序的竞争,最长前缀匹配只是接近其末尾的一条规则。想要得到期望的结果,就得知道哪条规则已经胜出。规则本身枯燥而精确,这正是要按顺序阅读它们的原因。

两次查询,而非一次

目的地址选择决定下一跳和出接口。随后源地址选择决定主机的哪个地址会出现在报头中,而这两个问题由不同的机制回答,尽管两者都用到了前缀。一台同时拥有物理地址、临时地址和 VPN 地址的主机,对任意目的地都有三个候选,而通往 VPN 的路由并不会自动提名第三个。

这就是正确的路由与错误的源地址能如此轻易共存的原因,也是同一个请求从浏览器和从强制绑定出发可能表现不同的原因。在找到能把两者联系起来的证据之前,请把两次查询分开看待。

把规则当作一场有序竞争来读

RFC 6724 按顺序列出这些规则,每一条只解决前面规则留下的平局。出接口偏好与标签匹配出现在前缀比较之前很久,因此位于路由所用接口上的地址,早已获得一项更优前缀匹配也无法抹去的优势。弃用与作用域也参与其中,所以有时无人改动策略,陈旧地址就不再被选中。

实践中的读法是:不能只凭目的地推断胜出者。列出候选,按顺序走一遍规则,看看决定究竟在哪一步做出。

还要注意,这只是问题中源地址的一半。把两次前缀比较混为一谈,会得出听起来严谨、却预测错误地址的解释。每当在工单里用到“前缀”一词,请说明你指的是哪一次比较。

应用绑定会改变问题

应用程序可以请求特定的源地址,而有效的显式选择把问题从“主机会偏好哪个地址”变成“该地址能否到达目的地并返回”。绑定到源地址的工具,或请求所选地址附加数据的工具,会直接揭示这一点,它们是证明一条连接真正使用了哪个地址的最快方式。这个实验胜过第三次阅读路由表,因为它报告的是内核的决定,而不是你的配置。改动后重复一次,并比较两个答案。

这让源地址绑定既是诊断工具,也是临时变通办法:绑定 VPN 地址,观察请求是否成功。若成功,路径没有问题,问题出在选择上。若失败,问题从一开始就在返回路径或对端策略上。

确认对端接受这个源地址

无论主机选了什么,都必须符合 VPN 的保护范围,以及对端的返回路由和访问规则。选择器之外的源地址可以进入隧道,却在远端被丢弃,看起来像单向故障,并被归咎于路由。在改动加密设置之前,先把选中的内部源地址与保护范围作比较,因为切换模式并不会在候选地址之间做选择。

也要把外层端点地址单独放在推理之外。它标识的是 VPN 参与者之间的传输,并不是内部应用报文的源地址。

用四项观察来定夺

记录所使用的目的地、合格的本地源地址、实际选中的源地址以及有效的出路径。四行足以解释几乎每一种情况,而且可以在正常与故障主机之间对比,无需重新争论理论。选择这一步请使用操作系统自身支持的回显,而不是标准里的名称,因为各实现都会附加自己的本地偏好。

当答案仍然出乎意料时,说明排序在做你的心智模型没有做的事,解决办法是改变输入,而不是与算法争辩。把四项观察写进工单,下一位读者就能复现你的结论。

相关文章