是哪一层 VPN 失败了:IPsec、L2TP 控制还是 PPP 认证
找到最后一个成功的阶段,只修那一层:IPsec、L2TP 控制通道、PPP 认证或地址分配。
你改了密码却毫无变化,因为故障从来不在 PPP。L2TP/IPsec 对五种截然不同的交付只报同一个连接错误,而每种交付有各自的修法。倒着排查:找到最后一个成功的阶段,只改它之后的部分。下面的顺序也决定你先收集哪些证据。
按顺序回答四个问题
先强制一次新尝试,因为有些客户端会一直显示上一次的错误,直到配置文件断开并重连。然后回答:有没有 IPsec 安全关联、L2TP 控制连接和呼叫是否出现、PPP 是否走到认证判定、IPCP 是否给客户端分配了地址?第一个没有就是你该修的那一层。它之后的一切都未经检验,所以当关联从未建立时,被拒的用户名什么也证明不了。
比较之前先同步两端时钟。一次清掉 IPsec、却在 PPP 上失败的重连,在客户端只显示最后一条消息、而服务器日志还留着上一次尝试时,会看起来像同一个故障。要按时间戳读,别按最吵的那一行读。
如果你只有用户的截图,就依靠最省事的区分:预共享密钥错误和 xl2tpd 从未运行,在 Windows 对话框里会给出同样的文字,但前者要两端都改密钥,后者要在服务器上启动服务或放行防火墙。中间设备在传输模式 IPsec 把内层 1701 包起来之后无法丢弃它,所以别去找并不存在的路径过滤。
每一层究竟拥有什么
IPsec 保护两个对端之间的包;L2TP 在这条受保护路径里承载 PPP 会话,所以 RFC 3193 规定的是传输模式而不是自带隧道。客户端标签写着 L2TP,于是隧道和登录看起来像一个机制。其实不是:L2TP 控制连接在部署启用它的地方认证隧道端点,PPP 则按服务器策略用 CHAP、PAP 或 MS-CHAPv2 单独认证用户。
这个区分解释了人们老是混淆的两个秘密。预共享密钥认证的是 IPsec 对端。用户名和密码是给 PPP 认人的。在靠证书认证的配置里重打 Windows 共享密钥,对失败的那一层毫无作用;改 PPP 密码也补不出缺失的受保护通道。同样的克制也适用于身份校验:不要为了拿到隧道就关掉对端身份或证书校验,因为那样连上的是路径,而不是对端。
认证也不是 PPP 的终点。用户被接受之后,IPCP 还要协商客户端地址以及服务器愿意下发的 DNS 与 WINS 选项。客户端可以过了 CHAP 或 MS-CHAPv2 却仍然没有地址,这属于 PPP 内部的故障,不是路由问题。没有 IPsec 的纯 L2TP 依然有效且不受保护,所以连得上从不证明流量受保护;要看服务器强制什么,而不是客户端的标签。
从第一个缺失的阶段判断
按第一个缺失的条目从左往右读表。右边那一列才是当下唯一值得做的事;它左边的一切都已被证明,重复测试只会白白烧掉故障窗口而不增加信息。
| First thing missing | What it means | Change this |
|---|---|---|
| No IKE reply on 500 or 4500 | The path or the listener never answered | Firewall, NAT-T forwarding, server listener |
| IKE runs, no IPsec association | Identity, key, or proposal mismatch | Proposal and PFS set, pre-shared key, local and remote ID |
| Association up, no L2TP control connection | Inner signalling never reached xl2tpd | UDP 1701, tunnel and session sections, NAT encapsulation |
| Control connection up, PPP auth refused | The user or method was rejected | Credential format, allowed auth method, account policy |
| PPP auth accepted, no address assigned | IPCP never completed | Address pool in xl2tpd.conf, ms-dns and ms-wins in options.xl2tpd |
| Address assigned, applications fail | The inner path is wrong | Routes, DNS, MTU or MSS, server forwarding |
有三行值得警惕。1701 那一行是 NAT 后的 Windows 客户端常落下的地方:关联完成,然后什么也不来,原因是封装而不是密码错。IPCP 那一行最容易被误读成路由问题,因为 Windows 把缺地址包成 720 错误,托盘图标只说连接失败;那个故障在认证之后、路由之前。最后一行根本不算 IPsec 故障,尽管图标显示已断开。
分层排查的命令
在跑 strongSwan 的 Linux 服务器上,swanctl --list-sas 连同对端身份列出已建立的关联,ipsec statusall 覆盖较老的 strongSwan 与 libreswan 主机。再往下,ip xfrm state 显示内核的真实关联,ss -lunp | grep 1701 证明 xl2tpd 绑在哪里。把 xl2tpd -D 放到前台就能看到控制连接和呼叫到来;在 /etc/ppp/options.xl2tpd 里打开 pppd 调试就能看到提议的方法和应答。
日志显示认证成功之后,下一个问题是 IPCP 有没有完成。检查 /etc/xl2tpd/xl2tpd.conf 的 [lns default] 段里 ip range 是否还有空闲地址,以及客户端期待时 /etc/ppp/options.xl2tpd 是否真的带着 ms-dns 和 ms-wins。地址池耗尽和缺少 DNS 选项在线上表现不同:前者让客户端没有地址并报 720,后者给了地址却没有解析器,于是域名失败而直连 IP 的 ping 正常。两者都不能靠重输密码解决。
在客户端,NetworkManager 的 L2TP 插件会把 pppd 的对话写进日志,所以 journalctl -u NetworkManager -b 通常能把隧道起来了、认证被拒和根本没有隧道分开。在 Windows 上,Get-VpnConnection 会报告配置文件真实的认证设置,事件查看器 Application 下的 RasClient 事件会点名失败的组件。对话框太含糊时,打开 netsh ras set tracing * enable。
抓包需要一个注意。传输模式 IPsec 下内层 UDP 1701 是加密的,所以外网口抓包只会看到 ESP,或在 NAT-T 下看到 UDP 4500,完全看不到 L2TP。抓包里没有 1701 是正常的,不是端口被封的证据;要看 ESP 或 4500 的计数是否在动。
NAT、MTU 与路由:栈在哪里骗你
NAT 在任何认证之前就先破坏了假设。ESP 是独立的 IP 协议,做地址转换的设备会直接丢掉它,除非对端做封装;UDP 4500 正是为此存在。在自身位于家用路由器或云 NAT 网关之后的 Windows 服务器上,IPsec 阶段会以 789 错误失败,直到在 PolicyAgent 键下把 AssumeUDPEncapsulationContextOnSendRule 设为 2 并重启机器,而这个故障看起来和端口关闭无法区分。NAT 后的客户端反而简单:服务器有公网地址时,UDP 4500 上的 NAT-T 会带着它们走,那个值不参与其中。
PPP 起来以后,带黑洞的 MTU 会伪装成死隧道:小包能过,TLS 握手或页面加载卡住,而客户端还可能显示已连接。在怪服务器之前,先调低接口 MTU 或在网关上压 MSS。分离隧道的路由是另一个冒充者;子网掩码推错会让隧道健康而某个应用不可达。私有主机名又多一步:如果查询走本地解析器出去,名字在测任何路由之前就已经解析失败。
动凭据之前的检查清单
按顺序走清单,停在第一个失败项。每一步都很便宜,而每一步都排除一整类改动。
- 确认两端都有该关联,且按对端身份匹配,而不是按「已连接」标签。
- 确认 UDP 1701 到达 xl2tpd;没有呼叫的关联就是你的故障。
- 先读 PPP 的判定,若认证通过再读 IPCP 的结果,然后才假设密码错。
- 到这一步才按服务器期待的形式重输凭据,因为域前缀会改变账号。
- 若仍然失败,用对齐的时间戳两端同时抓包,逐阶段比对。
停在第二步意味着路径或封装问题,改密码再怎么改也不会动它。停在第三步意味着日志已经点出了要修的方法或地址池。无论如何,下一次改动必须是你讲得出理由的,你也就不再绕着从未参与的设置打转。