隧道仍在,路由已失:区分两种 VPN 故障
一个前缀可在三个不同阶段被接收、选中和装表。先看转发表,再看协议表,最后看时钟。
某台主机变得不可达,而隧道接口仍报告自己处于已建立状态,这两个观察并不矛盾。有东西移除了流量原本使用的路径:邻居撤销了前缀,被跟踪的静态路由被撤下,或者另一条路由变得更优。安全关联在这三种情况下都可以完全正常。要区分这些事件,就要问哪一层先发生变化,而不是问 VPN 是否失败。
看似同一事件的三个阶段
路由决策有三个阶段。前缀被接收、被选为最优,并被装入转发表。每个阶段都可能单独失败,而从应用侧看失败现象完全相同。当你看的唯一证据是转发表时,一个已学到但在选举中落败的前缀,与一个从未到达的前缀无法区分。
所以第一个问题是哪一阶段坏了,而不是哪个协议有错。答案决定事件归谁负责,以及下一步检查该用哪个工具。
先读已装入的路由
向内核询问发往故障目的地的流量实际走向哪里。ip route get 会打印下一跳、出接口以及内核将使用的源地址,而且只针对一个目的地作答,不是针对整张表。如果答案指向隧道,说明转发表仍认为路径存在,问题在它之上。
ip route get 10.20.5.10
ip route show 10.20.0.0/16
回答「unreachable」意味着根本没有已装入的路由,这指向撤销或缺失的安装。答案指向物理接口,意味着流量在无人决定的情况下离开了隧道,下一步检查就是胜出的优先级。而答案指向隧道、数据包却仍在消失,则指向路径更下方,指向过滤或对端。
然后看协议自身的视角
路由守护进程维护不止一张表,真正有意义的比较是在它们之间。对 BGP 来说,邻居会话状态、收到的通告和已装入的路由是三份彼此独立的证据。一个前缀可以停在已接收的表中,却因为管理距离更短的路由获胜而永远进不了内核。在断定对端停止通告之前,三处都要检查。
vtysh -c "show bgp summary"
vtysh -c "show bgp ipv4 unicast 10.20.0.0/16"
摘要说明会话是否建立,按前缀的视图说明前缀是否被接受,内核查询说明它是否被装入。按这个顺序阅读,就不会把会话抖动误认为撤销,也不会把撤销误认为策略拒绝。
当时钟不一致
用真实时区把隧道日志、路由日志和应用的首次失败放在同一条时间线上。如果邻居丢失在前,说明隧道把路由一起带下了。如果撤销在前,说明路由先变了,隧道随后才反应。这是两起归属不同的事件,而顺序就是全部结论。
一分钟的时钟偏差就足以反转这个结论,所以在相信顺序之前,先确认时区和偏移。以本地时间记录又不带偏移的设备,是自信却错误的时间线的常见来源。
无环的恢复
撤销之后可能有两条路径合格:协议选出的那条,以及你手工钉住的那条。只有前者是网络持续替你做出的决定,所以手工路由只是权宜之计,不是恢复方案。替代通告也不会为已建立的会话保留防火墙或 NAT 状态,因此新流量可能可用,而原有流量仍然中断。确认应启用哪条备份,以及远端站点是否会通过它 接受回程路径。
在弄清撤销原因之前,不要装入永久性的静态覆盖。这条捷径可能把流量钉在故障路径上,或悄悄绕过有意设置的网络策略,并把根因埋进新配置之下。路由恢复后重新测试应用,并确认所选前缀拥有可用的数据路径,而不只是表里的一条记录。