跳到正文

Site-to-Site VPN 图:IPsec 隧道、BGP 路由与冗余

依次讲解 Site-to-Site IPsec VPN 的 IKEv2、每个连接两条隧道、BGP、冗余设计、MTU 与 MSS,以及监控。

· 创始人兼开发者

发布于

网络图。左侧是 AS 65010 中的本地数据中心,包含服务器 LAN 和边缘防火墙。两条隧道 169.254.10.0/30 和 169.254.10.4/30 通向 AS 64512 中 virtual private gateway 的两个端点,该网关再路由到两个可用区的私有子网。

你的数据中心通过一条 Site-to-Site VPN 访问 AWS 上的工作负载,这条 VPN 已经平稳运行了一年。某天夜里,AWS 在例行维护中替换了一个隧道端点,所有到 VPC 的连接随即中断。防火墙上只配置了隧道 1。隧道 2 从创建那天起就一直显示 DOWN。

在大多数图里,Site-to-Site VPN 只是一条线。实际上它是两条 IPsec 隧道、两个 BGP 会话和一份 MTU 预算,故障往往出在这条线隐藏的部分。本文涵盖 IPsec 的组成部分、一个 AWS 示例、静态路由与 BGP 的对比、冗余、MTU 与 MSS、监控,以及什么时候专线更合适。

Site-to-Site VPN 与远程访问 VPN

Site-to-Site VPN 连接两个网络:两端的网关持有隧道,其后的主机不需要任何 VPN 软件。远程访问 VPN 连接的是单个设备,每台笔记本都装客户端,用户需要登录。如果真正的需求是让人访问内部应用,那么零信任架构中的身份感知代理往往比这两者都更合适。

IPsec 的组成部分

IKEv2(RFC 7296)负责认证对端并协商密钥。ESP(RFC 4303)负责加密流量。

组成部分 作用 常见选择
IKE SA(阶段 1) 认证对端并保护 IKE;UDP 500,NAT 之后用 4500 AES-GCM、SHA-2、DH 组 14、19 或 20;8 小时
Child SA(阶段 2) 每个方向一个 ESP 安全关联 AES-GCM;1 小时,提前重新协商
ESP 加密每个数据包:IP 协议 50,使用 NAT 穿越时为 UDP 4500 隧道模式
Dead peer detection 存活检测,用来清除或重启无响应的隧道 30 到 40 秒
基于路由的隧道 路由和 BGP 都能使用的隧道接口 BGP 必需

IKEv2 通常用四条消息(IKE_SA_INIT 和 IKE_AUTH)建立 IKE SA 和第一个 Child SA。IKEv1 已在 2023 年被 RFC 9395 弃用。关于算法,RFC 8247 要求实现必须支持 DH 组 14,并推荐组 19;组 2、5、23 和 24 不应使用,组 22 禁止使用。

每个连接两条隧道:一个 AWS 示例

AWS Site-to-Site VPN 把你的客户网关设备连接到 AWS 一侧的网关。根据 AWS 隧道选项文档,每个连接都有两条隧道,各自有独立的公网 IP,终结在不同的 Availability Zone。

AWS 会因打补丁和硬件退役而替换隧道端点,每次只换一条隧道,所以只使用一条隧道的设备,每当该端点被替换时都可能失去连通。当某条隧道每天中断超过一小时,AWS Health 会每月发送一次通知。

每条隧道都有一个来自 169.254.0.0/16 的内部 /30。AWS 使用第一个可用地址,你的设备使用第二个,BGP 就在两者之间运行。除非把启动操作设为 start(仅 IKEv2),否则由你的设备发起 IKE。无论你的设备按什么顺序发送提议,AWS 都从其允许列表中的最小值开始评估,所以请在两侧都移除 IKEv1、SHA-1 以及 DH 组 2、5 和 22 到 24。

Virtual private gateway Transit gateway
连接对象 一个 VPC 多个 VPC、VPN 和 Direct Connect
每条隧道的带宽 1.25 Gbps 1.25 Gbps,使用 Large Bandwidth Tunnels 时为 5 Gbps
跨隧道 ECMP 不支持 支持,需配合 BGP
来自你设备的 BGP 路由数 100 1,000
额外费用 无 Transit gateway 费用

用代码定义隧道,可以让两条隧道保持一致。在 Terraform 中,隧道 1 如下:

resource "aws_vpn_connection" "dc" {
  vpn_gateway_id      = aws_vpn_gateway.main.id
  customer_gateway_id = aws_customer_gateway.dc.id
  type                = "ipsec.1"
  static_routes_only  = false

  tunnel1_inside_cidr                  = "169.254.10.0/30"
  tunnel1_ike_versions                 = ["ikev2"]
  tunnel1_phase1_encryption_algorithms = ["AES256-GCM-16"]
  tunnel1_phase1_integrity_algorithms  = ["SHA2-384"]
  tunnel1_phase1_dh_group_numbers      = [20]
  tunnel1_phase2_encryption_algorithms = ["AES256-GCM-16"]
  tunnel1_phase2_dh_group_numbers      = [20]
  tunnel1_dpd_timeout_seconds          = 30
  tunnel1_dpd_timeout_action           = "restart"
  tunnel1_startup_action               = "start"
  # tunnel2_*: the same values with 169.254.10.4/30
}

静态路由还是 BGP

静态路由在连接上列出你的前缀,故障切换则交给设备的健康检查。使用 BGP 时,每条隧道运行一个 eBGP 会话,隧道一旦断开,会话中断,其路由随即被撤销。只要设备支持,AWS 就推荐用 BGP,而 ECMP 必须用 BGP。有四条规则:

  1. 使用互不相同的私有 ASN。 AWS 一侧默认是 64512。给你的站点分配自己的私有 ASN:64512 到 65534,或 4200000000 到 4294967294(RFC 6996)。
  2. 通告汇总路由。 Virtual private gateway 最多接受来自你设备的 100 条路由,这是固定上限。
  3. 绝不要让 CIDR 重叠。 VPC 的本地路由优先于任何 VPN 路由,即使后者更具体。请在各站点之间统一规划地址空间,或在一侧做 NAT。
  4. 了解选路的决胜顺序。 对同一个前缀,virtual private gateway 优先选 Direct Connect,然后是静态 VPN 路由,再是 BGP 路由;接着是最短的 AS 路径,最后是最低的 MED。

没有 ECMP 时,AWS 每次只让回程流量走一条隧道,并用 MED 标记。AWS 路由优先级指南的建议是允许非对称路由,并保持 AS 路径等长。如果你的有状态防火墙无法应对,就在隧道 2 上做 AS 路径前置并降低其 local preference;不过 AWS 出口路径一旦变化,就可能中断流。AWS 的示例配置使用 10 秒的 keepalive 和 30 秒的 hold time,而不是 RFC 4271 建议的 90 秒。

冗余设计

两条隧道能覆盖 AWS 一侧的故障。它们仍然共用你的设备、你的 ISP 和你的站点。

设计 隧道数 能承受 不能承受
一台设备,一个 ISP 2 AWS 端点维护 设备或 ISP 故障
两台设备,一个 ISP 4 设备故障或打补丁 ISP 中断
两台设备,两个 ISP 4 设备或 ISP 故障 整个站点丢失
两个连接,Transit gateway ECMP 4 条或更多 同上,带宽更大 单个流超过一条隧道的上限

有两台设备时,每台都有自己的 VPN 连接,并且都通告相同的前缀。ECMP 通过哈希把每个流分配到一条隧道,所以四条隧道合计约 5 Gbps,但单个 TCP 连接仍然最高只有 1.25 Gbps,而且有状态防火墙可能需要源 NAT 来保证对称。站点很多时,transit gateway 会成为中心辐射型网络的中心。

MTU 与 MSS 钳制

每个经过隧道的数据包都要带上新的 IP 头和 ESP 开销。AWS 最多支持 1,446 字节的 MTU 和 1,406 字节的 TCP MSS,不支持 Path MTU Discovery,也不支持巨型帧。确切数值取决于你的算法,依据 AWS 客户网关最佳实践如下:

加密与完整性 NAT-T 隧道 MTU TCP MSS(IPv4)
AES-GCM-16 关 1446 1406
AES-GCM-16 开 1438 1398
AES-CBC,SHA-1 或 SHA2-256 关 1438 1398
AES-CBC,SHA-1 或 SHA2-256 开 1422 1382
AES-CBC,SHA2-512 开 1406 1366

设置隧道 MTU,并在两个方向上都钳制 TCP SYN 包的 MSS,因为双方各自通告自己的值。在 Linux 网关上:

ip link set dev vti1 mtu 1446
iptables -t mangle -A FORWARD -o vti1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1406
iptables -t mangle -A FORWARD -i vti1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1406

数值不对时的典型症状是:ping 和 SSH 正常,但文件复制会卡住。AWS 设备要求页面建议使用 1,399 字节,这个值也能工作,只是会浪费几个字节。

监控隧道

  • 隧道状态。 CloudWatch 为每条隧道发布 TunnelState;对 BGP 连接,1 表示会话已建立。任何一条隧道低于 1 时就告警。TunnelDataIn 和 TunnelDataOut 显示哪条隧道在承载流量。
  • 日志。 Site-to-Site VPN 日志会记录 IKE 状态、DPD 事件、BGP 状态和路由变化。
  • 你的一侧。 按隧道监控 BGP 状态和收到的前缀。会话已建立但前缀为零,仍然是故障。

隧道起不来时,按层逐项检查:IKE SA、IPsec SA、对 AWS 内部地址的 ping,然后是 BGP。

什么时候迁移到 Direct Connect

Site-to-Site VPN Direct Connect
路径 公共互联网,已加密 Direct Connect 站点上的私有线路
带宽 每条隧道 1.25 Gbps,使用 Large Bandwidth Tunnels 时为 5 Gbps 托管型 50 Mbps 到 25 Gbps,专用型 1 到 400 Gbps
SLA 每个连接 99.95% 采用最高弹性模型时最高 99.99%
加密 始终是 IPsec 默认无;支持的专用端口可用 MACsec,或在上层叠加 IPsec

当流量长期稳定在吉比特级、延迟很重要,或互联网出口费用高于一个端口的费用时,就该迁移。自 2026 年 9 月起,10 Gbps 和 100 Gbps 的专用连接可以使用包含同一档位内出站数据传输的统一费率。请把 VPN 留作备份:virtual private gateway 优先选择 Direct Connect 路由,所以只有线路故障时,流量才会走隧道。灾难恢复架构图讲的就是这类规划。

Site-to-Site VPN 图

网络图。左侧是 AS 65010 中的本地数据中心,包含服务器 LAN 和边缘防火墙。两条隧道 169.254.10.0/30 和 169.254.10.4/30 通向 AS 64512 中 virtual private gateway 的两个端点,该网关再路由到两个可用区的私有子网。

20 个组件 · 5 个连接

在 Archboard 中打开
图表内容
  • On-premises data center · 10.20.0.0/16 · AS 65010
  • Server LAN
  • ERP database
  • File server
  • Edge firewall (customer gateway)
  • VPC · eu-west-1
  • Virtual private gateway · AS 64512
  • Tunnel 1 endpoint
  • Tunnel 2 endpoint
  • Private subnet · eu-west-1a
  • App instance
  • Private subnet · eu-west-1b
  • to 10.50.0.0/16
  • Tunnel 1 · inside 169.254.10.0/30 · BGP .2 ↔ .1
  • Tunnel 2 · inside 169.254.10.4/30 · BGP .6 ↔ .5
  • 10.20.0.0/16
一个本地数据中心通过一条 Site-to-Site VPN 连接接入 AWS VPC:边缘防火墙向不同 Availability Zone 中的两个网关端点各建一条 IPsec 隧道,每条隧道都有自己的 BGP 会话,因此一个端点被替换时链路不会中断。

这张图的读法如下:

  • 左侧是数据中心:AS 65010 中的 10.20.0.0/16。LAN 把发往 VPC 的流量送到边缘防火墙,也就是客户网关设备。
  • 两条隧道通向 virtual private gateway 的两个端点,各有自己的内部 /30 和 BGP 会话。两条都处于启用状态,由 AWS 选择回程隧道。
  • 右侧是 VPC:10.50.0.0/16,在两个 Availability Zone 中有私有子网,并有一条传播到 10.20.0.0/16 的路由。
  • Markdown 块列出了两条隧道上必须一致的设置。
  • 底部的注释说明了两条隧道能覆盖什么(端点替换)和不能覆盖什么(一台防火墙,一个 ISP)。

把 Site-to-Site VPN 图画清楚

  • 给两端都加标签,写上 CIDR、ASN 和公网 IP。大多数 VPN 工单都从其中之一开始。
  • 画出两条隧道,标明各自的内部 /30 和 BGP 对端,并说明哪条是首选以及原因。
  • 把共用设置放进一个框里:IKE 版本、算法、DH 组、生存期、MTU 和 MSS。
  • 标出单点故障,例如只有一台设备或一个 ISP。
  • 不要画预共享密钥、ISP 内部细节和主机列表。

办公室一侧见网络拓扑图;子网和路由表见 AWS VPC 图。

在 Archboard 中构建

  1. 用 Google 或 GitHub 登录并创建一个图表。
  2. 为数据中心添加一个来自基础包的框架,用它的 CIDR 和 ASN 命名。在其中添加一个子网,里面放两个服务器节点和一个防火墙,全部来自网络包。
  3. 添加一个来自网络包的 VPC。在其中添加一个用于 virtual private gateway 的框架,里面放两个路由器节点,再添加两个私有子网节点,每个里面放一个来自云包的计算实例节点。
  4. 从防火墙到各端点画出隧道,两端都带箭头,并标上内部 /30 和 BGP 对端。添加从 LAN 到防火墙、从网关到子网的连线。
  5. 在两条隧道之间添加一个来自基础包的 Markdown 块,用来写共用设置,再添加文本注释。

如果 VPN 是用 Terraform 定义的,免费的 Terraform 转图表工具可以给你一个初稿;另见网络图。

这个示例共用 14 个图表节点,在 Free 套餐的限制之内。

常见问题

Site-to-Site VPN 图应该展示什么? 两个网络及其 CIDR、每个网关的公网 IP 和 ASN、每条隧道的内部地址、路由,以及双方必须一致的设置。

为什么 AWS Site-to-Site VPN 有两条隧道? 每个连接都有两条隧道,通向不同 Availability Zone 中的端点。AWS 每次只维护一条,所以两条都配置好之后,流量会转移而不是中断。

IPsec 上应该用静态路由还是 BGP? 只要设备支持,就用 BGP。它会自动撤销故障隧道的路由,而且 ECMP 需要它。静态路由适用于不支持 BGP 的设备。

AWS VPN 应该使用多大的 MTU 和 MSS? 使用 AES-GCM 且没有 NAT 穿越时,最大为 1,446 和 1,406 字节。CBC 加密和 NAT-T 需要使用 AWS 表中更小的值。

什么时候应该用 Direct Connect 而不是 VPN? 当流量长期稳定在吉比特级、延迟必须可预测,或者你需要最高 99.99% 的 SLA 时。请把 VPN 留作加密备份。

免费开始 — 1 个席位,无需信用卡。

相关文章

← 返回博客

一分钟打开画布

使用 Google 或 GitHub 登录。单席位免费,团队加入后再升级。