OpenVPN 服务卡在“输入私钥密码”提示:如何修复
服务没有终端,加密密钥需要 askpass 与一份可读文件。把密钥口令与服务器登录分开,并检查 unit。
OpenVPN 在本机询问私钥口令,因此一份能用的登录文件永远回答不了它。服务没有终端可输入,启动要么卡住,要么失败,日志条目只提到缺失的输入,而不说原因。这里牵涉两个机密,重启 unit 之前,各自都需要可读的来源。下面的步骤把它们分开,再检查真正打开每个文件的身份。
区分两种提示
密钥口令用于解密本地私钥;账号凭据用于向服务器认证会话。两者来源不同、失败时机不同、报错也不同。混淆二者会让人去找密码重置,而账号根本没参与。改任何选项之前先读提示文字,因为措辞是判断缺哪个机密的唯一可靠线索。
在 Community OpenVPN 2.x 中,askpass 指定的文件首行存放密钥口令,auth-user-pass 指定的文件一行用户名、下一行密码。两个文件都不能满足对方的选项。桌面应用或 NetworkManager 配置可能把两者存在自己的密钥库里,命令行客户端从不读取它,所以写路径前先确认自己在配置哪个客户端。
让两个选项都指向可读文件
需要两种输入的配置最终会有 三个文件引用:加密密钥、解锁它的口令,以及登录凭据对。添加它们时不要动 CA 和身份校验,那些决定服务器是谁,不属于这个问题。如果部署根本不用账号凭据,加上 auth-user-pass 只会造出一个没人能提供的输入。
key /etc/openvpn/client/office.key
askpass /etc/openvpn/client/office-key.pass
auth-user-pass /etc/openvpn/client/office-login.auth不带参数的选项与带路径的选项行为不同,在服务里这个差别很关键。不带参数的 askpass 仍然读控制台,而只写了用户名的 auth-user-pass 文件仍会留下一个等待输入的密码提示。客户端一旦转入后台,就完全无法向终端索要输入,这样配置的服务起不来。
绝对路径消除了工作目录的问题,但并不授予访问权限。接着是属主、权限位和路径可达性,三者都要按进程运行所用的账号检查。
先看 unit 的配置,再看配置文件
决定实例加载哪份配置的是 unit,而不是你正在编辑的文件。读它的命令行和所有 drop-in,再顺着工作目录找到真正在用的配置文件。把口令引用加到另一个 .ovpn 文件里,对这个实例毫无影响。
三条只读命令能回答大部分问题。第一条打印 unit 与所有 drop-in,第二条打印约束进程的身份与沙箱设置,第三条打印上一次启动实际报的错。用主机上真实存在的实例名:
systemctl cat [email protected]
systemctl show [email protected] -p User -p Group -p WorkingDirectory -p ProtectHome
journalctl -u [email protected] -b注意 ProtectHome,以及配置文件自己的 user、group、chroot 选项。home 目录下的文件在你的 shell 里可读,一旦 home 被隐藏,服务内部就看不见它。systemd 启动时用的账号,并不总是最后打开密钥的那个账号。
证明运行时身份能打开两个文件
只看权限位不够,路径上每一级目录都必须能被同一身份穿过。逐级检查路径,然后用进程所用的账号实测打开。属主为 root、权限 600 的文件只在进程仍是 root 时可用,而许多配置在降权之后就不再是。两条命令分别覆盖路径穿越和打开:
namei -l /etc/openvpn/client/office-key.pass
sudo -u openvpn test -r /etc/openvpn/client/office-key.pass && echo readable第一条打印每一级的权限,并在账号无法穿越处失败;第二条回答唯一要紧的问题:运行时身份能否以只读方式打开该文件。两条都不打印文件内容,这正是文件里存口令时需要的。对登录文件重复同样的测试,因为两者的属主常常不同。
如果进程用了 chroot 或受限命名空间,就要在那个视图内部跑同样的测试,否则测的是错误的文件系统。存在被隐藏的 home 目录下的口令,就是“unit 外测试通过、unit 内失败”的典型例子。
先看首次启动,再看重连
启动实例一次,看第一个失败而不是最后一个。缺少输入文件、密钥解密失败、服务器返回 AUTH_FAILED,是三件不同的事,修法也各不相同。修掉一条权限告警,并不证明密钥已被解锁。
日志行会告诉你属于哪一种。修法取决于哪个输入失败了:
| What the journal shows | Which input failed | Where to look |
|---|---|---|
| A path that cannot be opened | The file the profile names | Askpass or login path, and the unit's working directory |
| A key decryption error | The key passphrase | First line of the askpass file, and read access for the runtime identity |
AUTH_FAILED from the server | The account credentials | Login file contents, and whether the account is still valid |
然后测试 你真正需要的生命周期:开机启动和支持的重连,而不只是在 shell 里手动启动一次。启用 auth-nocache 后,输入在首次使用后就被丢弃,之后的每次重连仍需一个可读来源。桌面登录时解锁的密钥环,对在任何人登录之前就启动的服务不可用,这正是手动测试通过、重启却失败最常见的原因。如果首次启动成功、之后重连失败,先读重连事件的日志,再考虑改权限。
把口令和密钥放在一起,会削弱加密带来的保障,所以要限制该文件及其备份的权限。去掉密钥口令属于另一项凭据决策,而不是缺少输入时的修法。依赖人工批准或交互式 MFA 的部署,需要用受支持的 agent 或管理集成;把一次性口令永久保存下来并不是等价的替代。