UDP VPN 空闲后中断:防火墙把你的流忘了
客户端仍显示会话时,防火墙可能已丢弃空闲的 UDP 映射。先测量中断,找出最短的定时器,再选择修复方式。
VPN 连上后能工作一段时间,随后在客户端仍显示会话的情况下停止转发流量。重新连接就能恢复,所以看起来像客户端的问题。实际上通常是防火墙或 NAT 设备丢弃了空闲的 UDP 映射,并且不知道隧道仍然存在。
这个症状足够稳定,可以据此诊断:它出现在空闲之后,而不是负载之下。
空闲中断是什么样子
不要描述,要测量。记录隧道空闲多久后流量停止、新的出站数据包能否让它恢复、客户端接口是否仍持有地址。如果客户端发来的新请求能用,但对已有流的回应不能用,可疑的就是映射。如果必须重新连接才有任何流量,客户端的会话状态也已经丢失。
两者都与空闲有关,但需要的修复并不相同。
改动之前先把时间记下来。说它空闲约十分钟后中断,这种报告可以验证;说它随机掉线,就无法验证。这一差别决定了你要追定时器还是追路由改动。
找出忘记流的那台设备
同一股流的状态可能被多台设备保存:本地路由器、上游转换设备、云边界和主机防火墙。每台都有自己的定时器,最短的那个生效。五分钟就断,通常说明某台设备配置得远低于其他设备。
不要以为文档里的默认值就是你这条路径上的超时。那只是一台设备的默认值。
- 家用路由器:常常是几分钟,有时短得多。
- 云 NAT 或负载均衡器:去查文档里专门针对 UDP 的空闲超时。
- 主机防火墙:netfilter 的跟踪定时器按流生效。
在实际路径上检查定时器
在 Linux 上,netfilter 的跟踪定时器可见也可调: sysctl net.netfilter.nf_conntrack_udp_timeout 和 net.netfilter.nf_conntrack_udp_timeout_stream。第二个在双向都看到流量之后才生效,所以已经建立的隧道能比一次简单的探测活得更久。
RFC 4787 规定了 UDP NAT 的行为和建议的最低值。当厂商默认值看起来短得不正常时,就该引用这份文档。
Keepalive 与重连是两种不同的工具
Keepalive 让映射保持存活;重连则重建已经死掉的会话。它们解决不同的故障,也不是可以互换的速度设置。WireGuard 的 PersistentKeepalive 会按固定间隔发送数据包,让 NAT 绑定保持打开。OpenVPN 的 keepalive 选项用自己的方式做同样的事。如果中间设备已经忘了这股流、两个方向都丢弃,两者都帮不上忙。
过于频繁的探测只会增加开销,并不能修正错误的边界。
用新请求验证,而不是刷新页面
改完定时器或加上 keepalive 之后,完全按原样重跑一遍空闲场景。然后从被覆盖的应用发出一个真正的新请求。已经加载过的浏览器标签页可能直接从缓存渲染,什么也说明不了。
如果中断仍然存在,就往外走一跳,检查那台设备的状态表。