Windows 与 strongSwan:对齐 IKE 提议中的四项变换
当双方在密钥交换组上无法达成一致时,仅有共享加密算法并不够。先比较全部四项变换,再应用一条范围明确的配置文件策略。
双方都支持 AES,也都接受 SHA-256,可隧道就是起不来。提议是在没人比较过的那一项上失败的,通常是密钥交换组。本手册在改动任何内容之前先读取实际交换,应用一条范围明确的策略,并留下可恢复原有参数的回滚方案。
先读懂失败,再改动组
「策略匹配错误」只是摘要,不是诊断。它的意思是找不到双方都能接受的提议,却完全没说哪一项被拒绝。应把它当作排查的起点,而不是关于某个具体组的证据。
答案通常掌握在服务器一侧。合适级别的 strongSwan 日志会列出它从客户端收到的提议,以及它被配置为接受的提议,两份列表的差集就点明了失败的那一项。
不要假定客户端提供的就是旧论坛帖子里所说的内容。实际提供哪份列表由当前生效的配置文件及其已安装策略决定,而更新过的 Windows 版本可能提供与你正在照抄的截图不同的组合。
把两份列表都写下来。四个变换位置加一个组是一份很短的列表,逐行比对比任何实验都省时间。四个位置能一直看在眼里。日志文件不能。
比较每一项变换,而不是只盯一个熟悉的名称
IKE 提议是一组必须全部匹配的选项。加密保护协商过程,完整性或 PRF 对其进行认证,Diffie-Hellman 组则建立新的密钥材料。前两项匹配、第三项不同的提议,对双方依然不可接受。
这里容易混淆的两个 Windows 字段 属于不同阶段。DHGroup 作用于 IKE 密钥交换,而 PfsGroup 作用于保护流量的子关联。改动后者无法修复前者的失败。
各组实现之间的组名并不相同,这是另一处混淆来源。strongSwan 写作 modp2048 和 ecp256,Windows 则使用 Group14、ECP256 这类枚举名,所以比较之前必须先换算。留一份两列对照的笔记。这样下一次不匹配几秒钟就能归类。
| Transform | Windows parameter | strongSwan name | Failure it causes |
|---|---|---|---|
| Encryption | CipherTransformConstants | aes, aes256gcm and similar | No common proposal at all |
| Integrity or PRF | AuthenticationTransformConstants | sha256, sha512 and similar | Proposal rejected after encryption matches |
| Key-exchange group | DHGroup | modp2048, ecp256 | Exchange fails during key establishment |
| Child SA protection | PfsGroup | esp proposal groups | Tunnel negotiates, data association does not |
应用一条完整且范围明确的策略
原生 IKEv2 配置文件所支持的手段是按连接设置的 IPsec 策略,整体作为一个对象设置,而不是逐字段设置。先预览,再应用,并把原有参数留在变更记录里。
Set-VpnConnectionIPsecConfiguration -ConnectionName "Northwind IKEv2" -AuthenticationTransformConstants SHA256128 -CipherTransformConstants AES256 -EncryptionMethod AES256 -IntegrityCheckMethod SHA256 -DHGroup ECP256 -PfsGroup ECP256 -WhatIf
-WhatIf 开关只预览本地改动,不会应用任何内容。这很有用,同时也是常见的陷阱,因为预览只能证明这些参数对本地 cmdlet 而言语法上可接受。它并不会说明网关是否接受由此得到的提议。
顺便把作用域也对齐。位于所有用户存储中的连接需要对应的所有用户参数,而用同样的显示名去编辑单用户配置文件,改的是隧道并不使用的另一个对象。
然后在测试前把 strongSwan 一侧调到同一组。两端协同修改才是唯一会收敛的做法;只改一侧并反复重试,只会得到满是同样拒绝的日志。
把交换与密钥更新分开验证
连上只是一次观察,密钥更新是另一次。初始 IKE 协商使用一组参数,而承载流量的子关联之后可能用自己的策略重新协商。连上过一会儿又断的配置,通常属于第二种情况。
ipsec statusall | grep -A6 "Northwind"
Get-VpnConnection -Name "Northwind IKEv2" | Format-List *
第一条命令显示服务器对已建立关联的视角,包括子 SA 及其剩余生存期。第二条显示客户端配置文件现在持有的内容,这是确认所设策略就是生效策略的唯一办法。
在宣布成功之前先观察一次完整的密钥更新。也就是让连接保持足够久,使子关联被替换,然后确认流量仍在继续。多数策略不匹配就藏在这一步,因为初始协商可能用一组密钥更新并不接受的参数顺利通过。
回滚是回到原来那组参数,而不是放宽兜底。如果客户端只提供了薄弱的旧组,正确的做法是改进客户端与服务器的共同策略,而不是把那个组加到网关上,让今后每个对端都能向下协商到它。
记下四个参数、组、连接作用域以及密钥更新的结果。这份笔记很短,而它正是手册与「那次隧道终于起来了」的故事之间的区别。