连接在周四还正常,升级在周五执行,到了周一客户端就卡在“正在连接”上然后放弃。 同一台笔记本、同一台服务器、同一个账号、同一个预共享密钥。 配置文件里什么都没改,所以那些显而易见的嫌疑对象,密码和防火墙,只是在浪费你的时间。

改变的是你的机器愿意提供的转换列表。 Ubuntu 上使用的两套 IPsec 协议栈 strongSwan 和 Libreswan 都会剔除它们不再认为安全的算法,而排在前面的 NetworkManager 插件又有自己的一份列表,按另一套节奏变动。 一台被固定在 3DES、SHA1 和 1024 位 Diffie-Hellman 组上的服务器,最后可能听不到任何它愿意接受的东西。

升级究竟改了什么

IKEv1 提案由两层提供。 守护进程自带一套编译进去的默认提案集,而 L2TP 插件要么沿用它,要么提供自己的列表。 在 NetworkManager-l2tp 1.2.16 之前,插件是沿用的,所以你的提案就是已安装守护进程认为合理的那一套。 从 1.2.16 起,插件会发送一份参照 Windows 和 Apple 客户端制定的文档化列表,这份列表比旧的默认值更宽,但不再包含排在队列前面的每一种旧组合。

这种分裂解释了一种让人困惑的失败模式:同一个 Ubuntu 版本上的两台机器可能表现不同,因为一台装的是发行版软件包,另一台装的是向后移植版本,而在缺陷报告里两者的守护进程版本看起来完全一样。 在得出升级没有改变任何相关东西的结论之前,请检查插件版本,而不只是守护进程版本。

同一区域还有一个更小的陷阱。 两个守护进程拼写椭圆曲线 Diffie-Hellman 组的方式不同,一个写 ecp384,另一个写 ecp_384。 把错误的拼写粘贴到 Advanced 对话框中,守护进程就会以无法解析为由拒绝该设置,这在日志里表现为协商问题,而不是配置笔误。

动手修改之前先读失败信息

先确认你在跑哪个后端,因为答案同时决定语法和日志位置。

ipsec --version
nmcli connection show "Your VPN name" | grep -i ipsec

然后再读交换过程本身。 在 strongSwan 上,守护进程在当前版本会把日志写进 journal,在更老的版本则写进 /var/log/syslog;值得关注的部分是它发出的提案,而不是最后一行。 你要找的是“没有匹配的提案”这类措辞,那是算法问题;是认证失败,那指向密钥或账号;或者只是超时,那指向可达性。

这三种结果太经常被当成同一种症状。 守护进程日志为空时的超时,意味着数据包根本没到。 提案被拒绝,意味着数据包到了但被拒绝。 如果你的日志一片沉默,就把插件的调试级别提高一次尝试,然后再降回去,因为详细输出很快会填满 journal。

阶段 1 和阶段 2 是两场独立的赌局

IKEv1 要协商两次。 主模式用加密算法、完整性算法、Diffie-Hellman 组和认证方法建立 IKE 安全关联。 快速模式随后建立将要承载 L2TP 的 ESP 关联。 服务器完全可以接受前者而拒绝后者,所以一个只对了一半的配置文件会比你预想的更晚失败,看起来像是另一个缺陷。

Phase 1: 3des-sha1-modp1024!
Phase 2: 3des-sha1!

感叹号是 strongSwan 中表示严格条目的语法:只提供这一个组合,别的都不提供。 没有它,条目会加入一个兜底列表,这在对方是现代实现时没问题,在对方是只有一条硬编码策略的设备时则适得其反。 把上面这对当作形式示例,不要当成对今天要搭建的任何东西的建议。

改一个字段,然后重做测试

在较新的插件上,最快的第一次测试是把两个提案字段彻底清空再重新连接,因为随附的默认列表已经包含常见的 Windows 和 Apple 组合。 在较旧的插件上,清空它们会把控制权交还给守护进程,而它可能已经丢掉了你服务器坚持的算法,失败反而更严重。

如果清空没用,就按服务器文档设置那对严格组合,一次只改一个阶段。 改阶段 1,重新连接,并在碰阶段 2 之前读日志。 当某个组合终于生效时,把它记在服务器型号和插件版本旁边,因为默认值还会再变,而正是这条笔记让下一次升级变成五分钟的检查。

相关文章