客户端图标显示已连接,接口也确实存在,但应用仍然什么都访问不到。这种情况很常见,因为虚拟接口可以在远端对端、地址或路由缺失时继续存在。ip link 是正确的第一个工具,也是最容易被过度解读的工具。标志和计数器只描述一层,而它们上面的各层会各自独立地失败。人们想证明隧道已经起来时,引用的也常是它,而这恰恰是它单独无法支撑的结论。

先看接口,再看图标

先用 ip -details link show dev tun0,按 ip-link 手册 的说明,把命令里的接口换成你客户端实际持有的名字,而不是那个约定俗成的名字。标志、类型、MTU 和接口身份都是有用的观察项。虚拟接口的状态措辞不必像物理网线那样表现为载波指示,所以 UP 只应被读作关于接口本身的陈述,而不是关于隧道的。

这一区别正好解释了最令人困惑的情形:远端正在重连或不可达时,接口却依然存在。

持久化设置恰恰可以把链路保留下来,好让重连时不必重建它,这意味着存在不等于健康。

把计数器和一个应当走它的请求加进来

用受支持的统计视图 ip -s link show dev tun0,记下两个方向上的包数与字节数。然后发一个应当穿过该接口的无害请求,对比相关方向的计数。若某个请求走了另一个应用的直达路由,那些计数器就不会动,这正是这项练习的目的。

如果发送计数器在动、接收计数器不动,那就说明 包发出去了,却没有东西回来。这与接口从未承载过任何流量是两回事。如果两个计数器都在动而应用仍然失败,故障就在接口之上,这算是进展,而不是死路。

读数要取两次,一次在操作前、一次在操作后,不要只信一张快照。

地址和路由是两个独立的步骤

链路可以存在,却缺少应用所需的前缀、解析器配置或路由。用 ip address show dev tun0 查地址,再针对真实目标用 ip route get 查目的地会选中哪条路由。这三项观察回答的是三个不同的问题,只有最后一项才关乎转发。

对 IPsec 来说,安全策略和关联状态也可能相关,而且并非所有 IPsec 设计都会表现为一个简单的 tun 接口。去找一个本来就不会存在的 tun 设备,是快速得出错误结论的捷径。

保留任何输出时,都记下确切的接口名、命名空间和时间,因为另一个容器或恢复出来的会话里看起来相同的名字,代表的是完全不同的上下文。

没有弄清身份之前,不要删除

陌生的接口并不自动等于陈旧。删除任何东西之前先确认它的归属,确实需要移除时,用客户端文档中给出的拆除方式或受管配置。为了看看会怎样而删掉一条活跃隧道,是一个回答了没人提出的问题的测试。

如果该接口属于某个容器运行时或你并未创建的命名空间,它的归属只差一条命令,值得先找出来。

这条提醒同样适用于 ip link set down,它看似可逆,但往往并非如此。

检查结束时应当留下什么

一次好的检查最后会得到四个事实:接口名与命名空间、它的标志与 MTU、真实请求带来的计数器增量,以及应用实际需要的路由与地址。把这些写下来,下一步就显而易见了,而且能落到具体的一层上。没有这些,之后的每一次改动都只是带着回滚方案的猜测。

把这四个事实与一次正常工作会话里的同样四项对比。如果接口名与命名空间一致,但计数器增量为零,说明请求从未到达隧道。如果计数器增量正常、路由却指向别处,那隧道没问题,路由有问题。正是这种对比,把一堆输出变成了一项决定。

把输出连同工单一起保存,因为只有当你能看出改了什么,之后的对比才有用。

最后再测一次应用,把这个环闭上,因为接口从来不是用户真正关心的东西。

相关文章