流量从一个站点出去后再也没回来,两端网关都报告协商已完成,唯一的线索是一堆没有回应的出站数据包。在 Linux 端点上,常见原因不是加密强度、MTU 或路由表,而是策略条目的粒度以及把每条策略与安全关联绑定起来的那个编号。下面的流程先读这两个数据库,再动别的。

先拆解症状,再动手修改

协商已完成却单向不通,问题被压缩到数据路径。要么出站策略匹配而回应被丢弃,要么回应根本没到,因为对端没有可用的发送路径。从应用看两者一模一样,xfrm 数据库能把它们分开。

不要从 MTU 入手。错误的 MTU 造成卡顿和分片症状,而不是出站计数持续上涨的干净方向割裂。

读策略数据库与状态数据库

Linux 上由策略条目决定加密,所以 让数据包进入隧道的是匹配的策略,而不是路由。运行 ip xfrm policy 查看每条条目的选择器、方向、优先级和模板,运行 ip xfrm state 查看已建立的安全关联及其 reqid。策略与安全关联由这个 reqid 连接。

三个方向都要看。出站与入站覆盖进出本机主机的流量;当主机为他人转发时,forward 方向才重要。某个方向条目缺失或不匹配,就足以解释单向结果,而不涉及任何加密故障。

经典不对称:一个 reqid 对多个子网

常见故障来自对端把所有协商子网的策略都装在同一个 reqid 下,racoon 的 generate_policy require 就会这样。流量于是从最后建立的那条安全关联出去,而对端仍按子网各建一条。回应到达的那条安全关联,其 reqid 并不指向应当接受它的策略,内核在解密后将其丢弃。

修法是配置变更,而不是防火墙规则:generate_policy unique; 让每条策略拥有自己的 reqid,对端按策略建立的安全关联就有了匹配的伙伴。改完重新协商,并在宣布成功之前数清预期子网对应的不同 reqid。

如果两个子网仍共用一个 reqid,而对端期待两个,就找到了不对称。记录这份映射,因为它正是下一次变更修好了还是保留了问题的证据。

选择器来自协商,而不是你的配置

受保护的网段是两端谈定的结果,而不是某一方要求的。客户端用一对主机去对端的大范围提议,只会拿到网关收窄后的版本,客户端无法把它放宽。要读已安装的选择器,而不是本地文件里的那份。

当目标相反,要把某个目的地留在隧道之外时,加一条优先级数字更小的旁路策略,让它压过自动安装的条目。没有模板的策略允许明文,这使它成为变更记录里的显式例外,而不是排查步骤。

按这个顺序验证,并知道如何回退

两个方向逐个子网列出策略,主机转发时还要包括 forward 方向。数清不同的 reqid,并确认期待的一侧每条策略一个。把已安装的选择器与协商结果对比。密钥更新后重新读取每条安全关联的计数,因为刚查过的那条可能已经消失。最后再查路由,因为缺少到远端子网的路由会产生相似的单向症状,而策略计数却是干净的。

改动对端之前,先保存两条 xfrm 命令的当前输出。如果新设置没有恢复回程方向,恢复这份输出比凭记忆重建隧道回退更快,也让前后对比保持诚实。

相关文章