L2TP NO_PROPOSAL_CHOSEN:实际失败的是哪个阶段?
通知只说明有一项提议被拒绝,并未说明是哪一项。请查阅后端日志确定阶段,再与网关运维方核对套件。
NO_PROPOSAL_CHOSEN 在任何 PPP 用户名被检查之前就会到达,这既是有用的事实,也是这条消息容易误导人的原因。它只报告某一方拒绝了提议,却不报告哪个参数不一致,也不说明拒绝发生在构建 IKE 关联时,还是发生在随后协商流量保护时。这两种可能性背后对应两种不同的修法,而人们最先去动的 PFS 复选框只与其中一种有关。
一条消息,两套提议
IKEv1 L2TP/IPsec 的安排包含两轮依次进行的协商。阶段 1 用加密算法、完整性算法和 Diffie-Hellman 组构建 IKE 安全关联。阶段 2 随后协商流量如何受到保护,而 PFS 要求属于第二轮对话。
| Phase | What is agreed | What a rejection here means |
|---|---|---|
| Phase 1 | Encryption, integrity, DH group for the IKE SA | No management tunnel exists, so nothing later can run |
| Phase 2 | ESP transforms plus the PFS group policy | The IKE SA negotiates, then child negotiation fails |
由于阶段是先后进行的,失败出现的位置就能告诉你该比对哪一份列表。这正是这条消息的全部诊断价值,值得在改动任何设置之前先提取出来。
为什么 PFS 复选框修不好阶段 1
关闭 PFS 改变的是阶段 2 的属性。如果双方从未在阶段 1 上达成一致,ESP 对话根本不会发生,因此该复选框对拒绝毫无影响,这也是为什么切换它只会得到同样的错误,只是时间戳不同。
反向的错误同样常见。IKE 关联成功并不能证明 ESP 提议可以接受,更不能证明阶段 2 的组是一致的。请把已建立的管理隧道只当作关于阶段 1 的证据。人们看到绿线便认为「隧道通了」,然后在一个小时里折腾错误的阶段,因为没有任何信息告诉他们第二轮协商根本没有开始。
先读日志,再选算法
从真正处理这条连接的后端上,收集紧挨着拒绝之前的那几行消息,并把它们与同一次尝试对应起来。少了这层对应,你读的是另一条连接的历史,并据此得出结论。
journalctl -b -u NetworkManager --since "10 min ago"
ipsec statusall # strongSwan
ipsec whack --status # Libreswan
从这些行里回答两个问题:阶段 1 的关联是否建立,以及哪一次交换失败了。这两个答案把排查范围缩小到一份属性列表。一条孤立的通知,周围没有任何上下文,做不到这一点,无论照搬论坛帖子里的提议多么诱人。从使用另一种后端的机器上复制一条可用字符串,通常只是把一个拒绝换成另一个稍晚出现的拒绝。
后端语法不通用
在比对任何内容之前,先记录 NetworkManager-l2tp 的版本和 IPsec 后端的版本。Libreswan 与 strongSwan 既不共用提议语法,也不共用完全相同的算法集合,因此在一边可用的字符串在另一边就是语法错误。已安装的后端还可能按策略拒绝 IKEv1,那样任何提议都不会被接受。
项目的 README 记录了这些后端差异,并把阶段 1 与阶段 2 的字段分开处理。请把它当作结构文档来读,而不是当作开启所有历史加密算法和一个弱组的邀请,因为只能靠这种方式才连得上的连接,并不是被要求搭建的那个连接。
先就套件达成一致,再逐段验证
向网关运维方确认哪些 IKE 与 ESP 套件受支持并获得批准,然后把这一答复与客户端实际发出的提议比对,而不是与它的配置文件比对。如果分歧具体出在阶段 2 的 PFS 上,就选定一个受支持的组,或明确批准的「不使用 PFS」策略。不要从错误名称去推断策略。
当唯一的交集需要组织已不再接受的密码学时,决定权在网关或协议迁移这一层。把客户端字符串一路放宽到能协商为止,等于在交付一个已知弱点的同时,还在旁边打上绿色对勾。
修正真正的差异之后,先确认 IPsec 建立,再排查 L2TP 与 PPP,并把之后出现的任何认证拒绝都归到下一阶段。然后在批准的测试流程中演练续期,因为第一次关联建立成功,说明不了它余下的寿命。