为什么 IPsec 安全策略不是路由表条目
一条能用的路由并不能证明 IPsec 的任何事。请对照同一流量的路由查找与策略选择器,再确认有一条安全关联覆盖它。
通过隧道 ping 10.20.0.5 却什么也不返回,而路由表坚称该子网可达。路由与 IPsec 回答的是不同的问题,只有一个与可达性有关。转发查找先选出路径,随后安全策略数据库决定该路径必须受保护、保持原样还是被拒绝。两者不一致时,数据包会悄无声息地消失,所以要按这个顺序去读。
从查找开始,而不是从表开始
问内核它究竟会怎么做:ip route get 10.20.0.5 会打印选中的路由、出接口以及它将使用的源地址。前缀、策略规则、标记或首选源都可能改变这个答案,因此实时查找胜过用眼睛读表。
测试受保护范围内的目的地址,而不是网关地址。能到达对端网关只证明存在某条路由,对你真正需要的子网一无所知。然后再确认查找所选的接口正是你期望隧道使用的那个。
两侧的选择器要匹配
策略数据库有自己的条目,每条都写明方向、源、目的和协议,然后规定匹配的数据包应当如何处理。用 ip xfrm policy 列出它们;标志会显示动作是保护、绕过还是阻断。选择器比测试流量更宽或更窄的策略不会匹配,数据包会不受保护地发出。这才是你要找的故障,而不是缺少路由。
比较实际取值:源、目的、协议和端口。如果查找解析出一对地址,而策略条目覆盖的是另一对,两种视图描述的就是不同的流量。下结论前用同一元组把两者都重跑一遍,否则你会去改一条从未在路径上的策略。
策略匹配不等于已安装状态
匹配的策略只说明数据包必须受保护;内核仍然需要一条安全关联来执行保护。用 ip xfrm state 列出它们,或在内核交由 strongSwan 协商时用 swanctl --list-sas,并读取每条条目的选择器与计数器。
当策略匹配而没有关联覆盖同样的选择器时,数据包会被丢弃,而不是以明文发出。隧道正常但单个子网失败时,要找的就是这种丢弃。计数器会说明其余部分:从不增长的关联从未被选中,而增长了却仍以丢弃收场的关联指向远端。修选择器和重新生成密钥是两种不同的修复,动手改配置前先确定你需要哪一种。
基于路由的隧道仍然需要什么
XFRM 接口让隧道看起来像一块可以路由进去的设备,这确实有用。但它并不能去掉那些决定数据包到达之后如何处理的策略与状态。路由只贡献下一跳,仅此而已。
如果设备存在且路由指向它,却没有关联匹配内层选择器,数据包会被丢弃,再怎么改路由也生不出密钥或选择器。用你当初路由的同一源和目的检查该接口,再把它与状态列表对照。
动手修改之前先厘清归属
主机防火墙增加了两个数据库都不知道的第三个决定。正确的路由、匹配的策略加上已安装的关联,仍可能止于被丢弃的数据包,而应用只报告超时。在怪罪 IPsec 之前,先确认防火墙允许受保护的流量。在隧道设备和物理接口上抓包,能看出数据包消失在加密的哪一侧。
配置归属决定你的修复能否在重启后保留。某个组件安装状态,另一个组件管理路由,对后者的手工修改会在隧道下次建立时被覆盖。改拥有者的配置,然后重读两种视图;RFC 4301 在你需要向别人解释这种分工时,把两个数据库明确分开。