为什么 PPTP 和 L2TP/IPsec 会停在用户名输入之前?
没有出现用户名提示,说明 PPP 从未启动,故障出在传输、密钥交换或隧道建立上。重装之前先确认阶段顺序。
没有用户名提示是一份诊断礼物:PPP 尚未启动,因此账户、密码和域策略都还没有被查询。在 PPTP 或 L2TP/IPsec 连接中,客户端只有等隧道存在、服务器开始 PPP 会话之后才会索取凭据。在那之前可能失败的一切都属于传输、密钥交换或隧道建立,这比「VPN 坏了」要小得多。
缺少提示把故障缩小到三个阶段
记下最后一个肉眼可见成功的阶段,因为每个阶段的负责人和修法都不同。明明卡在两个阶段之前,却去猜账户设置,这就是一个下午消失的方式。
| Stage | What has to work | How a failure looks |
|---|---|---|
| Reach | UDP 500, 4500 and 1701 — or TCP 1723 plus GRE — through every firewall and NAT device | Client hangs, then reports no response |
| Key exchange | Preshared key or certificate, phase 1 and phase 2 proposals | Fast error, or a stall after the client says it is verifying |
| Tunnel | L2TP or PPTP control channel, then PPP starts | Connects, then closes with no prompt |
| User auth | PPP credentials and an address pool with room | Prompt 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。于是缺失的提示不再是谜,而变成一份你真正能照着做的清单的第二行。这份清单也是你交给网络团队的东西,否则他们会被要求去检查防火墙,而故障其实住在一个没有启动的守护进程里。