一条 L2TP/IPsec 连接内部有三样东西在认证,其中只有一样与拨号的人有关。IPsec 证明隧道两端,L2TP 控制连接可能用自己的密钥再次证明对端,随后 PPP 证明会话内的用户账号。任何阶段的失败在客户端对话框里都像是普通的登录错误,在服务器日志里却完全不同。按顺序排查各个阶段,并在第一个失败处停下,因为未经验证的阶段之下的每一层同样未经验证。

三个认证阶段,三种不同的身份

IPsec 用预共享密钥或证书证明端点归谁所有。这个身份属于机器或网关,从不属于键盘前的人。当对端在此阶段无法达成一致时,一个 L2TP 包都不会交换。

L2TP 控制连接可以增加第二次独立的口令-应答交换,由两端都必须持有的共享密钥驱动。

RFC 2661 把这种控制连接认证设为可选,这解释了为什么同一个错误在两台服务器上症状不同。从未配置隧道密钥的部署会完全跳过该阶段;只在单侧配置的部署会在 PPP 被提供之前就失败。随后 PPP 用 PAP、CHAP 或 MSCHAPv2 认证用户,并把名字交给可能是本地、chap-secrets 或 RADIUS 上的账户存储。此时密码错误仍会留下可用的隧道和失败的会话。

改配置之前先读停下来的位置

先用 ipsec --version 确认状态输出来自 strongSwan 还是 Libreswan。然后读服务器日志,而不是客户端对话框,因为服务器记录了是哪一阶段拒绝的。

通常一行就能定案:IKE 或提案的抱怨是第一层,控制连接的消息是第二层,PPP 方法或账户被拒是第三层。把那一行连同时间戳复制进工单。从客户端一侧猜测,会浪费你手上唯一的证据。

把密钥材料和密码排除在那次粘贴之外;阶段名称决定工作方向,而泄露的预共享密钥会让工单以更糟的后果重新打开。

第一阶段:IPsec 有安全关联吗?

在 strongSwan 上运行 ipsec statusall,或在 Libreswan 上运行 ipsec whack --status,寻找已建立且计数器非零的子关联。ip xfrm state 在两者上都显示内核视图。已安装的一对 SA 且计数器在增长,说明第一阶段已完成,可以继续。

完全没有关联指向对端地址、提案集合或预共享密钥,偶尔也指向一个重写 UDP 500 却丢弃 UDP 4500 的设备。建立后几秒就消失的关联,通常是两端的生存期不匹配,而不是凭据问题。在重新输入任何内容之前,先检查两侧是否列出相同的加密和哈希提案。若不相同,任何密钥都不会生效。

关联缺失时就停下。此时修改 PPP 选项什么都不会改变,还会把真正的故障藏起来,留给下一个人。

第二阶段:L2TP 控制连接认证了吗?

IPsec 起来后,观察 L2TP 守护进程是否出现进入已建立状态的控制连接,因为在此之前 PPP 无法开始。控制连接被拒,说明两端的隧道密钥不同,或一端要求的密钥另一端从不发送。客户端常只暴露一个标着 shared secret 的字段,而它通常属于 IPsec 而不是 L2TP。填上它不会配置隧道密钥,清空它也不会禁用它。

如果两侧都没有配置隧道密钥,就跳过这个阶段,把控制连接失败当作可达性问题处理。确认 UDP 1701 能到达守护进程,且两端对同一种封装达成一致。只为这两个条件之一写的防火墙规则,是连接只开一半的常见原因。

只有开始协商 PPP 的会话才真正走过了隧道阶段。

第三阶段:PPP 在拒绝账户吗?

PPP 失败从外部看不一样:隧道已建立,会话开始,守护进程记录认证方法失败或账户被拒。读那条消息里点名的方法。PAP 和 CHAP 失败的原因不同,而拒绝其中之一的服务器会拒绝只提供该方法的客户端。

在 Linux 服务器上检查守护进程传给 PPP 的选项文件,通常是 /etc/ppp/options.xl2tpd,并确认接受哪些方法、账户在哪里解析。在 RADIUS 中存在但本地密钥文件里没有的名字会干净地失败,看起来像密码错误。然后检查客户端提供的是服务器接受的方法,而不是服务器拒绝协商的更强方法。为修这一层去改预共享密钥,只会浪费一下午,什么都不会改变。

当会话终于起来时,地址分配、DNS 和路由仍未检查,而且每一项都以自己的方式悄然失败。在笔记里把三层分开记录:正确的密钥配错误的账户总是失败,修好一层永远修不好另一层。

相关文章