「NAT 会破坏 L2TP/IPsec」这个说法只对了一半,所以没什么用。地址转换本身很正常,NAT 穿透正是为了扛过它而存在,每天有数百万客户端从路由器后面连上来。真正坏掉的是某次交换中的某个阶段:IKE 完全收不到回应;只放行一种协议的策略把封装后的隧道丢掉;或者隧道空闲时转换映射到期。一旦知道自己在哪个阶段,修复通常只是一条规则或一个 keepalive,而不是重新设计 VPN。

迷思本身就是问错了问题

有用的问题不是「NAT 会不会破坏它」,而是「交换的哪一部分被转换,执行转换的设备对它做了什么」。L2TP/IPsec 是分层协议:IKE 负责协商,ESP 负责保护,而 L2TP 在这层保护里承载 PPP。地址转换对每一层的作用都不同;看协商阶段而不是看错误弹窗,就能区分不同的故障特征。

能正常上网的路由器只能证明带源端口转换的 TCP 可用。对 UDP 500、UDP 4500 或协议 50 一无所知,而这次部署恰恰依赖这三样。

阶段 1:IKE 得先收到回应

第一次交换走 UDP 500 发往响应方。如果没有任何回应,别的都无从谈起:预共享密钥、提议和凭据都没被读到。与其从客户端超时去猜,不如盯住请求和响应:

sudo tcpdump -n -i any 'udp port 500 or udp port 4500 or proto 50'
swanctl --list-sas

只有请求没有回应,通常意味着防火墙或上游运营商把包丢了,而不是服务器拒绝了它。带 notify 载荷、指名提议或证书问题的响应,说明包到了、协商卡在内容上,那是完全另一种修法。

两端都在转换后面时,发起方只要能到达响应方即可,所以大多数客户端侧部署从阶段 1 就能工作。服务器侧托管才是入站问题开始的地方,这也是两种情形绝不该混为一谈的原因。

阶段 2:封装改变了防火墙看到的东西

ESP 是 IP 协议,不是 TCP 或 UDP 端口,普通的端口地址转换没有端口字段可以改写。所以 NAT 穿透把受保护的载荷放进 UDP 4500:封装让转换设备拿到自己会转换的东西。一旦如此,只针对 UDP 500 写的防火墙规则就会 放行协商、放掉隧道,于是日志显示阶段 1 成功却没有任何流量,令人困惑。

IKE 交换本身在检测到 NAT 后也可能转到 UDP 4500,这让只放行 500 的人很意外。路径上两个端口都要双向放行,并记住有状态防火墙只会在看到流量时维持流表。

协议 50 在没有转换的路径上仍然重要,在中间设备被配置为放行它的路径上也一样。如果你用排除法诊断,请关掉假设,而不是成批加规则:放行 500、4500 和 ESP,确认隧道起来,再删掉发现多余的部分。没人能解释的规则,等它成为下一次故障的原因时也没人会删。把收窄过程连同它修好的阶段一起写进变更记录,让下一位工程师从你的证据出发,而不是从同一条经验法则出发。

阶段 3:映射到期,隧道死掉

转换设备会为转发的流保存状态,而状态是有寿命的。没人使用时 L2TP/IPsec 隧道几乎不传流量,空闲隧道可能活得比自己的映射还久,然后收不到回程流量。客户端仍以为连接正常,服务器什么也看不到,第一个症状通常是应用超时而不是 VPN 报错。

死对端检测和 NAT keepalive 就是为此存在,两端都得愿意发送。如果你的服务器在转换后面,Windows 侧的要求是一个有文档的注册表设置,让服务器对自己发出的包假定使用 UDP 封装;没有它,响应方发出的 ESP 无法被转换设备映射回去。这是服务器配置问题,不是客户端问题。

WAN 地址变化会从另一个方向造成同样结果:映射围绕新地址重建,旧的安全关联现在指向一个不存在的元组。重连行为属于客户端实现,所以「路由器重启后重连」在一个客户端上有效,在另一个上却要手动切换。

在运营商级 NAT 后面做托管是另一个问题

如果你想在家里托管 L2TP/IPsec 服务器并从外网访问,需要的是未被请求的入站可达性,而这不是 NAT 穿透能提供的。路由器前面是运营商级 NAT,意味着没有任何可转发的端口能让你可达,因为公网地址是共享的、映射只出不进。

任何 IPsec 直通勾选框都改变不了这一点,任何客户端配置也补偿不了。受支持的答案是真正可达的地址、托管的端点,或者每个参与者都主动向外连接的架构。UDP 封装规范解决的是已存在流的转换问题;它不会在运营商不提供入站路径的地方凭空造出一条。

所以别猜,去比较网络。把同一台设备和配置带到另一个允许的网络,看那里卡在哪一步。如果在别处能用,差异就在路径上,这能把排查范围缩小到上面三个阶段,而不是整套配置。

相关文章