无人值守的 VPN 服务器更新需要一条你亲自测试过的恢复路径
更新可能重启你用来连到服务器的那项服务。在自动化之前,请把带外控制台与仅靠隧道的恢复方案做一次比较。
对于你通过它自己的 VPN 才能连上的服务器来说,无人值守更新是一项合理策略,同时也是一处你自己造成的单点故障。软件包操作会重启服务,隧道随之中断,而你正在使用的管理通道也一并消失。恢复模型有两种,二者之间的取舍取决于一个条件:你是否有 一条不经过被更新对象的入口通道。
两种恢复模型,一个决定性条件
第一种模型信任更新,并假定之后你能重新连上。当 VPN 只是到达主机的多种方式之一,且隧道故障不会剥夺你的诊断能力时,它就行得通。第二种模型预先准备一条独立通道,通常是托管商的控制台,并把隧道视为最容易被维护弄坏的东西。两种模型都站得住脚,而只有一种需要提前做工作。
决定性条件说起来简单,跳过也很容易。如果通往这台机器的每条管理通道都要经过被更新的服务,那你根本没有恢复模型,只有一份期待。请在变更评审上把这句话大声说出来。
测试这个条件只需十分钟,而且必须发生在第一次无人值守更新之前,而不是事故当中。在一切正常时打开控制台,确认凭据仍然有效,然后再关掉。确认控制台打开的是你以为的那台主机。接着确认你凌晨 3 点真正会用的登录仍然可用。
最后这一点比听起来更重要。一个半年前改过密码、却从未验证过的控制台账号不是恢复路径,而是一份描述恢复路径的文件。
备份不能恢复的东西
配置归档只是文件的记录,而更新改变的不止文件。软件包状态、内核模块、已启用的单元链接,以及通过另一套工具施加的防火墙规则,全都活在配置目录之外;一次忽略它们的恢复,只会得到一台看起来配置完好却不转发流量的机器。
| What changed | Restored by a configuration backup | Needs its own action |
|---|---|---|
| Service unit or startup ordering | Partly, if the unit file was included | Package state and enabled links |
| Kernel module or interface support | No | Kernel or module rollback, or a boot-time decision |
| Peer or device authorization | Only if the backup predates the revocation | A deliberate decision about which peers return |
| Firewall rules applied outside the config | Only if they were captured | Replaying and verifying each rule |
授权值得单独一行。在清除被入侵设备之前所做的备份,会欣然把那台设备的访问权也一并恢复。停机时回滚到它,正是一起事故变成两起的途径;而是否恢复的决定,应当像对待文件那样明确地对待对等端。
回滚的机制同样重要。把旧的二进制文件覆盖到由软件包管理的文件上,并不是受支持的包变更回退方式,它还会让包数据库描述一个与文件系统不符的状态。请使用包管理器自带的降级路径,或托管商提供的快照。只有包数据库记录在案的降级,才是你能重复执行的降级。
以上都不构成反对备份的理由。它主张的是:要知道每件产物覆盖哪一层,因为部分恢复的失败方式比最初的停机更让人困惑。请在运行手册里,把层写在各份备份旁边。
先记检查点,再更新,然后从外部验证
用之后可以比对的形式记录变更前的状态:已安装的版本、涉及的服务单元、正在监听的套接字,以及当前的对等端列表。在 Linux 主机上,四条命令就能覆盖其中大部分。
systemctl list-units --type=service | grep -E 'openvpn|wg-quick'
ss -lunp | grep -E ':51820|:1194'
journalctl -u wg-quick@wg0 --since '-10 min'
第一条显示有哪些单元、是否在运行;第二条确认监听者确实绑定成功;第三条给出服务自己对最近几分钟的说明。它们都不能证明客户端连得上,所以下一步要在主机之外进行。把这些读数留作你的比对基线。
请从不经过隧道的网络验证:认证一个被授权的客户端,解析一个名字,并访问一个目标应用。本地状态行说接口是通的,那只是关于接口的陈述,而不是关于路由、密钥或允许对等端接入的策略。
然后刻意测试重连路径。把服务重启一次,确认隧道无需人工干预就能恢复;因为只在开机时才能正确启动的服务,会在最糟的时刻给你惊喜。
失败时,走你测试过的那条路径
恢复顺序并不光鲜,但它有效:通过独立通道进入主机,读取服务自己的日志,并恢复与故障相对应的那个检查点。每次只改一件事,这样下一次读日志才有意义。
要抵制为了恢复连通性而同时做几处未记录改动的冲动。靠五处同时修改修好的机器,事后无法解释;而下一次更新会把真正承重的那一处重新带回来。
然后用证据决定长期策略。如果更新暴露出没人记录的依赖,正确的修法是补文档并加测试,而不是关掉更新。如果它暴露出一项无法干净重启的服务,正确的修法在单元里,而不在时间表里。
一旦把这个条件说出来,比较就干净地得出结论。有独立通道,无人值守更新就是可控风险。没有它,同一套策略就变成恢复时间未知的计划内停机,而再多的自动化也改变不了这道算术。