一个错误,三个秘密:到底是哪份 VPN 凭据失败?
客户端对每个阶段都显示同一个错误。在重置没人验证过的密码之前,先读关联、用户交换和方法。
“身份验证失败”可能指向服务器证书、机器预共享密钥或用户密码。到底指哪一个,取决于协议,因为每种协议定义的秘密集合不同。重置错的那个,错误会原封不动地留着。出路是在改动任何东西之前,先弄清协议要求几份证明。
两个方向相反的证据
隧道必须回答是否到达了正确的网关,以及另外一件事:用户是谁。网关证明是机器层面的:服务器证书、预共享密钥或静态公钥。用户证明是个人层面的:密码、令牌、客户端证书,或者什么都没有。这是两个相反的信任方向,消耗的是不同材料。
IKEv2 在 IKE_AUTH 内部完成网关证明;使用 EAP 时,随后在单独的交换中执行用户证明。IKEv2 规范把两者放在不同章节,这强烈提示:当一条消息同时覆盖两轮时该去哪里找。
读阶段,而不是读消息
无论哪个阶段失败,客户端都显示同一个错误字符串,所以字符串本身几乎不携带信息。携带信息的是每个阶段可以检查的状态:关联是否存在、用户交换是否开始、客户端有没有提供网关想要的方法。表格按这种方式给阶段分类,而不是按协议名。
| Stage that failed | Evidence you can inspect | What a password change cannot fix |
|---|---|---|
| The machine proof | no security association in the state list | a mismatched pre-shared key or an untrusted chain |
| The user proof | an association is up while PPP or EAP reports failure | an expired token, a locked account, a missing client key |
| The client's method support | the client offers no method the gateway accepts | a client without the required EAP or key material |
| The server's policy | the gateway rejects before any user exchange starts | a policy that requires a certificate the profile lacks |
只有第二行涉及用户可以重新输入的凭据。另外三行是配置事实,正是这种错位让这类报告常常以一次什么都没改变的密码重置收场。在动任何字段之前,先读与你的证据相符的那一行。
两个秘密的协议会亮出底牌
L2TP 跑在 IPsec 之上,让数量变得可见,因为两次校验发生在不同的进程里。IPsec 层必须先带着预共享密钥或证书起来,之后其中的 PPP 才会尝试用户登录。
机器秘密错误时,关联根本不会建立,用户凭据也就从未被尝试。机器秘密正确而用户秘密错误时,关联存在,隧道已经起来之后 PPP 拒绝登录。两件不同的事在屏幕上给出同一句消息。
sudo swanctl --list-sas
sudo ip xfrm state list
sudo journalctl -u xl2tpd -n 50 --no-pager空的关联列表会立刻排除用户层,所以在查密码之前先查它。关联已建立却反复出现 PPP 失败,指向另一个方向:用户层,或其中的认证协议。这两个结论都无法从客户端的错误文本里得到。
只靠密码到底依赖什么
只靠密码的访问对 L2TP、PPTP、SSTP 和带 EAP 的 IKEv2 来说很普通。WireGuard 根本没有这种选项,因为它的对端是密钥而不是用户。对 OpenVPN 来说,答案来自服务器对客户端证书的要求:同时要求证书和密码的网关,无论字段里输入什么,都会继续拒绝只有密码的客户端。
需要哪个组件同样由这个答案决定。IKEv2 下的密码登录需要会说 EAP 的客户端,而证书登录需要客户端的私钥和服务器的证书链。装错了,失败看起来就像凭据错误,尽管真正缺的是认证方法本身。
只改一处,然后重新测试
先确定三件事:跑的是哪个协议、它定义了几个秘密、其中哪些属于机器而不是用户。机器在第一阶段失败,人在第二阶段失败,把这两者混为一谈就是这个问题的全部。
然后只改一处,用同一台客户端重新测试。这种纪律能把一次令人困惑的失败,变成可以讲给下一个人听的修复,比一条谁都解释不了的可用连接更有用。