你改了密码却毫无变化,因为故障从来不在 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 missingWhat it meansChange this
No IKE reply on 500 or 4500The path or the listener never answeredFirewall, NAT-T forwarding, server listener
IKE runs, no IPsec associationIdentity, key, or proposal mismatchProposal and PFS set, pre-shared key, local and remote ID
Association up, no L2TP control connectionInner signalling never reached xl2tpdUDP 1701, tunnel and session sections, NAT encapsulation
Control connection up, PPP auth refusedThe user or method was rejectedCredential format, allowed auth method, account policy
PPP auth accepted, no address assignedIPCP never completedAddress pool in xl2tpd.conf, ms-dns and ms-wins in options.xl2tpd
Address assigned, applications failThe inner path is wrongRoutes, 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。分离隧道的路由是另一个冒充者;子网掩码推错会让隧道健康而某个应用不可达。私有主机名又多一步:如果查询走本地解析器出去,名字在测任何路由之前就已经解析失败。

动凭据之前的检查清单

按顺序走清单,停在第一个失败项。每一步都很便宜,而每一步都排除一整类改动。

  1. 确认两端都有该关联,且按对端身份匹配,而不是按「已连接」标签。
  2. 确认 UDP 1701 到达 xl2tpd;没有呼叫的关联就是你的故障。
  3. 先读 PPP 的判定,若认证通过再读 IPCP 的结果,然后才假设密码错。
  4. 到这一步才按服务器期待的形式重输凭据,因为域前缀会改变账号。
  5. 若仍然失败,用对齐的时间戳两端同时抓包,逐阶段比对。

停在第二步意味着路径或封装问题,改密码再怎么改也不会动它。停在第三步意味着日志已经点出了要修的方法或地址池。无论如何,下一次改动必须是你讲得出理由的,你也就不再绕着从未参与的设置打转。

相关文章