iOS IKEv2 连接 strongSwan:未选择提案时如何修正列表
「未选择提案」意味着两个列表从未交集。把 SHA1 映射为 SHA-96、modp1024 映射为 group 2,并同时设置子提案。
iPhone 把隧道建立起来,网关却什么都没回,手机上只显示一个笼统的失败。strongSwan 的日志更具体:no proposal chosen。这条消息意味着两份可接受的加密套件列表从未重叠,因此交换在认证开始之前就结束了。这是一个匹配问题,解决办法是让两份列表产生交集。
网关在哪里声明它的策略
strongSwan 把策略写在配置里,行尾的感叹号决定这份策略该怎么读。带上标记时列表是穷尽的:只接受这些条目,别的都不行。不带标记时,同一行就变成一份偏好顺序,守护进程可能选中你并不想要的东西。在翻译任何内容之前,先问清楚部署的是哪种形式,因为两者对同一个客户端的行为并不相同。把那一行连同标记原样记下来,并据此测试。
提供更宽列表的客户端仍然可以连上被钉死的网关,只要两侧至少有一个组合相同。不可能发生的是在钉死集合之外进行协商。
这就是为什么从另一个 VPN 应用复制来的配置文件能在你的配置失败的地方正常工作:那个应用发的是另一份列表。
名称必须一致,而不是更好
有两个翻译陷阱会绊住把 strongSwan 的值搬到 iOS 的人。在 IKE 提案里写成 SHA1 的完整性算法以截短形式传输,iOS 把它叫做.SHA96。写成 modp1024 的 Diffie-Hellman 组是第 2 组,iOS 把它叫做.group2。换成 SHA-256 或第 14 组,无法与只接受旧组合的网关协商成功。客户端必须描述同一个算法,而不是更强的算法。
在NEVPNProtocolIKEv2里显式设置这些值。默认值可能比你要替换的配置文件更宽或更窄,差别只有在握手失败时才会显现。
子提案失败得更晚、也更安静
除了 IKE,还要配置子安全关联。当只有 IKE 参数对得上时,隧道会通过认证,然后不承载任何流量,这比直接被拒要安静得多。在同一步里设置子的加密、完整性、组和生存期。把客户端生存期保持在网关值或更低,因为坚持要更长的时间会因另一个原因产生同样的 no proposal chosen 消息。那里的不一致看起来与日志里的 IKE 不一致完全相同。
在配置里时顺便检查这个配置文件是用证书还是用共享密钥做认证。提案被拒和认证被拒出现在不同的行上,修错一个就要花掉一天。每次改动后都用全新连接测试,一次只动一个变量,因为缓存状态会掩盖究竟是哪个参数变了。
旧套件只在还需要时保留
用 1024 位组钉死 SHA-1 是过渡桥,不是终点。两者都已弃用,更新的客户端可能直接拒绝,这意味着在你这边毫无改动的情况下,配置文件会在下一台设备上失败。把钉死当作临时措施,并写进记录里。
如果 strongSwan 是你自己的,就添加一个现代提案,让两端向上协商,同时为旧设备保留旧条目。读取守护进程的状态输出,看看每条连接实际用了哪个套件。确认现代组合之后,再移除客户端的钉死。隧道能建立起来并不足以作为证据,因为它可能正是建立在你想要淘汰的套件上。strongSwan 的 IKEv2 文档描述了提案语法和 strict 标记。