同样的配置,两种会话:从桌面连得上,走 SSH 却卡在一个没人能应答的提示上。什么都没坏,也没有丢设置。NetworkManager 在向密钥代理索要凭据,而密钥代理是你当前会话里不存在的桌面组件。

执行下面的命令,隧道就能在没有图形界面的情况下起来;但要记住,保存密钥会改变谁可以使用这份配置。

动手前先确认诊断

交互式和非交互式激活的差异就是全部诊断。如果在普通激活卡住时 nmcli --ask connection up 能成功,说明配置本身没问题,缺的是密钥来源。仅这一项对比就能让你免于重写一份可用的配置。

nmcli -f NAME,UUID,TYPE connection show
nmcli connection show "Office IPsec" | grep -i flags

去读标志位,而不是猜它。表示“问代理”的取值才是你要找的,具体的键名因 VPN 插件而异,因为键名就住在插件自己的数据字典里。FortiSSL 配置和 IPsec 配置未必使用同一套名字,所以要从你自己配置的输出出发。

还要确认该协议的插件包已经安装。缺插件时表现为未知的连接类型,或者一条完全不提密码的激活错误;在这种状态下追密钥等于把同一小时浪费两遍。查一次包,比花一下午改密钥文件划算。

把密钥挪进密钥文件

连接文件位于 /etc/NetworkManager/system-connections/ 下。默认不在那里保存密钥,这正是你刚读到的标志位的意义。把标志位改成零,就是告诉 NetworkManager 这个值随配置一起存着,而不是在激活时再询问。

[vpn]
password-flags=0

[vpn-secrets]
password=YOUR-VPN-PASSWORD

有两把密钥的配置,模式会重复:在 [vpn] 段里每把密钥一个标志位,值放在 [vpn-secrets] 里。IPsec 配置通常在用户凭据旁边还带一个预共享密钥,插件给它们起的名字和普通密码字段不同,所以要照着 vpn.data 的输出抄键名,而不是照搬用别的插件的博客文章。列名错一个,得到的配置能加载、却在认证时失败,看起来和密码错误一模一样。重新连接之前,先把自己的文件和同一插件下能用的配置对一遍。

含空格、引号或美元符号的值要加引号。不加引号又含 $ 的值,会按解析位置的不同被原样读取或被展开,由此产生的认证失败看起来就像密码错了。

接着修正文件的所有者和权限。这些密钥文件由特权服务读取,而其他用户能读的文件会被视为不可信,这正是改过的配置看似不起作用的常见原因。所有者 root,权限 600,没有例外。

先重新加载,再激活

文件是在连接加载时读取的,所以只改文件不够。重新加载配置,然后显式把连接拉起来。

sudo nmcli connection reload
sudo nmcli connection up "Office IPsec"

如果重新加载没有接住改动,完整重启服务可以;确实有这样的报告。其他链路要紧时优先用重新加载,因为重启服务会切断每一条受管连接,在远程主机上这可能在你要的隧道起来之前就结束你的会话。

名称有歧义时用 UUID。有多份客户配置的机器会堆积几乎重复的条目,激活错的那份会失败,看起来像凭据问题。

当保存的密钥不是问题时

FortiSSL 配置即使存对了凭据也可能失败,因为客户端从不信任网关的证书。那个设置在主页对话框里没有;它藏在 VPN 的高级选项后面,在那里填受信任证书的摘要。如果日志提的是证书而不是密码,你就在这个分支上,改 [vpn-secrets] 改多少都没用。

这里还有两项检查。确认配置不是从仍指向插件读不到的路径的文件导入的,并确认 生效的是当前配置,而不是过时的副本。两者都会造成激活失败,读起来像认证错误。

判断保存是否可以接受

保存下来的 PSK 和密码,机器上任何以 root 运行的东西都能读。在你掌控的机器上,为无界面服务做这个交换是合理的。在共享主机上就值得商量,因为配置里现在带着一份凭据,而它以前受桌面钥匙环保护。先问清那台主机上还有谁能拿到 root,再把改动落地。

如果策略禁止保存 VPN 密钥,不要为了让 cron 任务跑起来而削弱配置。改从带代理的会话运行连接,或者给自动化换一种机制。

最后,记下哪些配置带着密钥,免得有人没注意就复制到笔记本上。在密钥段上面写一行带日期和原因的注释就够了,将来能替某人省掉一次尴尬的复查。

相关文章