照字面读这个选项名。它命名的是密钥,当被解锁的文件与正在认证的账户混为一谈时,困惑就开始了。把账户密码粘贴进这个选项,客户端会用它去打开密钥文件,失败的原因与 VPN 登录毫无关系。

令人困惑的地方在于,同一条连接可以合理地需要两个机密。客户端证书认证可能需要加密密钥,而同一个网关在证书被接受后仍可能进行用户认证交换。两个机密都不能满足另一个阶段,而其中一个失败时,从外面看和另一个失败非常相似。

两个机密,两项不同的工作

把角色理解为文件访问与网络准入。密钥口令解密 --sslkey 指定的 PEM 私钥,以便出示 TLS 客户端证书。解密在本地、在客户端进程内完成,口令本身从不会传到网关。网关看到的是证书和用该密钥生成的签名。OpenConnect 的手册把 --key-password 与 --certificate 和 --sslkey 放在一起,而在可以使用 TPM 中密钥的构建里,同一选项改为携带存储根密钥的口令。

账户密码是另一种东西。它进入认证交换:用户名与密码表单、令牌、SAML 往返,或网关公布的某种组合。有些部署在证书是唯一因素时根本不问它,有些即使已有证书也会问,因为证书证明设备,账户证明人。

把两者混在一起会产生误导性的错误。拒绝登录的网关通常报告认证失败,而错误的密钥口令通常失败得更早,此时 TLS 层读不了密钥文件。这是不同阶段、不同修法,而名称又足够相似,人们把它们对调之后就去追错日志。在改动任何设置之前,先记下出现的是哪一个提示,因为提示的措辞就是你手头最便宜的诊断。

什么时候真正需要密钥口令

只有存在需要解锁的加密密钥时,这个选项才有意义。如果你用用户名和密码连接而且没有客户端证书,--key-password 就无从发挥作用,加上它也改变不了什么。如果你用 --certificate 和 --sslkey 连接,密钥文件自身的格式决定是否会要求口令。

同一条命令里放两个机密在受管环境中很常见:加密密钥中的设备证书,加上每个用户各自的登录。正确的顺序是让客户端在本地索要密钥口令,完成证书握手,然后单独处理网关的账户提示。想用一个重复使用的脚本把两者都预先填好,通常正是混淆的起点。

有用的诊断是看失败发生在什么时候。如果客户端在任何网络认证开始之前就停下,怀疑密钥文件、它的格式或口令。如果 TLS 会话已经建立,随后网关拒绝了用户,那么密钥完成了它的工作,问题在账户交换。

把两个机密挡在 shell 历史之外

命令行参数可以通过进程表被其他本地用户读到,而且经常被 shell 历史、脚本和支持记录留下来。OpenConnect 可以用 --passwd-on-stdin 从标准输入读取账户密码,密钥口令可以来自交互式提示或代理,而不是参数。两种机制本身都不能让机密变安全,但都能把它从最暴露的地方移开。

文件也值得同样的谨慎。把口令写进临时文件的脚本应当以受限权限创建它,在退出时删除它,并避开所有人可读的目录。会话结束后还留在临时目录里的口令,就是你忘掉的副本。环境变量对子进程可见,又常常被调试工具打印出来,所以它并不是相对参数的免费升级。

诊断输出是安静的泄漏。更高详细度的客户端日志可能显示请求体或选项值,而复制的终端记录很容易粘进工单,所以在分享之前先读一遍输出。

失效的桌面按钮是另一种故障

一个显示转圈、然后什么也没发生的桌面 VPN 入口,通常根本不是认证问题。那个按钮属于网络管理器、厂商小程序,或替你启动 OpenConnect 的插件,而缺失的组件或读不了的配置文件恰好能产生这种症状。先找出按钮启动了哪个进程,读它的错误,再去动凭据。

当图形界面拒绝连接时,放松证书校验或关掉某项检查很有诱惑力。那会把客户端集成故障变成安全降级,而且很少修好启动问题。保持服务端校验完整,确认配置文件指向预期的网关,并检查界面所期待的辅助程序是否真的安装好了。

一份简短的清单能把几种情况分开。任何数据包发出之前的本地失败,指向密钥或客户端安装。TLS 会话之后的网关拒绝,指向账户交换。从不启动客户端的按钮,指向桌面集成。三种不同的故障,其中一种是差点被粘进错误输入框的密码。

相关文章