OpenConnect 应该对掉线的 VPN 继续重试多久?
OpenConnect 的重连超时限制的是链路中断或对端无响应后的重试,而不是进程监管、凭据续期或流量封锁。
--reconnect-timeout 只回答一个很窄的问题:隧道掉线后,这个客户端进程还要试多久才会放弃并退出。OpenConnect 手册页 记录了这个选项,文档给出的默认值是 300 秒,用于链路丢失或对端停止应答之后的重试;这个数字是单个运行中客户端的截止期限,而不是 VPN 仍然可达的证明。它也不是让进程保持存活的管理策略,大部分混淆正是从这里开始的。
当第二套机制叠在上面时,混淆会加倍。重启客户端的监管程序、ping 网关的探测程序,以及内置的重试窗口,都会对同一次故障做出反应,于是事故产生三条谁也对不上的时间线。
重连窗口实际限制了什么
设想接入网络消失了几秒钟。客户端看到链路断开,或者听不到死对端的应答,于是开始重建会话,同时尽量保留状态。重试会持续到网关再次接受,或者窗口耗尽;窗口耗尽会以非零退出结束。真正把生命周期所有权交给监管方的是这个退出,而不是超时数值。
窗口没有说明探测程序多久运行一次,也无法延长认证。如果网关撤销了会话,或者账户现在要求新的第二因素,等得更久并不会让旧会话重新有效。重试只有在路径恢复、网关仍然认得该会话、且所需凭据仍然可用时才会成功,所以要把这个数字读成截止期限,而不是存活间隔。
窗口也不管运行期间应用的行为。取决于平台和故障推进的程度,客户端可能在路由仍安装时重连,也可能在路由被撤销后重连。这就是为什么中断期间发出的请求往往一直挂到超时,而不是快速失败。
监管程序的重启与客户端的重试是两个层次
让运行中的客户端消耗自己的窗口,让服务管理器对退出做出反应。systemd 下带重启策略的前台客户端正好给出这种分工:在一段有界时间内重试,然后只做一次重启决定。结果是一条事后仍可还原的时间线。
后台客户端加上一个独立轮询器,在看不到接口时再启动一份副本,就是会出错的模式。两个进程随后会争夺同一个设备节点、路由和解析器设置。如果确实想要守护进程,就把该选项放到客户端真正启动时使用的命令行上:
sudo openconnect --background --pid-file=/run/openconnect/vpn.pid \
--reconnect-timeout=180 \
--user=<account> https://vpn.example.edu那一行里有两个细节很有分量。--background 会分离进程,因此 pid 文件成为它唯一可靠的抓手;超时也只在该进程存活期间消耗,杀掉它的监管程序不会留下继续的预算。
有意的断连需要自己的信号。计划内的暂停和真正的故障在朴素观察者看来完全一样,两者都会被读成“未连接”。请通过监管程序的停止操作,或包装脚本能理解的标记来驱动暂停,使有意的停止不会触发没人要求过的重启。
避免交接与重试循环赛跑
无人值守的恢复依赖无需人在场就能续期的凭据。只在交互式桌面会话内解锁的密钥环,或者始终需要手动输入代码的令牌,会在路径恢复后把客户端卡在认证阶段。先把这套工作流解决掉,再延长窗口,因为更长的窗口只是给同一个被阻塞的提示更多失败时间。
不应为了减少提示而放宽服务器校验。正是校验网关的固定或信任锚,才让自动重连变得安全;为了回避证书问题而关掉它,是把可见的中断换成不可见的中断。保留已验证的身份,转而修复提示;愿意连接任何网关的客户端,比停下来等待的更糟。
接口存在也不是健康信号。隧道设备可以存在,但其背后是死会话;启动进程也可以存在,却完全没有隧道。这些观察都经不起真实请求的检验。健康必须来自用户需要的东西,例如一个穿过隧道到达已知内部服务的请求。
中断期间和之后要验证什么
把四个事件当作独立的测试:短于窗口的中断、长于窗口的故障、认证失败,以及有意的停止。每个都应以不同且可预测的状态结束,而前两者的边界正是选择这个数值的全部理由。
让检查朝外,因为进程表本身证明不了什么。观察 pid 在短切断期间是否保持稳定,然后在长切断之后确认它已消失且只被替换过一次:
curl -sS --max-time 5 -o /dev/null -w '%{http_code}\n' https://intranet.example.internal/health
cat /run/openconnect/vpn.pid
ps -o pid,etime,cmd -p "$(cat /run/openconnect/vpn.pid)"短中断期间,确认客户端确实重试过而不是提前退出,并确认路由和解析器条目无重复地恢复。较长的故障则确认干净退出,且之后恰好发生一次重启。认证失败时确认客户端没有对着会持续拒绝它的网关空转。再加一项检查:pid 回到单一值,而不是不断累积。
对于有意的停止,健康检查 URL 应保持不可达,进程应保持停止。然后从应用侧闭环:同一个请求在隧道消失时必须失败,并在隧道恢复后从策略期望的源地址成功。绿色隧道图标不是证据,完成一次请求才是。