IPsec 日志可能显示存活应答,而它们前面的应用却卡住了,这两件事可以同时成立。DPD 应答只能确定对端的 IKE 处理在当时作出了回应;它无法说明子 SA 是否承载你真正关心的报文。把故障附近的每条告警都当成原因,正是把选择符问题误诊为协议缺陷的常见方式。有三类观察最容易被混淆,它们回答的是三个不同的问题。在读时间戳之前,先按关联和目的去读。

每种观察能证明什么

表格把每种观察所确立的内容与它仅仅伴随的内容区分开来。

ObservationWhat it establishesWhat it leaves open
DPD replies arriveThe peer's IKE process answeredThe child SA, forwarding path and application reply
TFC padding notificationThe peer will not accept padding for that child SAWhether ordinary ESP protection still works, which it does
Selectors reported as narrowedThe accepted traffic set is a subset of the offerWhether the subset includes the flow the user needs

这三者本身都不是错误。每一种只有在与正在排查的流相邻时才有意义,而无法与具体流对应的行只是背景,不是证据。

存活不等于数据健康

DPD 以 INFORMATIONAL 交换运行,是 IKE 守护进程之间的控制面会话。应答证明对端的 IKE 进程可达且愿意回应,超时则证明并非如此。两种结果都不检验子 SA、选择符、转发路径或应用的应答,因此数据流停住时的健康 DPD 是一幅自洽的图景,而非矛盾。

所以,无论日志顶部的存活行看起来多让人安心,它们都是数据面工单中最没用的部分。

填充通知只是关于填充的声明

TFC 填充是这些日志里被过度解读最多的一行。它说的是该子 SA 不会接受流量机密性填充,这是关于一项可选填充功能的声明,而不是拒绝 ESP 保护。在故障附近看到它通常只是冗长程度的巧合,开关填充对选择符覆盖范围毫无影响。

《IKEv2 规范》既定义了该通知,也定义了选择符协商;实现方给出的告警标签在两种情况下都不能取代协议本身的含义。

收窄更安静,也更可能真正相关

响应方可以只接受所提议选择符的一个子集,而接受的集合可能分散在多个条目里:一条限定端口,另一条覆盖所有端口。只读第一条限定端口的行会低估实际接受的范围;只读那条宽泛的行则会高估。请把打印出的提议与已安装的策略对照,因为提议是双方说过的内容,策略是内核将要匹配的内容。两者不一致时,隧道在、流量不在,这正是经典的间歇性投诉。比较对端时要交换本地与远端的视角,因为每一侧的本地就是对方的远端。

带端口限制的主机专属条目值得读两遍,因为正是它们排除了 ICMP 或第二个端口,同时让发往网关的 ping 继续可用。

为出错的那条流建一条记录

按保护决策处看到的样子记录源、目的、地址族、协议和端口,包括任何有意的转换。这些才是必须与选择符匹配的值,也是工单交到第三个人手里时人们凭记忆重新敲一遍的值。

然后定位子 SA 及其方向计数:swanctl --list-sas 会给出 strongSwan 主机上的关联摘要,ip -s xfrm state 会给出计数。要在一次新的、被允许的请求之后读取,而不是在系统闲置时读。出方向没有增长,指向选择或本地路径;有出无对应的入,则指向对端、它的转发或它的应答。

一次完整的应用层交互优先于任何一个计数,所以测试应当在应用处结束,而不是在隧道指示灯处结束。

之后再选择修正

只有那条记录存在,才有可选的修正:接受的选择符、路由、过滤、对端实现,或你刚刚证明的边界。重置对端会一次改变多个状态,往往在没说明哪一处出错的情况下恢复了流量,于是故障复发。也不要把内核状态转储放进工单,它们可能含密钥,而简短的摘要对需要帮忙的人已经够用。

当记录与你的第一个假设矛盾时,相信记录,重写假设;这个习惯比这里讨论的任何一行日志都更有价值。

相关文章