当防火墙的加密计数器不断上升,而隧道什么也没送达时,人的第一反应往往是放宽访问规则。这个反应跳过了接收端自身的检查顺序。入站 ESP 数据包要经过若干阶段,每个阶段都可能以不同原因终结这个包:没有匹配的安全联盟、重放或完整性校验失败,或者内层数据包本身没问题却不被允许继续转发。说出失败的阶段,就能把含混的 IPsec 坏了变成具体的计数器和具体的修法,而不是靠猜测去改配置。

到达只是一个观测,不是三个

一份显示 ESP 抵达网关的外部抓包,只能证明外层数据包到了。接受意味着接收端找到了安全联盟并校验了数据包。交付意味着还原出的内层数据包被路由到目的地并得到回应。这是三个彼此独立的结果,把它们合并展示的仪表盘恰好藏起了你需要的信息。

同样的区分能解释一种常见报告:一端加密计数器在涨,另一端却报告没有可用的解密流量。两句话可以同时为真,因为它们描述的是同一次尝试的不同阶段。

安全联盟的查找发生在解密之前

接收端在需要时重组分片,然后为该数据包查找安全联盟。普通单播由 SPI 和目的地址来选定。没有有效联盟就没有后续处理,这正是过期或不匹配的 SPI 只带来沉默、而不给应用报错的原因。

安全联盟是有方向的,并可能在密钥更新期间变化,所以请把接收方、SPI 和时间戳记在你认为当前的那条入站联盟旁边。界面上显示的一条出站联盟,或一段健康的 IKE 关系,都不能代替本该接收这个包的那条联盟。

重放与完整性校验在有载荷之前就拒绝

找到联盟后,接收端套用该联盟规定的算法。如果启用了防重放,窗口之外的序列号会被拒绝。完整性校验失败同样会终止处理,因为 ICV 与收到的数据包对不上。这两种情况都不会产出已解密的内层包,因此路由、策略和应用什么都收不到。

遇到这些状况,请使用实现文档中列出的错误和计数器,而不是把每次接收失败都当成访问列表拒绝。为了让流量出现而关掉完整性或防重放,并不能证明进来的包是合法的;它只是撤掉了那个说真话的检查。

UDP 4500 端口是容器,不是结论

NAT 穿透把 ESP 装在 UDP 里,同一个端口还承载 IKE 和保活消息。因此 4500 上有活动只说明有东西在用这个端口,不说明应用产生了 ESP 包。先对载荷分类,再把它算作数据流量。

当抓包是唯一证据时,这一点尤其重要。按时到达的保活消息能让死掉的隧道看起来还活着,一条 IKE 消息也能让抓包显得比真实数据路径更繁忙。

只有取出内层包之后,路由和策略才生效

解密成功后,还原出的内层数据包进入常规路径:策略检查、路由、转发规则以及目的主机。数据包可以过掉所有安全检查却在这里被丢弃,回程路径也必须存在。那种失败属于转发,不属于 ESP。

让计数器与它文档所写的阶段对应。接口接收、已接受 ESP、已解密字节和已转发的内层包不必是同一个数字,尤其在加速路径负责数据面、控制面另行上报的时候。仪表盘上的一般化标签并不能证明两个计数器含义相同。

对一次全新的授权操作,保留最后确认的边界和第一条相关错误。这一对信息能告诉下一位管理员该查传输交付、联盟与完整性,还是普通的内层转发,也能避免为了挪动一个数字就把每条规则都改成放行。

相关文章