登录状态下命令能跑,于是你把它写进启动脚本就回家了。第二天早上机器在线,隧道却不在线。误区在于:一次能用的调用就等于一个能用的服务。实践中差别通常只有两种:配置属于你的用户会话而不是系统,或者解锁密钥的东西只在登录后才存在。两种情形在手动测试里都完美通过,却偏偏在无人值守的那一刻失败。

为什么登录之后就能用

图形登录会启动会话总线和一个密钥服务代理,许多面向桌面的客户端就把配置的密码或私钥口令存在那里。登录后以你的用户身份运行的激活流程可以问该代理要密钥并成功。由开机单元执行的同一激活流程没有会话、没有总线、也没有代理,于是查询失败,或卡在没人看得见的提示上。

在登录前后各跑一次同一个配置,你会从同一份配置得到两种结果。这是凭据依赖的特征,而不是隧道坏了,也解释了为什么终端里的手动测试并没有看上去那么有说服力。隧道本身没问题;缺的是解锁它的那把钥匙。

确定由哪个所有者启动隧道

有两种受支持的模式,把它们混用则是另一种失败方式。NetworkManager 可以激活系统级连接,适合机器已经把网络集中管理在那里的情形。另一种做法是用专门的 systemd 单元直接运行 VPN,并让它自己拥有该接口。

systemctl list-unit-files 'openvpn*'
systemctl list-unit-files 'wg-quick*'
nmcli connection show --active
systemctl enable --now wg-quick@wg0

不要让两个所有者对着同一份配置运行。如果 NetworkManager 管理接口,而某个单元又把它拉起来,它们会争抢路由和 DNS,最终状态取决于谁最后完成。

把密钥放在服务能读到的地方

后台服务无法回答提示。证书口令、账户密码和引用的认证文件,都需要一套服务单元无需人工即可访问、由运行服务的账户持有、其他人不可读的存储安排。

诱人的捷径是把文件改成所有人可读,直到权限报错消失。这等于用一次开机失败换一次长期凭据暴露,而且这类改动没人会回头复查。请使用部署本来就信任的机制:受限的凭据文件、由文件权限保护的非加密密钥,或带独立密钥存储的系统级连接。

测试真正发生的事件

登录后手动启动服务几乎什么都测不到。重启一次,或者停用图形登录一个周期,看单元能否自行起来。这是唯一能同时检验凭据可用性、网络就绪和单元顺序的测试。它也是唯一能复现用户所报故障的测试,而手动启动永远做不到。

systemctl is-enabled wg-quick@wg0
journalctl -u wg-quick@wg0 -b --no-pager
systemctl status systemd-networkd-wait-online --no-pager

顺序和凭据同样重要。在底层上行链路配置好之前就启动的单元会放弃,而不同发行版对是否等待连通性的处理并不一致。如果单元在开机时报失败,但过三十秒手动启动却成功,你遇到的是顺序问题,不是密钥问题。

不只验接口,还要验路由和 DNS

接口存在不等于隧道可用。无人值守启动之后,先查路由、解析器状态,并按地址查一个目标,再查域名。然后再查隧道所服务的那个应用。

ip -4 route show
resolvectl status
ping -c 3 10.61.0.1
curl -sS --max-time 5 https://internal.example/ -o /dev/null -w '%{http_code}\n'

如果地址通而域名不通,剩下的问题是 DNS 策略,而不是隧道。记下由哪个所有者启动服务、密钥放在哪里,因为下一个重启这台机器的人两样都需要。

相关文章