可使用开源的 strongSwan 软件,快速地与阿里云建立 IPsec-VPN 连接(IPsec 连接绑定转发路由器),实现云上 VPC 与本地 IDC 的网络互通。
场景说明
某公司在华东1(杭州)地域创建了 VPC,现需通过 IPsec-VPN 将本地 IDC 与云上 VPC 网络互通。与直接绑定 VPN 网关不同,本场景中 IPsec 连接绑定转发路由器——通过云企业网(CEN)的转发路由器统一管理云上网络,后续可灵活扩展更多 VPC 或跨地域互通。
本场景采用 BGP 动态路由,IDC 侧仅有一个公网出口 IP,与阿里云建立双隧道模式的 IPsec 连接。两条隧道会自动形成 ECMP(等价多路径),流量在双隧道间负载均衡,一条隧道中断时自动收敛到另一条。
资源规划
云上:VPC 网段 10.0.0.0/16,地域为华东1(杭州)
交换机 1:可用区 H,网段 10.0.0.0/24
交换机 2:可用区 J,网段 10.0.2.0/24
ECS 实例:位于交换机中,IP 地址 10.0.0.1(用于验证连通性)
CEN 实例:用于承载转发路由器
转发路由器:在华东1(杭州)地域创建,TR 地址段 10.10.10.0/24(不可与 VPC / IDC / BGP网段冲突)
云下:本地 IDC 网段 172.16.0.0/16
strongSwan 设备:私网 IP 172.16.0.1
公网出口 IP:XX.XX.3.3
加密算法:IKEv2 / AES-128 / SHA-1 / DH Group 2 / SA生存周期86400秒。隧道两端请务必配置相同的加密参数。
路由方式:使用 BGP 动态路由。BGP 网段规划如下(隧道网段需为 169.254.0.0/16 内的 /30,两条隧道不能相同)。
资源
隧道
隧道网段
BGP IP 地址
BGP AS 号
IPsec 连接(云端)
隧道 1
169.254.10.0/30
169.254.10.1
65535
隧道 2
169.254.20.0/30
169.254.20.1
65535
本地网关设备(IDC)
隧道 1
169.254.10.0/30
169.254.10.2
65530
隧道 2
169.254.20.0/30
169.254.20.2
65530
两条隧道的本端自治系统号必须相同;对端(IDC)AS 号也建议两条隧道相同。
前提条件
云上 VPC 网段、云下 IDC 网段、BGP 隧道网段两两之间不能冲突。
已创建 VPC,并在两个不同可用区各创建了一个交换机(交换机所在可用区需在转发路由器支持的可用区列表中)。VPC 内至少有一台 ECS 实例用于验证连通性。
已创建 CEN 和 TR,并且:
已在本地 IDC 部署一台 Linux 服务器(本文以 CentOS Stream 9 为例),具备 1 个公网出口,后续将在该服务器上安装 strongSwan(IPsec 隧道)与 FRRouting(BGP)作为本地网关。
第一步:创建用户网关
用户网关用于将本地网关设备的公网 IP 和 BGP AS 号 记录到阿里云。本场景中 IDC 只有 1 个公网出口,因此只需创建 1 个用户网关。
前往 VPN网关页面, 在左侧导航栏单击用户网关。
在顶部菜单栏选择华东1(杭州)地域。
单击创建用户网关,配置:
名称:输入用户网关名称,例如 cgw-idc。
IP地址:输入本地 IDC 的公网出口 IP(XX.XX.3.3)。
自治系统号:输入本地 IDC 的 BGP AS 号,本文为 65530。
重要:BGP 场景下用户网关必须填写自治系统号。如果已创建的用户网关未指定 ASN,需删除后重新创建。
第二步:创建 IPsec 连接
在 VPN 网关控制台左侧导航栏,单击IPsec连接。
单击绑定云企业网,配置 IPsec 连接基本参数:
IPsec连接名称:填写资源名称,例如 ipsec-demo。
地域:选择华东1(杭州)。
网关类型:选择公网。
绑定云企业网:选择本账号绑定
绑定资源:选择转发路由器。
云企业网实例ID:选择前提条件中已经创建的云企业网CEN实例。
路由模式:选择目的路由模式(BGP 动态路由推荐使用目的路由模式)。
立即生效:选择是,配置完成后立即进行协商,阿里云侧会主动向对端发起协商。
开启 BGP 并配置本端自治系统号:
在双隧道配置区域,打开启用BGP开关(勾选开启)。
本端自治系统号:输入云端 IPsec 连接的 BGP AS 号,本文为 65535。两条隧道的本端自治系统号必须相同。
高级配置(包含自动关联路由表、配置转发路由等配置):全部勾选,包括自动发布路由、自动关联至转发路由器的默认路由表、自动传播系统路由至转发路由器的默认路由表。
配置隧道参数:
隧道 1(主):
用户网关:选择第一步创建的用户网关。
预共享密钥:两端约定好的密码,用于建立隧道时互相验证身份。建议使用复杂密码,云上云下填写必须完全一致。
加密配置:保持默认值即可。如需手动指定算法,可展开修改。
重要请将云上和云下的加密配置保持一致,包括IKE版本、协商模式,以及各阶段的加密算法、认证算法、DH分组,SA生存周期。
展开 BGP配置:
隧道网段:输入 169.254.10.0/30。
本端BGP地址:输入 169.254.10.1。
隧道 2(备):
用户网关:选择与隧道 1 相同的用户网关(本场景 IDC 只有 1 个公网出口)。
预共享密钥:本文使用与隧道 1 相同的密钥。
加密配置:本文使用与隧道 1 相同的加密配置。
展开 BGP配置:
隧道网段:输入 169.254.20.0/30(不能与隧道 1 相同)。
本端BGP地址:输入 169.254.20.1。
单击确定。创建成功后系统提示是否去发布路由,先单击取消。
IPsec 连接资源初始化约需 5 分钟(状态为准备中),此时还无法配置路由。您可以先记录云上公网IP地址,后续再前往第三步配置路由。
记录云上 2 条隧道的公网 IP,后续配置 strongSwan 时需使用:
回到IPsec连接列表页,找到刚创建的 IPsec 连接。在网关IP列,记录IPsec地址1:和IPsec地址2:。本文以 XX.XX.1.1 和 XX.XX.2.2 为例。您也可以单击实例ID进入连接详情页,查看每条隧道的隧道网段、本端BGP地址、对端BGP地址及 BGP 状态。
第三步:确认TR和VPC路由
BGP 动态路由方式下,无需在 TR 路由表中手动添加去往 IDC 网段的静态路由。本地网关设备通过 BGP 宣告 IDC 网段后,路由会自动传播到 IPsec 连接 BGP 路由表,再通过 TR 的路由学习功能传播到 TR 路由表,最后通过TR的路由同步功能传播到VPC路由表。
前往云企业网控制台,单击云企业网实例 ID。
在转发路由器页签中,找到华东1(杭州)的转发路由器,单击其 ID 进入详情页。
切换到转发路由器路由表页签,在路由条目页签中确认:待本地网关设备的 BGP 配置完成后(见第四步),此处会自动出现去往 IDC 网段(172.16.0.0/16)的路由条目,路由来源为 IPsec 连接。
如果创建 IPsec 连接时未保持默认勾选自动传播系统路由至转发路由器的默认路由表、自动关联至转发路由器的默认路由表,则需手动为 IPsec 连接创建关联转发关系并开启路由学习,否则 TR 无法学到 IDC 路由、流量不通。
前往专有网络VPC控制台,在 VPC 的路由表页面确认是否已有去往 IDC 网段(172.16.0.0/16)、下一跳为转发路由器的路由。待本地网关设备的 BGP 配置完成后(见第四步),此处会自动出现去往 IDC 网段(172.16.0.0/16)的路由条目。
若未开启路由同步功能,本地网关配置完成后,此处不会生成去往 IDC 的路由条目。您可以在TR上开启对VPC的路由同步,也可直接在VPC路由表添加路由条目。
第四步:配置 strongSwan 设备
以下内容包含的第三方产品信息仅供参考。阿里云对第三方产品的性能、可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺。
下面以 CentOS Stream 9 64位操作系统为例配置 strongSwan,其他操作系统请参考 strongSwan 官方文档。
1. 放通防火墙策略
在 strongSwan 设备上放通 ESP 协议(IP 协议号 50)、UDP 500 端口和 UDP 4500 端口,允许云上的 2 个 IPsec 地址访问。
以 iptables 为例,请根据实际使用的防火墙工具调整命令:
iptables -I INPUT -s XX.XX.1.1,XX.XX.2.2 -p esp -j ACCEPT
iptables -I INPUT -s XX.XX.1.1,XX.XX.2.2 -p udp --dport 500 -j ACCEPT
iptables -I INPUT -s XX.XX.1.1,XX.XX.2.2 -p udp --dport 4500 -j ACCEPT2. 开启路由转发
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sudo sysctl -p3. 安装 strongSwan
sudo dnf install epel-release -y
sudo dnf install strongswan -y4. 创建 XFRM 隧道接口和 updown 脚本
由于双隧道场景下需要区分每条隧道的流量,需要创建 XFRM 虚拟接口来避免内核路由策略冲突。BGP 动态路由方式下,还需要在 XFRM 接口上配置 BGP 隧道地址。
# 创建 XFRM 隧道接口(分别对应隧道 1 和隧道 2;单公网出口时底层接口均为 eth0)
sudo ip link add ipsec0 type xfrm dev eth0 if_id 42
sudo ip link add ipsec1 type xfrm dev eth0 if_id 43
sudo ip link set ipsec0 up
sudo ip link set ipsec1 up
# 在 XFRM 接口上配置本端 BGP 隧道地址
sudo ip address add 169.254.10.2/30 dev ipsec0
sudo ip address add 169.254.20.2/30 dev ipsec1XFRM 接口和地址为临时配置,设备重启后需重新添加。可将上述命令写入开机启动脚本(例如
/etc/rc.d/rc.local)。使用 XFRM 接口需要 strongSwan ≥ 5.8、Linux 内核 ≥ 4.19、iproute2 ≥ 5.1,且内核支持 xfrm 模块(
lsmod | grep xfrm)。
5. 配置 strongSwan
备份原始配置文件:
mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak新建配置文件:
vi /etc/strongswan/swanctl/swanctl.conf添加并保存以下配置。请将示例中的 IP 地址和密钥替换为您的实际值:
# strongSwan 双隧道 IPsec-VPN 配置 # 适用于:阿里云转发路由器绑定的 IPsec 连接 + 本地公网单出口 + BGP 动态路由 # # 只有带"请修改"标记的参数需要根据实际环境修改,其余参数保持默认即可。 # 使用 XFRM 接口(if_id)区分两条隧道的流量;路由由 BGP 动态学习。 connections { # === 隧道1 === tunnel1 { version = 2 dpd_delay = 10s rekey_time = 86400s proposals = aes-sha1-modp1024 encap = yes local_addrs = 172.16.0.1 # strongSwan 本机网卡 IP(请修改:NAT 环境填私网 IP;网卡直接绑公网 IP 则填公网 IP) local { auth = psk id = XX.XX.3.3 # 本地侧公网出口 IP(请修改) } remote_addrs = XX.XX.1.1 # 阿里云侧隧道 1 的公网 IP(请修改) remote { auth = psk id = XX.XX.1.1 # 阿里云侧隧道 1 的公网 IP,与上方 remote_addrs 一致(请修改) } children { tunnel1-child { local_ts = 0.0.0.0/0 remote_ts = 0.0.0.0/0 mode = tunnel esp_proposals = aes-sha1-modp1024 dpd_action = restart start_action = start close_action = start if_id_in = 42 # 对应 ipsec0 接口 if_id_out = 42 } } if_id_in = 42 if_id_out = 42 } # === 隧道2 === tunnel2 { version = 2 dpd_delay = 10s rekey_time = 86400s proposals = aes-sha1-modp1024 encap = yes local_addrs = 172.16.0.1 # strongSwan 本机网卡 IP,与隧道 1 相同(请修改) local { auth = psk id = XX.XX.3.3 # 本地侧公网出口 IP,与隧道 1 相同(请修改) } remote_addrs = XX.XX.2.2 # 阿里云侧隧道 2 的公网 IP(请修改) remote { auth = psk id = XX.XX.2.2 # 阿里云侧隧道 2 的公网 IP,与上方 remote_addrs 一致(请修改) } children { tunnel2-child { local_ts = 0.0.0.0/0 remote_ts = 0.0.0.0/0 mode = tunnel esp_proposals = aes-sha1-modp1024 dpd_action = restart start_action = start close_action = start if_id_in = 43 # 对应 ipsec1 接口 if_id_out = 43 } } if_id_in = 43 if_id_out = 43 } } secrets { ike-tunnel1 { id-1 = XX.XX.3.3 # 本地侧公网出口 IP(请修改) id-2 = XX.XX.1.1 # 阿里云侧隧道 1 的公网 IP(请修改) secret = "your-psk-here" # 隧道 1 的预共享密钥,需与阿里云侧一致(请修改) } ike-tunnel2 { id-1 = XX.XX.3.3 # 本地侧公网出口 IP(请修改) id-2 = XX.XX.2.2 # 阿里云侧隧道 2 的公网 IP(请修改) secret = "your-psk-here" # 隧道 2 的预共享密钥,需与阿里云侧一致(请修改) } }重要if_id_in和if_id_out将每条隧道绑定到对应的 XFRM 接口(ipsec0 / ipsec1),确保两条隧道的流量互不干扰。local_ts和remote_ts设置为0.0.0.0/0,由 BGP 学习到的路由决定哪些流量进入隧道。目的路由模式下,云上侧的流量选择器也为0.0.0.0/0。
6. 启动并确认隧道状态
sudo systemctl enable strongswan
sudo systemctl restart strongswan
sudo swanctl --load-all
sudo swanctl --list-sas如果两条隧道均显示 ESTABLISHED 且 CHILD_SA 为 INSTALLED 状态,则表示 strongSwan 设备和阿里云之间已成功建立 IPsec-VPN 连接。
# 期望输出示例(已省略部分内容)
tunnel1: #1, ESTABLISHED, IKEv2
tunnel1-child: #1, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
tunnel2: #2, ESTABLISHED, IKEv2
tunnel2-child: #2, reqid 2, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_967. 配置 BGP 动态路由(FRRouting)
IPsec 隧道建立后,网络还无法互通,需要在本地网关设备上配置 BGP,与阿里云侧建立 BGP 邻居,自动宣告本地网段并学习云上网段。
说明:strongSwan/FRR 设备重启后,需要重新添加 XFRM 接口、BGP 隧道地址及 BGP 配置。
安装 FRRouting:
sudo dnf install frr -y开启 bgpd 守护进程:
编辑
/etc/frr/daemons,将bgpd=no改为bgpd=yes,保存后启动 FRR:sudo sed -i 's/^bgpd=no/bgpd=yes/' /etc/frr/daemons sudo systemctl enable frr sudo systemctl restart frr添加 BGP 配置:
进入 vtysh 配置界面,添加如下配置。执行时请将地址替换为您的实际值:
169.254.10.1、169.254.20.1替换为阿里云侧两条隧道的本端 BGP 地址(即本地设备的对端 BGP 邻居)。65535替换为阿里云 IPsec 连接的本端自治系统号。65530替换为本地 IDC 的 BGP AS 号。172.16.0.0/24替换为您需要宣告给云上的本地 IDC 网段。
sudo vtyshconfigure terminal route-map allow-all permit 1 exit router bgp 65530 bgp router-id 169.254.10.2 neighbor 169.254.10.1 remote-as 65535 neighbor 169.254.10.1 timers 10 30 neighbor 169.254.20.1 remote-as 65535 neighbor 169.254.20.1 timers 10 30 address-family ipv4 unicast network 172.16.0.0/24 neighbor 169.254.10.1 soft-reconfiguration inbound neighbor 169.254.10.1 route-map allow-all in neighbor 169.254.10.1 route-map allow-all out neighbor 169.254.20.1 soft-reconfiguration inbound neighbor 169.254.20.1 route-map allow-all in neighbor 169.254.20.1 route-map allow-all out maximum-paths 32 exit-address-family exit exit write memory确认 BGP 邻居和路由:
show ip bgp summary show ip bgpshow ip bgp summary中两个邻居(169.254.10.1、169.254.20.1)的State/PfxRcd应显示为已接收的前缀数量(而非 Active/Idle),表示 BGP 邻居已建立。show ip bgp中应能看到通过 BGP 学习到的云上 VPC 网段(如 10.0.0.0/24、10.0.2.0/24),且每个网段有两条等价路径(分别经隧道 1 和隧道 2),形成 ECMP。
# show ip bgp summary 期望输出示例(已省略部分内容) Neighbor V AS ... State/PfxRcd 169.254.10.1 4 65535 ... 2 169.254.20.1 4 65535 ... 2 # show ip bgp 期望输出示例 *> 10.0.0.0/24 169.254.10.1 ... 65535 i *= 169.254.20.1 ... 65535 i *> 10.0.2.0/24 169.254.10.1 ... 65535 i *= 169.254.20.1 ... 65535 i确认内核已安装 ECMP 路由:
ip route show 10.0.0.0/24 # 期望:一条路由带两个 nexthop,分别经 ipsec0 和 ipsec1
验证测试
验证连通性
先确保 ECS 的安全组规则已放通 ICMP 协议,再从本地 IDC 内的客户端 ping 云上 ECS:
ping 10.0.0.1若能收到回复报文,说明云上 VPC 和云下 IDC 之间已成功互通。
说明:若从 strongSwan 设备自身发起 ping 时,请指定 IDC 内网 IP 为源地址(例如
ping -I 172.16.0.1 10.0.0.1),避免内核选用 BGP 隧道地址(169.254.x.x)作为源地址导致回程不通。先确保strongSwan或内网服务器已放通 ICMP 协议,再登录 VPC 中的 ECS 实例(10.0.0.1),ping strongSwan 设备的内网地址:
ping 172.16.0.1若能收到回复报文,说明反向连通也正常。
验证高可用
绑定转发路由器且使用 BGP 的 IPsec 连接默认以 ECMP(等价多路径)方式同时使用两条隧道,流量在双隧道间负载均衡。当一条隧道中断时,BGP 会自动撤销该隧道的路由,流量收敛到另一条隧道,无需手动切换。
保持 ECS 持续 ping IDC 服务器:
ping 172.16.0.1 -c 10000中断其中一条隧道:在阿里云控制台修改 IPsec 连接隧道 1 的预共享密钥(使两端密钥不一致),该隧道将中断,其 BGP 邻居随之断开。
观察 ping 结果:流量在短暂中断后重新恢复通信,说明流量已自动收敛到隧道 2。
恢复隧道:将隧道 1 的预共享密钥改回正确值,隧道与 BGP 邻居恢复后,流量将重新在两条隧道间负载均衡。
故障排查
常见问题与解决方案:
问题现象 | 可能原因 | 解决方案 |
控制台隧道状态显示协商失败 | 网络不通 | 检查 strongSwan 设备能否连通阿里云的 IPsec 地址;确认本地 IDC 的防火墙已放通 UDP 500/4500 端口。 |
预共享密钥不匹配 | 核对两端的预共享密钥是否完全一致(包括大小写和特殊字符)。 | |
IKE 参数不一致 | 检查 IKE 版本、加密算法、认证算法、DH 分组等参数是否在两端匹配。 | |
隧道已建立但 BGP 邻居无法建立 | BGP 配置错误 | 检查用户网关是否已填写正确的自治系统号;检查 IPsec 连接的隧道网段、本端 BGP 地址是否与本地设备匹配;检查本地 FRR 中 remote-as(对端应为云端 ASN 65535)、邻居地址(云端隧道 BGP 地址)是否正确;确认 XFRM 接口已配置对端 BGP 隧道地址(169.254.x.2/30)。 |
BGP 已建立但无法 ping 通 | 路由未生效 | 检查 TR 路由表是否已通过路由学习学到 IDC 网段;检查 VPC 路由表中是否已有去往 IDC 网段、下一跳为转发路由器的路由(若未自动生成需手动添加);确认 IPsec 连接已与 TR 路由表建立关联转发并开启路由学习/路由同步。 |
安全组限制 | 检查 ECS 安全组是否允许来自 IDC 网段(172.16.0.0/16)的 ICMP 流量。 | |
本地防火墙限制 | 检查 IDC 防火墙是否允许来自 VPC 网段(10.0.0.0/16)的流量。 | |
strongSwan 侧源地址选择错误,从设备自身 ping 时未指定源 | 从 strongSwan 设备自身测试时使用 |
如果仍未解决,详见:故障排查。