AWS 到 Azure 站点间 VPN:先写回程路由
跨云隧道接通并不说明任何问题,直到每个工作负载子网都有通往对端前缀的路由。按顺序执行计划,然后再测试服务。
隧道总会起来。通常如此,因为 IKE 只需要匹配的提议和可达的对端地址。随后失败的是回程路径:AWS 工作负载把数据包送进隧道,但 Azure 侧没有任何东西知道如何回应 10.10.0.0/16,或者 Azure 路由存在于工作负载子网并不使用的表中。在碰任何控制台之前先写出路由计划,隧道就会成为这项工作中最无趣的部分。
第 1 步:冻结地址规划
用具体数值工作。AWS 工作负载位于 10.10.0.0/16 内的 10.10.1.20,需要 TCP 443 访问 10.20.0.0/16 内 10.20.1.30 上的 Azure 服务。两个网段不得重叠,验收测试是这对服务,而不是隧道。
在做其他任何事之前把这四个事实写下来,因为后面每一步都要对照它们检查。
第 2 步:说清每个端点的网关归谁
AWS Site-to-Site VPN 可以终结在虚拟专用网关或中转网关上,这两者的路由归属不同。Azure 提供托管的 VPN Gateway,另外还有客户自行运维的基于 VM 的设备。记下你属于哪一种组合,因为每种组合的下一跳都不同。
对托管网关,不要照抄一条指向猜测的私有设备地址的路由。对设备,不要以为云端路由传播会配置来宾操作系统,它并不会。
这里搞错,就会得到一份看起来完整、却把数据包送往永不回应地址的计划。
第 3 步:写出每个工作负载真正使用的路由
下面每一个边界都是一次独立查找,其中一个边界里的路由并不等于数据包的路由。在隧道上线之前,用你自己的值把表填好。
| Boundary | Must reach | Owner to inspect |
|---|---|---|
| AWS workload subnet | 10.20.0.0/16 | the subnet's VPC route table |
| AWS transit gateway, if used | 10.20.0.0/16 via the VPN attachment | the table associated with that attachment |
| Azure workload subnet | 10.10.0.0/16 | effective routes on the NIC, whatever their source |
| VPN scope | both prefixes, agreed | static connection ranges or BGP advertisements |
在 AWS 中,工作负载子网的路由表即使 BGP 或隧道已健康,也仍要由你更新;路由概述把它视为连接的一部分。在 Azure 中,用户定义路由表关联的是子网,而不是虚拟网络,所以要查工作负载网卡上的有效路由,而不是 VNet 边栏。
托管的 Azure 网关可以通过网关传播学到远端前缀,而 UDR 可以推翻这个决定。有理由时才加 UDR,不要条件反射。若要添加,请指向网关为 VPN 路径发布的下一跳,而不是编造一个设备地址。然后重新读取网卡上的有效路由,因为决定实际是在那里做出的。
第 4 步:对齐范围
对 BGP,逐条前缀比较双方通告的内容与对方实际学到的内容。对静态路由,比较配置的远端网段与你在第 3 步写下的工作负载路由。
在加密算法上达成一致的 IKE 关系,不能证明任何一方学到了 10.10.0.0/16 或 10.20.0.0/16。两条隧道可以都在运行,而一方只通告了单个 /24 而不是你计划的 /16。要在路由表里检查前缀,而不是在隧道状态里。不匹配以后会表现为一个子网通、另一个子网从不回应。
第 5 步:从真实源测试服务
在 AWS 安全组和网络 ACL、Azure NSG,以及路径上任何设备过滤器中放行预期流量。然后从 10.10.1.20 向获批的服务地址和端口开一条连接,确认回应回到同一个源。
云安全组和 NSG 都是有状态的,所以被拒绝的回程数据包是路由症状,而不是你忘了写反向规则。
从任何网关 ping 都说明不了问题。发往网关地址的 ICMP 演练的是控制平面路径,不是工作负载需要的被转发的 TCP 服务。
回滚与记录
把路由归属记在隧道标识旁边,并保留变更前的路由表。如果变更需要撤除,先删除工作负载路由再拆隧道,这样就不会有子网还指向已不存在的下一跳。
这样,日后的子网迁移或 spoke 接入就有了一个明确的更新位置,而不是让一条运行中的隧道替它从未拥有过的路由背锅。