隧道一建立,桌上的打印机就不再响应,而隧道配置里根本没提到打印机。通常发生的情况是,受保护网段写得足够宽,把打印机也包了进去,于是机器现在试图加密本应留在本地网段的流量。读一读已安装的策略就能解释这次捕获;在正确的位置收窄策略则能继续保护远程流量。从失败的请求走到匹配的策略,只需几分钟。

改动选择器之前先走一遍流程

从失败的请求出发,记下四个值:机器使用的源地址、确切的目标地址、内核选择的路由,以及与这对地址匹配的策略。

这四个事实决定了捕获是有意还是偶然。落在远程选择器内的目标地址按设计就是受保护的,即使设计本身有误。目标地址在它之外却仍被捕获,说明匹配到的是别的东西,改选择器不会有用。两种情况都很常见,而一条命令就能把它们区分开。

在动手修改之前先做这件事,因为真正有趣的情况是本地子网与连接所保护的私有网段重叠。像 192.168.0.0/16 这样的常见前缀出现在许多网络中,而为其中一个写下的选择器可能悄悄把你的网络也覆盖进去。

三种行为不同的“本地”

分配给本机的目标、同一链路上的目标、位于另一个接口之后的目标,是三种不同的情况。内核在判断流量是否需要保护时,对每一种的处理都不一样。

由网关自身产生的流量,也与从客户端转发的流量不同。一条对转发流量看起来正确的策略,可能捕获网关自己的管理会话,管理员修隧道时就是这样失去访问的。

有用的习惯是把情况说清楚:这个包是来自我、去往我的链路,还是穿过我?每个答案都指向不同的收窄位置。把情况写下来,也能防止下一个人重做同样的工作。

当受保护网段是整个私有空间时,三种情况可能同时落在里面,症状就变成一台除了隧道端点哪儿都到不了的机器。

读已安装的策略,而不是配置文件

配置文件描述意图;内核保存的是真正匹配的策略。把两者都打印出来,并把不一致当作第一个发现。

这些命令分别显示为目标选择的路由,以及每个方向上已安装的策略:

ip route get 192.168.50.20
ip xfrm policy list
sudo swanctl --list-conns

路由告诉你这个包会走哪块网卡。策略列表告诉你它随后会不会套上模板,连接列表则显示守护进程认为自己装了哪些选择器。如果目标出现在远程选择器里,不用猜就已经找到捕获了。

收窄选择器,或者绕过目标

有两种受支持的修法,它们回答的是不同的问题。收窄选择器表示这条连接只保护更小的范围,适用于更宽的范围本来就是错误的情况。添加绕过表示这个特定目标永远不该受保护,适用于受保护范围确实很宽、而某个目标是例外的情况。

能选第一种就选第一种,因为更小的选择器更容易推理,也会出现在连接定义里。当宽范围是有意为之、而例外是一个你能叫得出名字的主机或子网时,再选第二种。

两者都属于拥有这条连接的配置。手工添加的运行时规则会在下次重连时消失,故障就会在没人记得这个临时办法的时候回来。

能扛住重装的例外

改完之后,重复同一个无害请求,并看同一组计数器。本地目标应当恢复应答,原本要访问的远程目标应当仍然显示加密流量。

这两项检查确认例外活了下来,而保护没有丢:

ip xfrm policy list | grep -c out
ping -c 3 192.168.50.20

然后故意断开并重连隧道,把两项都再做一遍。一个在重连前有效、重连后失效的例外,是被加到了错误的层上,而这正是这个问题最常见的复发方式。

相关文章