WAN IP 变更与隧道掉线:按顺序排查
先记录 WAN 事件,再看哪些环节没有跟随它更新:过期的转换表项、绑定旧网关的路由、仍在向旧地址发送的对端。
隧道掉线,路由器记录一次重连,而局域网内没有任何东西移动。新的 WAN 地址会让外层连接失效,却不改动内部任何东西:客户端的源地址变了,旧的 NAT 状态指向一个已不存在的源,远端对端可能仍在向旧地址发送。恢复是正常行为,真正有用的问题是哪个状态没有更新。
先给事件命名,再读日志
确认接入层到底发生了什么。ISP 续租是一个事件。PPPoE 会话重连是另一个。光猫重启,或 WAN 从一条上行切换到另一条,属于第三种改变外层地址或其路径的方式。它们不是同一个事件,留下的残留也不同。
VPN 日志里的重连行同样不能证明 WAN 变了。空闲超时、重新认证间隔和死对端检测都会产生重连,却完全不伴随地址变化。下结论前先把接入日志的时间戳与 VPN 日志对照,并把对照窗口留得足够宽,以覆盖夜间发生的变更。
漫游与重连是两种不同的协议
WireGuard 把经过认证的漫游内建在协议里:当对端收到来自新源地址且认证正确的数据包时,它会更新该对端的端点。WireGuard 快速入门描述了让这一机制生效的对端配置,这也是地址变化中的客户端常常无需可见重启即可恢复的原因。
OpenVPN默认行为不同。UDP 会话可以结束并重连,可选的 float 行为允许已认证的对端在配置允许的情况下从新地址继续。基于 TCP 的隧道更严格,因为连接本身与地址对绑定。这一差异决定了恢复看起来是无声无息,还是每次都在日志里自我宣告。
两种行为都没有说明内部应用的情况。恢复的隧道不会恢复对端已经判定为死亡的 TCP 会话。
隧道并不拥有的状态
转换与路由状态会以令人意外的方式在重连后幸存。为旧源创建的 conntrack 表项会把回程路径钉在一个已不存在的地址上,而它按自己的时间表过期,并不跟随隧道恢复。重启隧道服务不会缩短这段等待,所以修好的链路仍可能在一段时间里看起来是坏的。
路由与策略规则可能引用旧的网关或接口。切换 WAN 之前正确的规则集,可能指向一台现在已宕机的设备,于是隧道报告已连接,流量却无处可去。自建服务器的动态 DNS 与客户端获得新源地址是两件事。记录必须更新,远端客户端才能找到你;而上游转换不会转发的地址,靠任何客户端侧配置都补不回来。
把排查从外向内排序
下面的顺序从外层连接向内推进,而正是“在第一个失败步骤停下”让它有用:每一轮都排除掉上面那一层。即使故障看起来很明显,也要守住这个顺序。
wg show
ip -br addr show
ip route get 198.51.100.7
conntrack -L 2>/dev/null | grep -c ESTABLISHED
journalctl -u openvpn-client@home --since '-2 hours' | tail -n 40
第一条命令显示每个对端当前的端点与握手时间。第二条和第三条显示外层接口以及到端点的路由是否仍然合理。conntrack 计数是对旧地址残留状态的粗查,而日志记录了重连原因。
然后从局域网客户端测试,而不是从路由器。由路由器自身发出的 ping 走的是与转发流量不同的路径,所以路由器 ping 成功只能证明隧道存在,完全不能说明客户端能否到达。
确定期望行为并写下来
对大多数部署来说,重连就是正确行为,所以目标不是阻止它。要决定的是中断期间流量该怎么办:停住、挂起,还是切到另一条路径。这个决定属于防火墙与路由策略,而不属于 VPN 配置。
把接入事件与重连时间一起记录一周。反复变更却没有对应的接入事件,指向接入服务;换掉 VPN 配置也修不好一条不断重新协商的上行。同一分钟里的一对记录,就能为这次事故定案,并给下一次留下基线。