在没有用户登录的情况下重启服务器,然后从一个不受你控制的网络连接。这一次测试就能回答恢复是否真实,因为只在有人手动执行命令之后才可用的隧道不叫恢复,那叫修复。大多数检查停得太早:服务显示为活动,接口已起来,页面却仍然打不开。缺口几乎总是出在隧道周边组件的持久性上,而不是隧道命令本身。

四类所有者,四种不同的测试

重启之前,先点名应该由谁把隧道带回来。你做的测试和你要应用的修复都取决于这个答案,常见的所有者有四类:VPN 服务的 systemd unit、WireGuard 接口的 wg-quick 实例 unit、容器运行时,或网络管理器配置。如果你说不出所有者,先停下来找到它,因为没有预期启动路径的重启测试只能告诉你「发生了什么」。

每个所有者把配置放在不同位置。由 systemd 管理的 OpenVPN 服务器在启动时读取配置,所以开机那一刻文件里是什么,运行的就是什么。wg-quick 接口从同一个文件推导地址、路由和 DNS,这意味着从 shell 手动拉起、却从未启用为 unit 的接口不会回来。容器会带回自己的入口,但不会带回宿主上的防火墙改动,除非这些改动位于容器之外。

先建立基线,否则结果没有意义

趁系统还正常时记录工作状态:隧道上的地址、客户端子网的路由、NAT 或转发规则、监听套接字,以及转发 sysctl。ip addr show wg0、ip route、nft list ruleset 或 iptables-save、ss -lunp、sysctl net.ipv4.ip_forward 在大多数主机上就够用。

记录服务是如何配置启动的,而不只是它正在运行。systemctl is-enabled wg-quick@wg0 和 systemctl is-active wg-quick@wg0 回答的是不同问题,开机时真正重要的是已启用状态,正如 systemctl(1) 所述。对于 OpenVPN,要确认主机用的是哪个模板,因为 openvpn@server 和 openvpn-server@server 是默认值不同的两个 unit。

执行重启并读出第一个失败点

在你选定的时间窗口内故意重启,并保持控制台或带外通道可用。关注事件顺序而不是最终状态:主机可达、unit 已激活、接口存在、路由已装、防火墙规则存在、监听已绑定、客户端被接受。第一个没有发生的环节就是结论,之后的一切都是噪音。

隧道不可用时服务仍可能是活动状态,这是最常见的假通过。如果 unit 只等 network.target 而不等 network-online.target,启动可能在网络上线之前就完成了。被引用的文件(证书、密钥或 CRL)那一刻可能读不到,因为挂载点或密钥路径还没就绪。这两个问题都不会出现在 systemctl status 里,直到你读该 unit 的日志。

从主机之外测试。同一 LAN 内的客户端可能通过一条远程客户端永远不会用的路由成功,而到机器上的 SSH 会话并不能证明隧道可用。连接、解析内部名称、访问私有资源,然后再连一次以确认吊销状态和密钥仍然生效。

决定修复方向的三类条件

如果隧道回来了但客户端什么都访问不到,故障在路由或 NAT 持久化。如果客户端连握手都完成不了,故障在接口或认证材料。如果服务根本不启动,故障在 unit 文件或其依赖。这三条分支通向不同的修复,所以没有基线的盲目重启,花费的时间比省下的多。

在设置的归属处做修复。把转发放进 sysctl drop-in,把 NAT 规则放进开机加载的规则集,启用 unit 而不是启动它,并把密钥放在 unit 启动之前就存在的路径上。给 unit 加 sleep 只是把依赖藏起来,而不是声明它。

把结果写进 runbook

写下哪些是自行恢复的、哪些是你手动启动的,以及缺口持续了多久。把验证用的确切命令一并写入,让下一个人重复测试而不是另发明一个。如果某一步需要手动命令,那条命令应进入配置,而不是作为永久步骤留在 runbook 里。

然后把下一次测试安排在主机网络栈下一次变更之后,而不是六个月后的某一天。你要防的失效模式是「感觉像永久的临时命令」,而它们恰好出现在有人修改防火墙规则或把服务迁移到新 unit 的时候。

相关文章