重复的 IKE 数据包:找到缺失的那次转换
重复出现的 IKE 请求是定时器事件,不是结论。请沿发起方到应答建立一条完整的证据链,并使用正确的版本标识。
日志里同一个 IKE 请求出现了两次,有人把矛头指向移动链路,工单就以一个猜测收尾。这个猜测正是误解所在:重复的数据包只是对一次交互的观察,并不是对链路的诊断。重传是带有自身规则的正常行为,只要应答变慢,健康的路径上也会出现它。先把应答追清楚,再去指责某个接口。
误解:请求重复就证明某条链路丢包
有两种完全不同的原因会造成重复,而它们都没有指向真正的责任方。请求方可能因为没收到应答而重复发送;抓包点也可能因为自己在协议栈上的挂接位置,把同一个数据包记成两个。一个能同时看到同一台主机收发的采集点,会毫不犹豫地把一个包记成两个,而读日志的人在没有交互标识的情况下根本分不清这两种情况。在你能够说清手里握的是哪一种之前,请把重复当成定时器事件。
两条上行链路只会让混乱更糟,而不是更好。一行日志只写出一个接口,而应答可能从另一个接口出去,所以日志里的接口说明的是数据包在哪里被看到,而不是这段会话的形状。这也是为什么第一个问题应该是你在看哪一次交互,而不是哪条链路有故障。
重传究竟告诉了你什么
在 IKEv2 中,重传 的机制是这样的:请求方在没有收到应答时会重复请求,应答方则可以重发已缓存的应答,而不必重新计算一份。报文标识属于那一次交互,正因为如此,带着同一标识的重复请求才能被认作协议在正常工作,而不是一次新的尝试。首次尝试往往需要不止源地址或发起方 SPI 才能对上号,所以平台自己的交互记录比一份数据包清单更有用。IKEv1 遵循不同的规则,标识也不同;厂商关于首个数据包重复的告警,在各版本之间的含义并不一致。
所以,一个重传时间戳只说明某个定时器到期了。它不说明哪一跳慢,更不说明运营商有责任。这是两个独立的判断,只有后一个在工单里有用。
实际做法是:在下结论之前先把这次交互记录下来。把本地接收地址、策略选定的应答路径、对端四元组以及交互标识写在同一处,因为日后回看记录时,它们各自回答的是不同的问题。
四个观测点连成一条链
把这次交互想成一条链上的四个环节,而不是四个彼此独立的观察位置。一个环节要么留下证据,要么保持未知;整条链的可信程度,只取决于记录得最弱的那一环。下表就是清单:每个位置能确认什么,又留下了什么没有触及。
| 位置 | 它能提供的证据 | 它没有回答的问题 |
|---|---|---|
| 发起方发送 | 有请求离开了这台主机 | 它是否到达了对端 |
| 应答方接收 | 请求已经到达 | 是否产生了应答 |
| 应答方发送 | 有应答离开了网关 | 它是否走了预期路径 |
| 发起方接收 | 这次交互已经完成 | 策略是否接受了结果 |
只在你确有权限的位置填写,其余一律标记为未知,而不是靠推断补齐。只在一台机器上记录数据包的钩子,说明不了远端机器收到了什么;一行写着“看到过请求”的日志,也不是应答曾经发出过的证据。诚实的空白比一份靠猜测拼出的完整记录更有价值。
找到第一处缺失的转换
从发起方往外走,在第一个没有证据的环节停下。如果网关从未记录这条请求,故障就在它之前的那段路径上。当网关反复记录同一条请求,而客户端从未记录到应答时,嫌疑就在返回方向:源地址、地址转换,以及你所控制的每一处边界上的过滤。如果应答到了而客户端仍然不往前走,问题就已经离开传输层,变成策略或状态问题。
比较时保持对端和协议不变,并记住时延、丢包、策略与状态各自给出不同的时间线。移动网络并不自动就是原因,固定线路也并不自动满足每项要求的可靠性。在这次交互还活着的时候,同时抓取两个方向:
tcpdump -ni any -vv 'udp port 500 or udp port 4500'
当访问在远端之前就中断时,只要记录说清断在哪里,它依然有用。只在发起方抓包,能显示请求发出而应答未到,从而把故障收窄到那个钩子之后的所有环节,同时不必假装知道是哪一跳把它丢了。把远端环节标记为未知,留给下一位有权限的人去补。这样写法既保持诚实,也依然简短。
改动之前先做比较。用同一协议、对同一对端重复同一条请求,变量才是可数的;而在两次抓包之间做一次重置、一次密钥更新或一次策略修改,比较就被毁掉了。如果改动无法避免,就在改动之后立刻重新抓取,让改动前后的记录仍然描述同一次交互。
一份有用的报告该说什么
值得据以行动的报告,会把一条请求和它的应答配对,并指出第一个背后没有证据的环节。这样一句话,一周之后由不在现场的人来读也依然站得住,而且它给下一个人留下的是起点,不是一个嫌疑人。
永远不要为了验证一个重传猜测而削弱身份校验,也不要为此放宽允许的协议集合。在任何重置之前,先把原始数据包和事件记录保存下来,因为重置恰好会毁掉你正要收集的材料,并抹掉那些显示交互卡在哪里的时间信息。
误解在于,一次重复就证明运营商有问题。事实是,一次重复只证明某个定时器到期了,而答案就在应答路径上。