第167篇:Hub & Spoke VPN 拓扑设计
关键词:Hub & Spoke、VPN拓扑、Route Target、星型拓扑、路由控制、RT策略、分支互通
一、引言
在典型的 L3VPN 应用中,全互联(Full-Mesh)拓扑允许所有站点之间直接互通。然而,许多企业的网络架构是星型拓扑——总部(Hub)需要与所有分支(Spoke)互通,但分支之间不需要也不应该直接通信。Hub & Spoke VPN 拓扑通过精细的 RT(Route Target)策略实现这种访问控制,同时保持网络的安全性和可扩展性。
二、核心概念
2.1 三种 VPN 拓扑对比
| 拓扑 | 互通模式 | RT 设计 | 适用场景 |
|---|---|---|---|
| 全互联(Full-Mesh) | 所有站点相互互通 | 共享 RT | 企业全网互通 |
| 星型(Hub & Spoke) | Spoke 仅与 Hub 互通 | Hub/Spoke 分离 RT | 总部-分支架构 |
| 部分互联 | 部分站点互通 | 多 RT 组合 | 复杂访问控制 |
2.2 Hub & Spoke RT 设计

2.3 RT 流向分析
| 方向 | Export RT | Import RT | 结果 |
|---|---|---|---|
| Hub → Spoke1 | RT-Hub | RT-Hub ✓ | Spoke1 学习 Hub 路由 |
| Spoke1 → Hub | RT-Spoke1 | RT-Spoke1 ✓ | Hub 学习 Spoke1 路由 |
| Spoke1 → Spoke2 | RT-Spoke1 | RT-Hub ✗ | Spoke2 不学习 Spoke1 路由 |
| Spoke2 → Spoke1 | RT-Spoke2 | RT-Hub ✗ | Spoke1 不学习 Spoke2 路由 |
2.4 Full Mesh 与 Hub & Spoke 对比
| 对比维度 | Full Mesh | Hub & Spoke |
|---|---|---|
| 互通模式 | 所有站点互相直接通信 | Spoke 仅与 Hub 通信,Spoke 间经过 Hub 中转 |
| 会话数 | N(N-1)/2 | N-1 |
| 延迟 | 最小(直连) | 增加一跳(Hub 中转) |
| 集中控制 | 无 | 有(所有流量经过 Hub) |
| 扩展性 | 差(N 大时路由表膨胀) | 好(线性扩展) |
| 安全策略 | 分布在各节点 | 集中在 Hub 统一部署 |
| 适用场景 | 数据中心互联 | 总部-分支架构 |
Full Mesh 适合所有站点需要高速直连的场景,如数据中心之间的存储同步。Hub & Spoke 适合需要集中管控的场景,如总部需要审计所有分支的流量。
2.5 Hub & Spoke 的实际路由流向
在 Hub & Spoke 中,Spoke1 想要访问 Spoke2 时,路由的实际走向如下:

关键点:虽然 Spoke1 的 VRF 路由表中没有 Spoke2 的路由条目,但如果采用"Spoke 也导入 Hub 导出路由"的模式,Spoke1 可以看到 Spoke2 的路由(因为 Hub 将从 Spoke2 学到的路由重新发布),只是下一跳指向 Hub。
三、技术细节
3.1 Hub & Spoke 路由传播

3.2 Hub & Spoke 的变种
| 变种 | 说明 | RT 设计 |
|---|---|---|
| 标准星型 | Spoke 间完全隔离 | Spoke Import 仅 RT-Hub |
| 部分互通 | 特定 Spoke 间互通 | Spoke 额外 Import 指定 Spoke 的 RT |
| 全互联回退 | Spoke 间也可互通 | Spoke Import 添加所有 Spoke 的 RT |
| 双向隔离 | Spoke 只能发不能收 Hub 路由 | Hub Import 含 Spoke RT,Spoke Import 不含 Hub RT |
3.3 路由聚合与 Hub & Spoke
当 Hub 侧有多个 CE 时,可以考虑在 Hub PE 上进行路由聚合:
| 场景 | 聚合方式 | 说明 |
|---|---|---|
| Hub 单 CE | 无需聚合 | CE 直接发布明细路由 |
| Hub 多 CE | Hub PE 聚合 | 汇总 Hub 侧路由,减少 MP-BGP 规模 |
| Spoke 聚合 | Spoke PE 聚合 | 汇总 Spoke 侧路由,减少向 Hub 发布的路由数 |
3.4 Hub 侧防火墙与 NAT 集成
在实际部署中,Hub 侧通常会串联防火墙来审计和控制所有 Spoke 流量:
# Hub PE 上配置 ACL,限制特定 Spoke 间的访问
[PE-Hub] acl number 3000
[PE-Hub-acl-number-3000] rule 5 deny ip source 10.2.0.0 0.0.255.255 destination 10.3.0.0 0.0.255.255
[PE-Hub-acl-number-3000] rule 10 permit ip
# 在 Hub VRF 的 CE 侧接口应用 ACL
[PE-Hub] interface GigabitEthernet 1/0/0
[PE-Hub-GigabitEthernet1/0/0] traffic-filter inbound acl 3000
同时,Hub 侧常部署 NAT 使 Spoke 能访问 Internet:
# Hub 侧 NAT 配置(Spoke私有地址 → 公网地址)
[PE-Hub] nat address-group 1
[PE-Hub-nat-address-group-1] section 0 203.0.113.1 203.0.113.10
[PE-Hub] acl number 2000
[PE-Hub-acl-number-2000] rule 5 permit source 10.0.0.0 0.0.255.255
[PE-Hub] interface GigabitEthernet 1/0/1
# 面向Internet的接口
[PE-Hub-GigabitEthernet1/0/1] nat outbound 2000 address-group 1
3.5 防环设计(SoO 属性)
Hub & Spoke 拓扑中可能出现环路风险:当 Hub 将从 Spoke1 学到的路由重新发布给 Spoke1 时,Spoke1 可能将流量发送回 Hub,形成环路。
解决方案:使用 SoO(Site of Origin)属性
# 在 MP-BGP 配置中为每个 Spoke 设置 SoO
[PE-Hub] bgp 65001
[PE-Hub-bgp-65001] ipv4-family vpn-instance HUB-VPN
[PE-Hub-bgp-65001-vpnv4] peer 10.1.2.1 as-number 65001
[PE-Hub-bgp-65001-vpnv4] peer 10.1.2.1 soo 100:spoke1
# Spoke1 的路由携带 SoO 100:spoke1
[PE-Hub-bgp-65001-vpnv4] peer 10.1.3.1 as-number 65001
[PE-Hub-bgp-65001-vpnv4] peer 10.1.3.1 soo 100:spoke2
# Spoke2 的路由携带 SoO 100:spoke2
SoO 属性会附加到每个 Spoke 发布的每条 VPNv4 路由上。当路由反射器将路由反射回原始 Spoke 时,Spoke 发现 SoO 匹配自己,便拒绝导入该路由,从而防止环路。
3.6 双 Hub 高可用设计
为避免 Hub 单点故障,可以采用双 Hub 部署:
# Spoke PE 上通过 Local Preference 控制 Hub 优先级
[PE-Spoke1] route-policy PREFER_HUB_A permit node 10
[PE-Spoke1-route-policy-PREFER_HUB_A-node10] if-match ip-address 10.1.1.0 24
[PE-Spoke1-route-policy-PREFER_HUB_A-node10] apply local-preference 200
# 来自 Hub-A 的路由优先级更高
[PE-Spoke1-route-policy-PREFER_HUB_A-node20] apply local-preference 100
# Hub-B 作为备用
[PE-Spoke1] bgp 65001
[PE-Spoke1-bgp-65001] ipv4-family vpn-instance SPOKE1-VPN
[PE-Spoke1-bgp-65001-vpnv4] peer 10.1.1.1 route-policy PREFER_HUB_A import
[PE-Spoke1-bgp-65001-vpnv4] peer 10.1.1.2 route-policy PREFER_HUB_A import
# Hub-A 和 Hub-B 同时作为 BGP 对等体
| 设计要点 | 说明 |
|---|---|
| 双 Hub 冗余 | Hub-A 和 Hub-B 互为备份,使用相同 VRF 配置 |
| Local Preference | Spoke 优先使用 Hub-A(Local Pref 200),备用 Hub-B(Local Pref 100) |
| BFD 快速检测 | Hub-A 故障时快速切换到 Hub-B(检测时间 < 1 秒) |
| 流量均衡 | 可通过不同 Spoke 绑定不同首选 Hub 实现负载均衡 |
3.7 Hub & Spoke 扩展性分析
| 问题 | 说明 | 解决方案 |
|---|---|---|
| Hub 带宽瓶颈 | 所有 Spoke 间流量经过 Hub | 链路扩容、关键业务补充 Full Mesh |
| Hub 单点故障 | Hub 故障导致全网中断 | 双 Hub 冗余部署 |
| 延迟增加 | Spoke-Spoke 多一跳中转 | 延迟敏感业务走独立通道 |
| 路由表膨胀 | Hub 存储所有 Spoke 路由 | 路由汇总、聚合 Spoke 前缀 |
| 防火墙性能瓶颈 | 所有流量经防火墙审计 | 防火墙集群、链路扩容 |
四、实战配置/案例分析
4.1 Hub & Spoke VPN 配置
# ========== 总部 Hub 配置 ==========
[PE-Hub] vpn-instance HUB-VPN
[PE-Hub-vpn-instance-HUB-VPN] rd 10.1.1.1:100
[PE-Hub-vpn-instance-HUB-VPN] route-target export 100:hub
[PE-Hub-vpn-instance-HUB-VPN] route-target import 100:hub
[PE-Hub-vpn-instance-HUB-VPN] route-target import 100:spoke1
[PE-Hub-vpn-instance-HUB-VPN] route-target import 100:spoke2
# Hub Import所有RT: 自己的hub + 所有spoke
# ========== 分支1 Spoke 配置 ==========
[PE-Spoke1] vpn-instance SPOKE1-VPN
[PE-Spoke1-vpn-instance-SPOKE1-VPN] rd 10.1.2.1:100
[PE-Spoke1-vpn-instance-SPOKE1-VPN] route-target export 100:spoke1
[PE-Spoke1-vpn-instance-SPOKE1-VPN] route-target import 100:hub
# Spoke1 Import仅hub RT: 只能学习Hub路由
# ========== 分支2 Spoke 配置 ==========
[PE-Spoke2] vpn-instance SPOKE2-VPN
[PE-Spoke2-vpn-instance-SPOKE2-VPN] rd 10.1.3.1:100
[PE-Spoke2-vpn-instance-SPOKE2-VPN] route-target export 100:spoke2
[PE-Spoke2-vpn-instance-SPOKE2-VPN] route-target import 100:hub
# Spoke2 Import仅hub RT: 只能学习Hub路由
# ========== MP-BGP 配置(各PE一致) ==========
[PE] bgp 65001
[PE-bgp-65001] address-family vpnv4
[PE-bgp-65001-vpnv4] import-route direct vpn-instance HUB-VPN
[PE-bgp-65001-vpnv4] import-route direct vpn-instance SPOKE1-VPN
[PE-bgp-65001-vpnv4] import-route direct vpn-instance SPOKE2-VPN
4.2 验证路由隔离
# Hub侧: 应看到Spoke1和Spoke2的路由
<PE-Hub> display ip routing-table vpn-instance HUB-VPN
Destination Protocol NextHop
10.2.1.0/24 OSPF 10.1.1.2 (Spoke1 CE)
10.3.1.0/24 OSPF 10.1.1.3 (Spoke2 CE)
192.168.1.0/24 OSPF 10.1.1.1 (Hub本地)
# Spoke1侧: 应仅看到Hub路由
<PE-Spoke1> display ip routing-table vpn-instance SPOKE1-VPN
Destination Protocol NextHop
192.168.1.0/24 BGP 10.1.1.1 (Hub路由)
10.2.1.0/24 OSPF 10.1.2.2 (Spoke1本地)
# 注意: 没有10.3.1.0/24 (Spoke2的路由)!
# Spoke2侧: 应仅看到Hub路由
<PE-Spoke2> display ip routing-table vpn-instance SPOKE2-VPN
Destination Protocol NextHop
192.168.1.0/24 BGP 10.1.1.1 (Hub路由)
10.3.1.0/24 OSPF 10.1.3.2 (Spoke2本地)
# 注意: 没有10.2.1.0/24 (Spoke1的路由)!
4.3 故障排查:Spoke 间意外互通
故障场景:Spoke1 可以 ping 通 Spoke2,但设计上是 Hub & Spoke 拓扑。
# Step 1: 检查 Spoke1 的 VRF 路由表
<PE-Spoke1> display ip routing-table vpn-instance SPOKE1-VPN
# 发现: 10.3.1.0/24 出现在路由表中!
Destination: 10.3.1.0/24, Protocol: BGP
# Step 2: 检查 MP-BGP VPNv4 路由
<PE-Spoke1> display bgp vpnv4 all routing-table
*> 10.1.3.1:100:10.3.1.0/24 10.1.3.1 0 100 i
Extended Community: RT 100:spoke2
# Step 3: 检查 Import RT
<PE-Spoke1> display vpn-instance SPOKE1-VPN
Route-target import/add: 100:hub
Route-target import/add: 100:spoke2
# 根因: 多配置了100:spoke2的Import RT!
# Step 4: 修正
[PE-Spoke1-vpn-instance-SPOKE1-VPN] undo route-target import 100:spoke2
# Step 5: 验证
<PE-Spoke1> display ip routing-table vpn-instance SPOKE1-VPN 10.3.1.0 24
# 路由已消失
五、总结
| 项目 | 要点 |
|---|---|
| Hub & Spoke 目的 | 分支仅与总部互通,分支间隔离 |
| RT 策略 | Hub Import 所有 RT,Spoke Import 仅 Hub 的 RT |
| 路由流向 | Spoke → Hub → Spoke(路由经过 Hub,但 Spoke 间不直接学习) |
| 安全价值 | 限制分支间直接通信,防止安全风险扩散 |
| 扩展设计 | 通过多 RT 组合实现部分互通等灵活策略 |
思考
- Hub & Spoke 拓扑中,Spoke1 的数据包要到达 Spoke2,需要经过 Hub 转发吗?如果 Hub 路由表中存在 Spoke2 的路由,数据包会被转发吗?
- 如果 Hub 侧有多个 PE 设备(多归属),如何确保所有 Hub PE 的 RT 配置一致?
- Hub & Spoke 拓扑是否可以与全互联 VPN 共存于同一 MPLS 骨干网上?RT 如何设计?
下篇预告:第168篇:跨域 L3VPN Option A/B/C 方案对比