位于 NAT 之后的 FortiGate 可以在其 WAN 接口上持有 10.0.0.2,而互联网将其呈现为 198.51.100.40,两个数字都是真实的。设备绑定的地址与它在 IKE 认证中发送的身份是两个独立的选择,写在不同字段里,面向不同对象。NAT 只在途中改写外层地址,不会把已认证的身份改写成对端期望的样子。这类部署中大多数第 1 阶段失败,都是把正确的值放进了错误的字段。

三个值,三个归属

先明确三个值以及各自的归属。local-gw 是 FortiGate 在外部接口上用作 IKE 源地址的地址,必须是设备真正持有的地址。公网端点是 NAT 设备的地址,归执行转换的一方所有。IKE 身份是供对端与自身配置比对的一串字符,完全不必是 IP 地址。

字段名过于相近,容易互相替代,这正是陷阱。localid 与 localid-type 描述的是身份识别;local-gw 描述的是本地绑定。

一个例子能让区别变得具体。在 FortiGate 上打开 config vpn ipsec phase1-interface,然后设置 set interface "wan1" 和 set local-gw 10.0.0.2 —— 这是设备持有的地址,正因如此 IKE 套接字才能成功绑定。若把 local-gw 留在 0.0.0.0,就会使用接口地址,通常等价但不够明确。不要把 local-gw 设为 198.51.100.40,因为设备并不持有该地址,套接字也无法绑定。让两个值在纸面上相等,并不构成配置。

第 1 步:选择对端会接受的身份

接下来是身份,这是另一个决策。set localid 取对端将要比较的值,而 set localid-type 告诉 FortiGate 如何解释它:地址、FQDN、用户 FQDN 或密钥 ID。使用 auto 时设备会自动推导,通常取出口接口地址,而这恰恰是 NAT 设备即将改掉的值。

正因如此,在这种拓扑中显式身份才重要。如果对端期望地址型身份,就把 localid-type address 和 localid 设为对端将看到的公网地址,然后确认对端接受该值作为身份,而不是作为路由目标。如果对端期望 FQDN,则使用 localid-type fqdn 以及配置时使用的名称。用 diagnose vpn ike gateway list 核实实际发送了什么,它显示网关状态和正在使用的标识符,而不是你打算输入的内容。不要假设身份类型选项接受任意非本地地址;先查阅该版本的文档语义。

第 2 步:把 UDP 500 和 4500 转发到设备

第三个值属于 NAT 设备,也是最容易被忽略的一项。公网端点必须把 UDP 500 和 UDP 4500 转发到 FortiGate,因为 NAT-T 探测以及随后的封装 ESP 都依赖这些端口到达。该设计假定一对一映射,而把单个公网地址按端口分给多个对端,是另一种拓扑,限制也不同。

用抓包而不是靠猜来确认转发:diagnose sniffer packet any "udp port 500 or udp port 4500" 4 会显示报文是否到达、回应是否发出。

Google Cloud VPN 把带 NAT-T 的一对一 NAT 记录为 NAT 之后对端所支持的方案;如果远端是 Cloud VPN 网关,就必须按这一限制来设计。一对多或按端口共享并不是同一种受支持拓扑,任何本地身份调优都改变不了这一点。如果远端是其他设备,其自身文档会规定它接受什么作为身份、是否容忍被转换的对端地址。改动本地字段之前先读那份文档,因为本地一侧无法协商对端未实现的规则。

第 3 步:检查第 1 阶段解决不了什么

NAT 穿越让隧道建立起来,身份一致决定对端是否接受,内部前缀路由决定实际能通什么。正确的本地 ID 无法补上缺失的静态路由或流量选择器。

所以要分层验证。get vpn ipsec tunnel details 显示隧道是否建立、协商了哪些选择器;已配置的远端子网与协商出的选择器不一致,就是披着第 2 阶段外衣的路由问题。execute vpn ike gateway clear 会强制重新协商,因此你测试的是当前配置,而不是上次改动之前建立的会话。然后向远端前缀中的主机发送流量,确认计数器在增长,因为隧道即使已建立但什么都不通,在检查之前与正常隧道毫无区别。

把三个值记在同一处:设备持有的本地地址、NAT 设备呈现的公网端点,以及对端期望的身份字符串。它们因不同原因、在不同时间发生变化。

NAT 设备重新编号并不是去动 FortiGate local-gw 的理由,身份变更也不是重新编号任何东西的理由。把两者混为一谈,就会在一次无关的维护窗口里重建一条本来正常的隧道。Cloud VPN 的 NAT 指南 是该侧受支持拓扑的参考。

真正能定论的检查既枯燥又快:在外部接口抓包,确认 UDP 500 和 4500 从对端到达,确认 IKE 交换中的身份与对端被配置期望的值一致,再确认协商出的选择器覆盖你关心的子网。第一项失败,怀疑 NAT 设备;第二项失败,问题在身份字段;第三项失败,说明 NAT 和身份从来都不是问题。

相关文章