客户端说认证已通过,IKE 状态看起来很健康,而数据包计数器却一直停在零。这种组合并不矛盾:IKEv2 会把控制关系和数据关系分开,而且第一条可以成功,第二条却始终起不来。父级负责协商,子级负责流量。在判定隧道故障之前,请分别阅读这两层。

两个 SA 各自做什么

IKE SA 是控制关系:它认证对端,并承载协商、替换和删除保护的那些交换。它从不承载你的应用数据包。因此父级健康只能证明两端能就安全策略达成一致,别的什么都证明不了。

CHILD SA 是数据关系,在父级之下创建,带有一个受保护集合的流量选择器和密钥材料。它是有方向的,所以状态输出会列出方向相反的两个关联,各自有独立的标识符,通常每个方向还有各自的计数器。正是这种配对,使得一个方向可用而另一个方向失效,也使得隧道已建立这句话对流量毫无说明。一个父级还可以持有多个子级,于是一个连接标签就藏起了你真正需要的那一个。

阅读子项,而不是连接标签

把父级状态和子级列表一起打开,找到选择器与你正在测试的流相匹配的那个子级。记下它的流量选择器、协商出的算法、生存期,以及两个方向的计数器。如果存在多个子级,请按选择器而不是按位置来匹配,因为重新生成密钥后位置会改变。在改动任何东西之前,先把标识符写下来。

如果父级列出的流量集合与你测试的不同,你读到的是错误的子级。这是选择器问题,不是隧道损坏。

同时记录时间戳。重新生成密钥可能替换掉一层,而另一层保持已建立,一个看起来是新的子级,可能就是你所观察那个的替代者。在得出某个子级消失的结论之前,先比较标识符。

当完全没有子级时

数据提议或选择器失败时,认证仍可能成功,于是父级完全没有子级。常见原因是算法不匹配或流量选择器不匹配,两端都会记录被拒绝的提议。两端都要读,因为你能到达的那一侧可能只显示拒绝。请修复不匹配,而不是重启父级,因为那会重复同一次失败的协商,并给证据再添一次中断。

不断重新建立的父级,与没有子级却保持运行的父级是不同故障。第二种情况下日志会写明被拒绝的提议,所以在修改策略之前,先从两端收集该提议。

当子级存在但计数器停在零时

发送一个与子级选择器匹配的新请求。发往该策略之外目的地的请求不会带动它的计数器,无论看起来多成功。

检查应该把流量推入隧道的那条路由,因为没有流量的子级,往往是没有任何流量被路由过去的子级。只在一个方向上移动的计数器,说明返回路径上存在选择器或策略不匹配。在触碰本地一侧之前,先看看远端对等方的返回选择器。新请求还会给你一个时间戳,用来与两端的状态输出对照。

在报告中指明层次

把故障报告成三个字段,而不是一个结论:失败的是哪一层、你检查的是哪次交换或哪个子级、你掌握的证据是什么。层次只有三种:父级从未建立、子级协商被拒绝,或者子级存在但流量到不了它。证据就是带选择器和计数器的子级标识符,或从两端日志中引用的被拒绝提议。读到这些的人可以直接去看真正重要的那次交换,而不必再问你说的是哪个 VPN。

strongSwan IKEv2 文档 展示了这些层在状态输出中如何出现。请附上你测试过的子级输出,而不只是父级摘要。

相关文章