Windows VPN 连接失败,搜索给出一个注册表值,于是连同重启一起改上。这套流程偶尔奏效,却从不解释任何东西。该设置只回答一个问题:服务器相对 NAT 设备处在哪一侧;在弄清哪个协议在哪一阶段失败之前,它是没有意义的。

这个值究竟在选择什么

AssumeUDPEncapsulationContextOnSendRule 决定 Windows 的 IPsec 实现是否尝试与位于 NAT 设备之后的对端建立关联。文档记载的默认值 0 不允许这种情况,1 在服务器位于 NAT 之后时允许,2 覆盖两端都被转换的情形。这些都是关于“谁在哪里”的拓扑陈述。

按顺序读下来,这些数字描述的是越来越多的转换,而不是越来越高的可靠性。在毫无转换的网络上设置 2,既不会让连接更快更稳,也修不好认证失败。Microsoft 的 L2TP/IPsec NAT 指南 记录了这一策略及其历史上的平台背景。要拿它对照你实际运行的 Windows 版本和角色,因为一份熬过多个版本的文档并不等于对每个当前版本的断言。

先对齐拓扑,再谈数字

画出路径并标出转换点:客户端是否在家庭路由器之后,服务器是否在负载均衡器或改写地址的防火墙之后,是否有一端处于你无法控制的运营商转换之后。只有画完这张图,才能判断该值是否适用、适用于哪一端。

“当前 Windows Server 版本就是把 NAT 穿越关掉出厂”这类说法太笼统,无法据此行动。真正重要的是你系统上的策略、它前面的拓扑,以及失败的那次交换,顺序就是这样。如果两端都是公网地址,这个设置就不是你的问题。此时应去看提议、证书或账户,别动注册表。

先确认失败发生在哪一阶段

L2TP/IPsec 至少会产生三种不同的失败:对端不可达、IPsec 保护建立不起来,以及 隧道已存在之后 PPP 用户认证被拒绝。被拒的账户改 NAT 策略修不好,提议不匹配重启也修不好。

Get-VpnConnection -Name "Corp L2TP" | Format-List Name, ServerAddress, TunnelType, EncryptionLevel
Get-WinEvent -LogName System -MaxEvents 40 | Where-Object Id -in 20227,20226,20274
netsh interface ipv4 show interfaces

无人应答的超时指向可达性或过滤,而不是策略。带提议消息的快速拒绝则指向算法。隧道起来之后的失败属于认证阶段,那是另一个责任方、另一种修法。

HTTPS 上的 SSTP 和原生 IKEv2 各有自己的日志和控制项。它们不会仅仅因为也跑在 Windows 上就变成 NAT 穿越问题。

改动要留退路

如果文档策略和实测拓扑都要求这么做,先记录旧值,通过受管配置而不是逐配置文件的脚本去改,并安排重启。在还承载其他工作负载的服务器上,这不是无害的编辑。

NAT 设备仍然要承载封装后的传输与回程流量。注册表值不会创建转发规则,不会对齐提议,也不验证身份,所以改完之后开始可用的连接,完全可能是因为别的原因才通的。用原拓扑重测原协议,然后写清哪一阶段失败、为什么指望这个值来解决它。正是这句话,把一条网上传言变成一份站得住脚的配置。

相关文章