DPD 应答只能证明 IKE 对端还活着,不能证明你的数据在流通
存活应答、填充通知和收窄的选择符描述的是三件不同的事。在把停顿归咎于其中之一之前,请分别解读。
IPsec 日志可能显示存活应答,而它们前面的应用却卡住了,这两件事可以同时成立。DPD 应答只能确定对端的 IKE 处理在当时作出了回应;它无法说明子 SA 是否承载你真正关心的报文。把故障附近的每条告警都当成原因,正是把选择符问题误诊为协议缺陷的常见方式。有三类观察最容易被混淆,它们回答的是三个不同的问题。在读时间戳之前,先按关联和目的去读。
每种观察能证明什么
表格把每种观察所确立的内容与它仅仅伴随的内容区分开来。
| Observation | What it establishes | What it leaves open |
|---|---|---|
| DPD replies arrive | The peer's IKE process answered | The child SA, forwarding path and application reply |
| TFC padding notification | The peer will not accept padding for that child SA | Whether ordinary ESP protection still works, which it does |
| Selectors reported as narrowed | The accepted traffic set is a subset of the offer | Whether 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 会给出计数。要在一次新的、被允许的请求之后读取,而不是在系统闲置时读。出方向没有增长,指向选择或本地路径;有出无对应的入,则指向对端、它的转发或它的应答。
一次完整的应用层交互优先于任何一个计数,所以测试应当在应用处结束,而不是在隧道指示灯处结束。
之后再选择修正
只有那条记录存在,才有可选的修正:接受的选择符、路由、过滤、对端实现,或你刚刚证明的边界。重置对端会一次改变多个状态,往往在没说明哪一处出错的情况下恢复了流量,于是故障复发。也不要把内核状态转储放进工单,它们可能含密钥,而简短的摘要对需要帮忙的人已经够用。
当记录与你的第一个假设矛盾时,相信记录,重写假设;这个习惯比这里讨论的任何一行日志都更有价值。