全部产品
Search
文档中心

VPN网关:建立VPC到本地数据中心的连接(双隧道模式)

更新时间:Jan 07, 2026

使用 VPN 网关配置 IPsec-VPN 连接(双隧道模式)连接 VPC 和本地数据中心,避免单隧道故障导致业务中断,保障连接高可用。

工作原理

某公司在阿里云新加坡地域创建 VPC(主网段为 192.168.0.0/16),且在新加坡部署本地数据中心(网段为 172.16.0.0/16)。因业务发展,本地数据中心需要访问 VPC 中的资源。公司可使用 VPN 网关建立 VPC 与本地数据中心的 IPsec 连接(双隧道模式)。

  • 双隧道模式,即包含一条主隧道和一条备隧道。系统自动检测主隧道的连通性,当检测到主隧道中断后,VPN 网关会自动将流量切换到备隧道。待主隧道恢复后,流量将自动切回。

  • VPN 网关创建时会分配两个公网 IP 地址,分别用于建立主隧道和备隧道。每条隧道独立完成 IKE 协商与密钥交换,并承载数据流量。

以本地网关设备部署 strongSwan 软件为例。其他本地网关设备配置示例
image

适用范围

  • 本地数据中心的网关设备:

    • 网关设备必须配置公网 IP 地址。建议配置 2 个公网 IP 地址或本地数据中心部署 2 个网关设备,每个网关设备均配置 1 个公网 IP 地址。

    • 网关设备必须支持 IKEv1 或 IKEv2 协议。

  • VPC:以下地域和可用区支持双隧道模式的 IPsec-VPN 连接。

    单击查看支持的地域和可用区

    支持调用DescribeVpnGatewayAvailableZones查询指定地域下支持的可用区信息。如果表中的可用区的信息与查询到的信息不符,以调用DescribeVpnGatewayAvailableZones查询到的信息为准。

    地域

    可用区

    华东1(杭州)

    K、J、I、H、G

    华东2(上海)

    L、M、N、A、B、E、F、G

    华东5(南京-本地地域)

    A

    华南1(深圳)

    A(已停止售卖)、C、E、D、F

    华南2(河源)

    A、B

    华南3(广州)

    A、B

    华北1(青岛)

    B、C

    华北2(北京)

    F、E、H、G、A、C、J、I、L、K

    华北3(张家口)

    A、B、C

    华北5(呼和浩特)

    A、B

    华北6(乌兰察布)

    A、B、C

    西南1(成都)

    A、B

    中国香港

    B、C、D

    新加坡

    A、B、C

    泰国(曼谷)

    A

    日本(东京)

    A、B、C

    韩国(首尔)

    A

    菲律宾(马尼拉)

    A

    印度尼西亚(雅加达)

    A、B、C

    马来西亚(吉隆坡)

    A、B

    英国(伦敦)

    A、B

    德国(法兰克福)

    A、B、C

    美国(硅谷)

    A、B

    美国(弗吉尼亚)

    A、B

    墨西哥

    A

    沙特(利雅得)- 合作伙伴运营

    A、B

    阿联酋(迪拜)

    A

  • 本地数据中心的网段与 VPC 的网段没有重叠。

操作步骤

第一步:创建 VPN 网关

  1. 前往VPN网关管理控制台

    • 实例名称资源组:可结合使用,统一标识云资源。

    • 地域:选择 VPC 所在地域。本文为新加坡

    • 网关类型:选择普通型

    • 网络类型:选择公网

    • 隧道:选择双隧道

    • 专有网络:选择计划与本地数据中心连通的 VPC。

    • 虚拟交换机1虚拟交换机2:选择 VPC 下不同可用区的 2 个交换机。

    • 带宽峰值:使用默认值。

    • 流量:选择按流量计费。

    • 开启IPsec-VPN关闭SSL-VPN

    • 购买时长:使用默认值。

    • 服务关联角色:确保创建服务关联角色AliyunServiceRoleForVpn,VPN 网关使用此角色来访问其他云产品中的资源。

    image

  2. 返回VPN网关页面,VPN网关实例的初始状态为准备中,约1~5分钟左右会转换为正常。系统会为 VPN 网关分配两个公网 IP 地址,分别用于建立主隧道和备隧道。本示例中,系统分配的两个公网 IP 地址为:IPsec地址1:120.XX.XX.152(IPsec地址1 - 主隧道)120.XX.XX.0(IPsec地址2 - 备隧道)

第二步:创建用户网关

前往VPN - 用户网关页面,单击创建用户网关

分别创建 2 个用户网关用于创建 2 个加密隧道。

  • IP地址:配置本地数据中心网关设备的公网 IP 地址。

  • 自治系统号:计划启用BGP时,需配置。本文无需配置。

image

image

第三步:创建 IPsec 连接

  1. 前往VPN - 创建IPsec连接页面,配置完成后单击确定

    IPsec配置

    • 地域:选择 VPC 所在地域。本文为新加坡

    • 绑定VPN网关:选择第一步创建的 VPN 网关。

    • 路由模式:选择目的路由模式,基于目的 IP 地址路由和转发流量。

    • 立即生效:选择是,配置完成后立即进行协商。

    image

    隧道配置

    • 启用BGP:本文选择不启用。

    • Tunnel:分别配置主隧道和备隧道。

      • Tunnel 1:主隧道。

        • 用户网关:选择第二步创建的用户网关CGW1

        • 预共享密钥:隧道及其对端网关设备配置的预共享密钥需一致,否则系统无法正常建立IPsec-VPN连接。

        • 加密配置:根据本地网关设备的支持情况选择,确保 IPsec 连接和本地网关设备的加密配置保持一致。

      • Tunnel 2:备隧道。

        • 用户网关:选择第二步创建的用户网关CGW2

        • 预共享密钥:与主隧道的配置保持一致。且隧道及其对端网关设备配置的预共享密钥需一致,否则系统无法正常建立IPsec-VPN连接。

        • 加密配置:根据本地网关设备的支持情况选择,确保 IPsec 连接和本地网关设备的加密配置保持一致。

    image

    image

  2. 创建成功对话框,单击取消。单击创建的 IPsec 连接操作列的生成对端配置复制配置并保存在本地,用于后续配置本地网关设备。

第四步:配置本地网关设备

本文以本地网关设备部署 strongSwan 软件(下文简称为“ strongSwan 设备”)为例。

其他本地网关设备配置示例
以下内容包含的第三方产品信息仅供参考。阿里云对第三方产品的性能、可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺。
以下步骤以运行CentOS Stream 9 64位操作系统的strongSwan设备为例。其他操作系统,请参考strongSwan官方文档
  1. 放通防火墙策略:在 strongSwan 设备上放通 ESP 协议( IP 协议号 50)、UDP 500端口、UDP 4500端口。

    iptables -I INPUT -p 50 -j ACCEPT
    iptables -I INPUT -p udp --dport 500 -j ACCEPT 
    iptables -I INPUT -p udp --dport 4500 -j ACCEPT
  2. 执行echo 1 > /proc/sys/net/ipv4/ip_forward开启流量转发。

    上述命令为临时性命令,strongSwan 设备重启后需重新配置该命令。可单击查看永久开启流量转发的配置。

    1. 执行vi /etc/sysctl.conf

    2. 在文件中添加配置并保存:net.ipv4.ip_forward = 1

    3. 执行sudo sysctl -p确保配置生效。

  3. 执行dnf install epel-release -ydnf install strongswan -y安装 strongSwan 软件。

  4. 配置双隧道:

    双出口基于 XFRM 虚拟网络接口实现,使用XFRM虚拟网络接口需要安装strongSwan 5.8.0或以上版本,同时要求Linux内核版本为4.19及以上、iproute2版本为5.1.0及以上,且内核支持xfrm模块(lsmod | grep xfrm无显示则不支持)。更多信息,请参见XFRM Interfaces on Linux

    1. 添加指向阿里云侧2个 IPsec 地址的路由,使 IPsec 地址1通过 eth0 出口访问,IPsec 地址2通过 eth1 出口访问,确保 IPsec 地址可 ping 通。

      ip route add 120.XX.XX.152 via 172.16.1.253 dev eth0  #172.16.1.253是eth0私网网关地址
      ip route add 120.XX.XX.0 via 172.16.2.253 dev eth1   #172.16.2.253是eth1私网网关地址
    2. 创建2个虚拟网络接口,分别用于建立 IPsec-VPN 主备隧道。

      ip link add ipsec0 type xfrm dev eth0 if_id 42 # 创建隧道1 XFRM虚拟网络接口,接口ID为42,底层接口为公网接口eth0。
      ip link add ipsec1 type xfrm dev eth1 if_id 43 # 创建隧道2 XFRM虚拟网络接口,接口ID为43,底层接口为公网接口eth1。
      ip link set ipsec0 up # 启动隧道1 XFRM虚拟网络接口。
      ip link set ipsec1 up # 启动隧道2 XFRM虚拟网络接口。

      创建虚拟网络接口的配置为临时性配置,strongSwan设备重启后,需要重新添加该配置,并执行sudo systemctl restart strongswan;swanctl --load-all命令(该命令需要root权限)。单击查看开机自动启动脚本

      1. 执行vi xfrm.sh创建脚本,添加并保存如下配置。

      2. 添加并保存如下配置。

        sudo ip link add ipsec0 type xfrm dev eth0 if_id 42 # 创建隧道1 XFRM虚拟网络接口,接口ID为42,底层接口为公网接口eth0。
        sudo ip link add ipsec1 type xfrm dev eth1 if_id 43 # 创建隧道2 XFRM虚拟网络接口,接口ID为43,底层接口为公网接口eth1。
        sudo ip link set ipsec0 up # 启动隧道1 XFRM虚拟网络接口。
        sudo ip link set ipsec1 up # 启动隧道2 XFRM虚拟网络接口。
      3. 执行sudo find / -name xfrm.sh查看脚本绝对路径。

      4. 执行sudo vi /etc/rc.d/rc.local,添加脚本绝对路径并保存。

      5. 执行sudo chmod +x /etc/rc.d/rc.localsudo chmod +x /root/xfrm.sh添加可执行权限。

    3. 修改 strongSwan 配置文件。

      1. 执行mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak备份原始配置文件。

      2. 执行vi /etc/strongswan/swanctl/swanctl.conf,按照 IPsec 连接的配置,添加、修改并保存如下配置。

        connections {
           vco1 {                               # 添加IPsec-VPN隧道1的VPN配置
              version = 2                       # 指定IKE版本,需与阿里云隧道1的IKE版本保持一致,2表示IKEv2。
              local_addrs  = 172.16.0.93        # 第1个本地网卡的ip地址
              remote_addrs = 120.XX.XX.152      # 指定隧道1对端的IP地址为阿里云隧道1的网关IP地址,即IPsec地址1。
              dpd_delay = 10
              rekey_time = 84600                # 指定隧道1的SA生存周期,需与阿里云隧道1 IKE配置中的SA生存周期保持一致。
              over_time = 1800               
              proposals = aes-sha1-modp1024     # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IKE配置保持一致,group2对应的是modp1024。
              encap = yes
        
              local {
                 auth = psk                     # 本段认证方式选择PSK模式,即预共享密钥方式。
                 id = 47.XX.XX.198              # 第1个本地公网出口IP,需与阿里云隧道1的RemoteId保持一致。
              }
              remote {
                 auth = psk                     # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
                 id = 120.XX.XX.152             # 阿里云侧IPsec地址1,需与阿里云隧道1的LocalId保持一致。
              }
              children {
                 vco_child1 {
                    local_ts  = 0.0.0.0/0    
                    remote_ts = 0.0.0.0/0    
                    mode = tunnel
                    rekey_time = 85500
                    life_time = 86400           # 指定隧道1的SA生存周期,需与阿里云隧道1 IPsec配置中的SA生存周期保持一致。
                    dpd_action = restart
                    start_action = start
                    close_action = start
                    esp_proposals = aes-sha1-modp1024   # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IPsec配置保持一致,group2对应的是modp1024。
        
                    if_id_out = 42                      # 指定隧道1的出接口和入接口为隧道1 XFRM虚拟网络接口。
                    if_id_in = 42
                    updown = /root/connect_1.sh         # 根据隧道1的UP和DOWN状态执行/root/connect_1.sh脚本,以配置路由。
                 }
              }
           }
          vco2 {                                # 添加IPsec-VPN隧道2的VPN配置
              version = 2                       # 指定IKE版本,需与阿里云隧道2的IKE版本保持一致,2表示IKEv2。
              local_addrs  = 172.16.2.57        # 第2个本地网卡的ip地址。
              remote_addrs = 120.XX.XX.0        # 指定隧道2对端的IP地址为阿里云隧道2的网关IP地址,即IPsec地址2。
              dpd_delay = 10
              rekey_time = 84600                # 指定隧道2的SA生存周期,需与阿里云隧道2 IKE配置中的SA生存周期保持一致。
              over_time = 1800                
              proposals = aes-sha1-modp1024     # 指定隧道2的加密算法、认证算法、DH分组,需与阿里云隧道2 IKE配置保持一致,group2对应的是modp1024。
              encap = yes
        
              local {
                 auth = psk                     # 本端认证方式选择PSK方式,即预共享密钥方式。
                 id = 47.XX.XX.181              # 第2个本地公网出口IP,,需与阿里云隧道2的RemoteId保持一致。
              }
              remote {
                 auth = psk                     # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
                 id = 120.XX.XX.0               # 阿里云侧IPsec地址2,需与阿里云隧道2的LocalId保持一致。
              }
              children {
                 vco_child2 {
                    local_ts  = 0.0.0.0/0
                    remote_ts = 0.0.0.0/0   
                    mode = tunnel 
                    rekey_time = 85500
                    life_time = 86400           # 指定隧道2的SA生存周期,需与阿里云隧道1 IPsec配置中的SA生存周期保持一致。
                    dpd_action = restart
                    start_action = start
                    close_action = start
                    esp_proposals = aes-sha1-modp1024     # 指定隧道2的加密算法、认证算法、DH分组,需与阿里云隧道2 IPsec配置保持一致,group2对应的是modp1024。
                    if_id_out = 43                        # 指定隧道2的出接口和入接口为隧道2 XFRM虚拟网络接口。
                    if_id_in = 43
                    updown = /root/connect_2.sh           # 根据隧道2的UP和DOWN状态执行/root/connect_2.sh脚本,以配置路由。
                 }
              }
           }
        }
        
        # 此处的密钥配置不指定id,所有隧道共享。不指定id时,请确保两个密钥的内容相同,否则可能协商失败。
        secrets {
           ike-vco1 {
              secret = <指定隧道1的预共享密钥>            # 与阿里云隧道1的预共享密钥保持一致。
           }
           ike-vco2 {
              secret = <指定隧道2的预共享密钥>            # 与阿里云隧道2的预共享密钥保持一致。
           }
        }
  5. 重启 strongSwan 进程,重新加载 strongSwan 配置,查看隧道状态。

    sudo systemctl restart strongswan
    swanctl --load-all
    watch swanctl --list-sas

    如下图所示,strongSwan设备和 VPN 网关之间已经成功建立 IPsec-VPN 连接。

    image

  6. 配置路由:

    1. 执行vi /root/connect_1.sh,添加并保存以下配置。

      # 如果隧道1的状态是UP,则添加路由使本地数据中心去往阿里云VPC(192.168.0.0/16)的流量通过隧道1 XFRM虚拟网络接口传输
      # 同时指定该路由的metric值为100,使该路由的优先级高于指向隧道2 XFRM虚拟网络接口的路由。
      # 如果隧道1的状态是DOWN,则撤销该路由。
      #!/usr/bin/env bash
      if [ x"$PLUTO_VERB" == "xup-client" ]; then
      	echo "ip route add 192.168.0.0/16 dev ipsec0" >> /root/vpn_route.log;ip route add 192.168.0.0/16 dev ipsec0 metric 100
      elif [ x"$PLUTO_VERB" == "xdown-client" ]; then
      	echo "ip route del 192.168.0.0/16 dev ipsec0" >> /root/vpn_route.log;ip route del 192.168.0.0/16 dev ipsec0 metric 100
      fi
    2. 执行vi /root/connect_2.sh,添加并保存以下配置。

      # 如果隧道2的状态是UP,则添加路由使本地数据中心去往阿里云VPC(192.168.0.0/16)的流量通过隧道2 XFRM虚拟网络接口传输
      # 同时指定该路由的metric值为101,使该路由的优先级低于指向隧道1 XFRM虚拟网络接口的路由。
      # 如果隧道2的状态是DOWN,则撤销该路由。
      #!/usr/bin/env bash
      if [ x"$PLUTO_VERB" == "xup-client" ]; then
      	echo "ip route add 192.168.0.0/16 dev ipsec1" >> /root/vpn_route.log;ip route add 192.168.0.0/16 dev ipsec1 metric 101
      elif [ x"$PLUTO_VERB" == "xdown-client" ]; then
      	echo "ip route del 192.168.0.0/16 dev ipsec1" >> /root/vpn_route.log;ip route del 192.168.0.0/16 dev ipsec1 metric 101
      fi
    3. 执行sudo chmod +x /root/connect_1.shsudo chmod +x /root/connect_2.sh赋予可执行权限。

    4. 执行sudo systemctl restart strongswan重启 strongSwan 进程。

    5. 执行route -n确认路由是否配置成功。

      image

    6. 为本地数据中心内、计划与 VPC 连通的服务器配置目标网段为 VPC 网段、下一跳为 strongSwan 设备的路由。

    7. 执行以下命令关闭 rp_filter,避免因非对称路由导致无法连通。

      sudo sysctl -w net.ipv4.conf.all.rp_filter=0
      sudo sysctl -w net.ipv4.conf.eth0.rp_filter=0
      sudo sysctl -w net.ipv4.conf.eth1.rp_filter=0

第五步:配置 VPN 网关路由

前往VPN - VPN 网关页面,单击第一步创建的 VPN 网关 ID。

单击目的路由表页签,选择添加路由条目

  • 目标网段:配置本地数据中心的网段。

  • 下一跳:选择第三步创建的 IPsec 连接。

  • 发布到专有网络:选择,将新添加的路由发布到 VPN 网关关联的 VPC。

image

验证测试

  1. 测试本地数据中心和 VPC 的连通性:登录 VPC 中的 ECS 实例,执行ping <本地数据中心服务器私网IP地址>,收到本地数据中心服务器的回复报文,即可正常通信。

  2. 测试 IPsec-VPN 连接的高可用性。

    1. 登录 VPC 中的 ECS 实例,执行ping <本地数据中心服务器私网IP地址> -c 10000连续向本地数据中心发送访问报文。

    2. 中断 IPsec-VPN 连接的主隧道:可通过修改 IPsec 连接主隧道的预共享密钥,主隧道因两端的预共享密钥不一致而中断。

    3. 中断主隧道后,观察 VPC 中 ECS 实例的通信情况:流量在短暂中断后,又重新恢复通信,则表示在主隧道中断后,流量自动通过备隧道进行通信。

      image