没有用户名提示是一份诊断礼物:PPP 尚未启动,因此账户、密码和域策略都还没有被查询。在 PPTP 或 L2TP/IPsec 连接中,客户端只有等隧道存在、服务器开始 PPP 会话之后才会索取凭据。在那之前可能失败的一切都属于传输、密钥交换或隧道建立,这比「VPN 坏了」要小得多。

缺少提示把故障缩小到三个阶段

记下最后一个肉眼可见成功的阶段,因为每个阶段的负责人和修法都不同。明明卡在两个阶段之前,却去猜账户设置,这就是一个下午消失的方式。

StageWhat has to workHow a failure looks
ReachUDP 500, 4500 and 1701 — or TCP 1723 plus GRE — through every firewall and NAT deviceClient hangs, then reports no response
Key exchangePreshared key or certificate, phase 1 and phase 2 proposalsFast error, or a stall after the client says it is verifying
TunnelL2TP or PPTP control channel, then PPP startsConnects, then closes with no prompt
User authPPP credentials and an address pool with roomPrompt appears, then a rejection

没有出现提示就超时的客户端从未获得 IPsec 关联,所以故障在 IKE 或者在你的数据包到底能否到达网关。报告正在验证凭据然后掉线的客户端,走得比消息暗示的更远。提示之后被拒绝属于 PPP 认证,那应该写在账户文章里,而不是这篇。

第一阶段:防火墙悄悄丢弃的协议

PPTP 的控制通道需要 TCP 1723,数据路径需要 IP 协议 47,两者分开传输。许多网络放行 1723 却丢弃协议 47,于是得到一个能协商、却什么也传不了的隧道。做 NAT 的路由器还需要支持 GRE 的穿透,而只有 IPv6 的接入路径在任何配置下都无法承载 PPTP。

IPsec 之上的 L2TP 用端口 500 做 IKE、用端口 4500 做 NAT 穿越,然后把 L2TP 流量本身封进 1701,关联建立之后由 ESP 承载受保护的有效载荷。只放行两个控制端口而不放行 ESP,你得到的正是标题里的症状:看起来有进展,然后在任何凭据对话框之前客户端就死了。从手机热点测试是区分客户端问题和路径问题的廉价办法。

第二阶段:不是那个密钥的密钥,没有被提出的提议

不匹配的预共享密钥失败得又快又安静,常见版本是屏幕上看起来正确、却带着粘贴进来的换行或末尾空格的密钥。在 Linux 客户端上对话框未必是事实来源:NetworkManager 的 L2TP 插件把机密保存在 /etc/ipsec.d/ 下的文件里,而 /etc/ipsec.secrets 仍然包含的旧连接文件会被使用,而不是你刚输入的那个。把那个文件复制到安全位置,把它从包含路径中移除,然后手工重新输入密钥。

这个阶段的另一半是提议。两端必须就同一套阶段 1 算法达成一致——加密、完整性以及 Diffie-Hellman 组——并为阶段 2 匹配 ESP 变换,否则关联根本不会形成。只提供 3DES、SHA1 和 MODP1024 的网关会拒绝按更强算法配置的客户端,而它的日志会点名被拒绝的变换。如果你去读日志而不是再次重启服务,日志会点名这种不一致。与其从论坛帖子里复制算法串,不如问网关真正会协商哪些变换:指向它地址的 ike-scan 会返回它将要协商的变换。如果唯一的提供是你的策略不再允许的加密,那么修复该在网关,而不是降低客户端。

在 Windows 上,密钥和认证方法住在 VPN 配置文件里,不匹配会出现在凭据提示之前而不是之后。当接收端是 Windows Server 时,确认远程访问角色已安装、证书与客户端连接的名字相符,并且没有端口过滤比上面的协议更窄。

第三阶段:隧道存在,PPP 却从不启动

当 IKE 完成而提示始终不出现时,要看隧道守护进程而不是防火墙。L2TP 需要有东西在 UDP 1701 上监听——Linux 上是 xl2tpd 或 kl2tpd,Windows 上是远程访问服务——而已安装却停止的服务从客户端看和丢包一模一样。在重新打开你已经验证过的规则之前,先检查监听者。随后 PPP 必须协商,而第一次 LCP 交换通常就是无声失败落地的地方。

这个阶段有一个陷阱根本不是网络故障:Windows 同时只允许一个特定类型的 VPN 连接,所以第二次尝试会返回错误 937,「此类型的另一个连接正在使用中」。这是一条本地规则,绕过它的办法是换设备、换隧道类型,或者共享已经存在的那条连接。

按阶段顺序读日志,而不是靠猜

停止客户端,重新启动它,然后按组件写日志的顺序去读。也就是先读 IPsec 守护进程——strongSwan 或 Libreswan,ipsec --version 会告诉你哪一个——再读 L2TP 守护进程,最后读 pppd。故障前最后写日志的那个组件标记出要排查的阶段,因为在顺序里排在它之后的东西根本没有运行。

用新连接而不是已保存的会话去验证,因为从缓存重连的客户端可能跳过交换的某些部分,从而复现过时的结果。按这个顺序逐项确认可达性、密钥交换、隧道和 PPP。于是缺失的提示不再是谜,而变成一份你真正能照着做的清单的第二行。这份清单也是你交给网络团队的东西,否则他们会被要求去检查防火墙,而故障其实住在一个没有启动的守护进程里。

相关文章