Azure VPN 的 NAT 无法解决 VNet 地址重叠
两个 VNet 使用同一段私有地址时,不会因为存在 NAT 就能互通。先确认连接类型,再决定重新编号,或者让某个设备真正持有转换后的别名。
两个 VNet 都用 10.40.1.0/24,隧道虽然起来了,却什么也不通。再加一台 VPN 网关没有用,把路由度量调低也没有用,因为问题不在选路。两份工作负载共用同一个私有地址,每个数据包的目的地都含糊不清,回程路径也无从核验。在规划任何地址转换之前,先弄清楚你实际建的是哪种连接,因为正是这一个选择决定了 Azure 的 NAT 功能到底能不能用。
这个症状真正在说什么
当 VNet A 中的主机发往 10.40.1.10 时,路由表只能把它指向某个地方。如果 VNet B 里也有 10.40.1.10,这个地址就不是路径能区分的目的地,而是一个地址有两个主人。
人们通常加的第二个网关帮不上忙。它给你的是另一条隧道,不是另一个地址,重复的地址段在隧道里原样穿过。它还会让你需要保持一致的配置翻倍。它做不到的,是让一个地址代表两台主机。
改动 VPN 对端的公网地址同样没有用。那些地址 标识的是隧道的端点,而冲突发生在隧道内部承载的私有地址段里。
连接类型决定 NAT 能不能用
Azure VPN Gateway 确实具备 NAT 能力,文档中针对特定网关 SKU 上基于路由的 IPsec 跨站点连接做了说明。同一份文档排除了 VNet-to-VNet 和点到站点连接,所以这个功能并不是每种网关关系都会出现的勾选项。
| Connection type | NAT support | Overlap workaround |
|---|---|---|
| Site-to-Site (route-based IPsec, documented SKUs) | Supported with configured NAT rules | Translate the range in the rules |
VNet-to-VNet (Vnet2Vnet) | Not supported | Renumber, or redesign as a site-to-site connection |
| Point-to-site | Not supported | Choose client address pools that do not collide |
原生 VNet-to-VNet 本身也要求 VNet 与本地网络的地址段一开始就不重叠,这与上面的排除是一致的。同理,VNet 对等连接也不是解决重叠的办法。
还有一种受支持的替代做法,常被与原生类型混为一谈:把另一个 VNet 建模为本地网络,再以站点到站点的方式连起来。这是另一种资源和另一种设计,所以请把改名后的连接当作需要验证的变更,而不是一次改名。
重新编号,或者用真正持有别名的东西做转换
如果两个 VNet 都是你的,就把计划中的重新编号与长期转换成本放在一起比较。重新编号会牵动应用配置、DNS 记录、安全规则和每一条现有连接,但留下的网络之后读起来是正常的。一次只做一个子网,DNS 改动放在最后。改了一半的地址段比两种选择都糟,因为接下来读表的人会觉得两个前缀都算数。
在重新编号不现实的地方,采用有真实归属的转换设计。VNet A 里的调用方也许能把 VNet B 的 10.40.1.10 当作 10.140.1.10 访问,但这个别名需要一台负责转换的设备、一条通往它的路由,以及与之匹配的回程行为。只在 DNS 里加一条记录,不叫转换。
把两段地址在两个方向上都记下来:调用方拨的是什么、目的方看到的源是什么、哪一侧可以发起。Azure 自己的 NAT 规则为其 SNAT 映射包含了反向转换,所以不必手写对应的 DNAT 规则,但这份便利只到该功能支持的连接类型为止。
行不通的做法
用户定义路由或路由度量都无法凭空造出地址区分。两者作用的仍然是含糊的目的地,数据包只会到达路由表偏好的那个下一跳。
把重复的地址段以更具体前缀的形式加进路由表,只是把含糊挪了一步。它还往往会破坏另一个方向,因为回包这时有两个说得通的来源。
用双向流量验收设计
用每一侧新做一次被放行的操作来证明,而不是看隧道状态。IPsec 隧道连上只说明双方在加密上达成一致,完全没说目的地是否变得可区分。
然后跑被拒绝的路径:一个应当始终不可达的地址,以及一项策略应当拦下的服务。如果两者仍然成功,说明转换比设计本意更宽。
最后用能在日后解释这套配置的事实收尾:原始地址段、对外呈现的地址段、负责转换的设备,以及每一侧可以发起的方向。这些只要缺一项,下一位工程师接手的网络里就有两台主机同名,而没人记得为什么其中一台会应答。