Linux 应该把 VPN 密码存在哪里?不是配置文件里
NetworkManager 的密钥标志决定密码由配置文件、密钥环代理还是无人保管。答案取决于连接在何时启动。
VPN 密码总得有个落脚处:连接配置文件里、桌面解锁的密钥环里,或者哪里都不放。NetworkManager 把这一选择称为密钥标志,选错就会导致连接在登录后能用、作为服务却失败。这个标志只有一行配置,却决定了你会得到那三种结果中的哪一种。
三个标志几乎覆盖所有情况,决定的关键在于连接何时启动。
三种密钥标志,三种行为
标志 0 表示密钥随连接一起保存,保存在持有该配置文件的任意存储中。标志 1 表示由代理持有:密钥来自密钥环之类的密钥代理,NetworkManager 在激活时向它索取。标志 2 表示不保存,密钥永远不会被写入,每次都必须提供。标志 4 把密钥标记为不需要,适用于确实不需要任何密钥的连接。
| Flag | Where it lives | Works unattended |
|---|---|---|
| 0 saved | Connection profile | Yes, if the store is readable |
| 1 agent-owned | Secret agent or keyring | Only if that agent is available |
| 2 not-saved | Nowhere | No |
标志要按密钥设置,而不是按连接设置。一个连接可以同时拥有由代理持有的密码和已保存的私钥口令。
按连接何时启动来决定
如果连接由已登录的用户启动,由代理持有是合理的默认选择,密钥环在登录时解锁,密钥永远不会落在文件里。如果连接必须在任何人登录之前启动,由代理持有就是错误的选择,因为 根本没有可供解锁的会话密钥环。
整个决定就是这样。其余都是它的变体。
对于登录前运行的服务,受支持的做法是系统级存储或受保护的密钥文件,文件权限就成了保护手段。不要靠把密码贴进开机运行的 shell 脚本来解决问题。
密钥环能给你什么,不能给你什么
密钥环把密钥挡在连接配置文件之外,并将其绑定到用户会话。它不会让没有会话的服务拿到密钥,也不会在链路上加密任何东西。这是人们经常混为一谈的两件事。它真正带来的,是配置文件泄露时更小的爆炸半径。
配置文件引用的私钥需要自己的权限,与密码存放在哪里无关。
不倾倒密钥的诊断
连接名称、UUID 和标志通常足以解释一次失败。 nmcli connection show 会列出该配置文件,而密钥标志会告诉你密码本应来自何处。
要避免 --show-secrets 出现在工单和聊天里。一旦粘贴,它就是留存在记录中的凭据。
存储不等于吊销
从一个密钥环里删除密钥,并不能让远端的运维方已接受的凭据失效。账号吊销是服务端的动作,而本地存储是另一件事,归另一个人管。
两件事都要在事故之前决定,而不是事故当中。交互式用户连接和登录前服务需要不同的答案,而共享的 shell 脚本两边都不是。NetworkManager 的 密钥标志文档 完整列出了这些取值。