Windows在NAT后需启用NAT-T(RFC 3947)解决IPSec连接失败问题:设注册表AssumeUDPEncapsulationContextOnSendRule=2,开放UDP 4500端口,调整IKEv2重试、禁用PFS或MOBIKE,并验证SA中EncapMode为UDP Encapsulation且NATT为Yes。
在windows系统作为ipsec隧道端点且位于nat设备之后(如家用路由器、企业防火墙)时,标准ipsec(特别是ah或纯esp传输模式)通常无法正常建立连接。根本原因在于nat会修改ip包头或tcp/udp校验和,而ipsec的完整性校验机制会检测到篡改并直接丢弃数据包。解决的关键是启用nat穿越(nat-t),并配合正确的windows策略与网络配置。
确认并强制启用NAT-T(RFC 3947)
Windows默认在检测到NAT存在时自动协商NAT-T,但有时探测失败或被策略禁用。需手动确保开启:
- 打开注册表编辑器,定位到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgent
- 新建 DWORD 值 AssumeUDPEncapsulationContextOnSendRule,设为 2(强制所有IPSec SA使用UDP封装,端口500/4500)
- 重启 “IPsec Policy Agent” 服务,或运行 net stop policyagent && net start policyagent
调整IKEv2协商参数以适配常见NAT网关
部分老旧或简化型NAT设备(如某些光猫、OpenWrt默认配置)不严格遵循RFC,需放宽Windows端IKEv2行为:
- 在组策略中启用 计算机配置 → 管理模板 → 网络 → 网络连接 → Windows防火墙 → 高级安全Windows防火墙 → IP安全策略 → IKEv2 → 启用IKEv2重传超时和重试,并设为“已启用”,重试次数建议≥3
- 若对端是强软(StrongSwan)或Cisco ASA,建议在Windows端IPSec策略中禁用“要求PFS”(完美前向保密),避免因DH组不匹配导致协商中断
- 检查是否启用了“MOBIKE”(RFC 4555),Windows Server 2016+默认开启,但部分NAT环境会干扰地址更新,可临时禁用测试
防火墙与端口放行必须显式配置
NAT-T依赖UDP 500(IKE)和UDP 4500(NAT-T封装后的ESP)两个端口。Windows防火墙默认可能仅放行500,遗漏4500:
- 运行 netsh advfirewall firewall add rule name="IPSec NAT-T UDP 4500" dir=in action=allow protocol=UDP localport=4500
- 确保出站规则也允许UDP 4500(尤其在域策略统一管控环境中)
- 若使用第三方防火墙(如Symantec、McAfee),需单独检查其驱动层是否拦截UDP 4500 —— 此类拦截常无日志,表现为“IKE阶段1成功,阶段2超时”
验证与排错要点
不要只看“连接成功”,需确认实际流量走的是NAT-T路径:
- 用 netsh ipsec dynamic show state 查看SA状态,若“EncapMode”显示 Transport 且“NATT”列为 No,说明NAT-T未生效;应为 UDP Encapsulation + Yes
- 抓包时过滤 udp.port == 4500,正常建立后应有持续的UDP 4500心跳包(ISAKMP Notify或ESP-in-UDP)
- 若两端均为Windows且均在NAT后,需至少一端配置为“发起方”(Initiator),另一端设为“响应方”(Responder),避免双方等待对方首包而僵死
不复杂但容易忽略:NAT-T不是开关式功能,它依赖端到端的UDP连通性、校验和处理一致性以及IKE版本兼容性。一次调不通时,优先确认4500端口是否真正可达,再查协商参数。

















