通过 Azure VPN 网关在两个分支之间路由流量
同一台 Azure VPN 网关上的两个站点到站点连接可以传递分支流量,但前提是两端都学到前缀,并且存在 LAN 回程路径。
两个分支可以在彼此之间没有直接隧道的情况下,通过 Azure VPN 网关交换流量。每个分支都向同一台网关建立站点到站点连接,网关则在两个连接之间传递学到的前缀。让这一切生效的不是第二条隧道,而是路由交换:分支 A 必须学到分支 B 的前缀,B 也必须学到 A 的前缀。请按顺序完成下面的检查,并在第一个失败的检查处停下,因为之后的每一步都依赖它。
先决条件:在配置任何东西之前
四个条件决定这套设计能否成立。网关必须基于路由并位于支持 BGP 的 SKU 上,两个连接都必须启用 BGP,分支的地址空间不得重叠,任何一侧都不得依赖 NAT 来隐藏真实前缀。
要有意识地规划 ASN。Azure 文档中的默认值是 65515,每个分支路由器都需要自己的私有 ASN,且不得与网关或另一分支冲突。不检查现有网关配置就沿用默认值,正是 AS 路径日后被拒绝的原因。
还要确认你并不期待 VNet 对等互连的行为。网关在你配置的两个连接之间交换路由;它不会让任意对等互连变得可传递。如果第三个网络需要到达两个分支,它需要自己的连接或自己的路由路径,而不是假设网关会把流量分发出去。在第一个变更窗口之前写下这条边界,因为这是日后新增站点时人们会回头查看的设计决策。
按这个顺序配置
每一步都有可观察的结果,所以在结果出现之前不要继续。
- 在虚拟网络网关上启用 BGP,并记录其 ASN 和对等地址。
- 为每个分支创建一个本地网络网关,填入该分支的真实地址空间、其 ASN 及其 BGP 对等地址。
- 创建每个站点到站点连接,并在连接本身上启用 BGP。
- 把分支路由器配置为与 Azure 分配的网关地址对等,而不是凭假设与网关的公共 IKE 端点对等。
第四步正是大多数尝试卡住的地方。Azure 报告的 BGP 对等地址才是分支路由器必须用作邻居的地址,它并不总是人们从隧道示意图里预期的那个地址。
宣告分支自己的前缀,例如从 A 宣告 10.10.0.0/16、从 B 宣告 10.20.0.0/16。不要宣告默认路由或宽泛聚合来覆盖缺失的具体网络;这个缺口日后会以静默黑洞的形式回来。
在两端验证路由交换
连接状态不是检查项。两个连接的 IPsec 都可能处于启用状态,而它们之间没有任何前缀通过。读取网关的 BGP 对等体和学到的路由,然后确认通往另一分支的路由以可用路径的形式出现。
| Check | Where | Stop if |
|---|---|---|
| BGP session established | Gateway BGP peers, branch router neighbour state | Session is Idle or Active on either side |
| Prefix learned | Gateway learned routes, branch BGP table | The other branch's prefix is absent |
| Prefix selected | Branch routing table, effective routes on the VNet | Prefix is known but a more specific route wins |
BGP 表中存在的前缀仍可能在与静态路由或更具体前缀的竞争中输掉转发决策。要检查被选中的路由,而不只是收到的路由。
在 LAN 一侧跟踪回程路径
这正是 Azure 里看起来正确、现场却失败的部分。分支 A 的主机只有在路由器是其默认网关,或者主机或其网关持有通往 B 前缀的路由时,才会把数据包发给 A 的 VPN 路由器。反方向也必须如此。
如果另有一台核心交换机是 LAN 的默认网关,它需要一条指向 VPN 路由器的、通往另一分支的路由。没有这条路由,请求能到达,回应却从互联网路径离开,用户看到的是连接打开后挂起。
不要指望网关子网上的网络安全组来修这个问题。那个子网有自己的要求,放在那里的 NSG 并不是分支侧策略受支持的替代品。过滤应当放在分支防火墙和负载本身,那里规则可以由其所有者审阅。把这些规则搬到子网 NSG 还会让它们避开将来排查下一次故障的团队。
放行操作,然后用一次被拒绝的测试来证明
学到的路由不等于许可。通过分支防火墙和端点策略放行你真正需要的源、目标和服务,其余保持拒绝。
从分支 A 的普通负载向分支 B 的真实服务做测试,确认回应,然后尝试一项应当继续被禁止的操作。VPN 设备自身产生的流量可能使用不同的源地址并跳过 LAN 路由阶段,所以从路由器上 ping 成功证明的东西比看上去要少。
最后写下四个事实:交换的前缀、使用的 ASN、每一侧的回程路径,以及放行该服务的策略。只要缺一个,配置就会一直工作到第一次变更,之后就没人能解释原因。