strongSwan配置示例

本文介绍如何使用strongSwan作为本地网关,实现云上和云下的网络互通。

strongSwan是一个开源、基于IPsecVPN解决方案,配置简单,可部署在主流的Linux发行版,快速地与阿里云建立IPsec-VPN连接。

说明

本文使用VPN网关实例默认的双隧道模式建立IPsec-VPN连接。如果您购买的VPN网关实例仅支持单隧道,请参见文末的单隧道如何配置?

场景示例

以下图场景为例,您可以在本地网关设备上部署strongSwan软件(下文简称为“strongSwan设备”),与阿里云建立双隧道模式的IPsec-VPN连接,实现云上云下网络互通。

image

IP地址规划

本地IDC

  • 私网网段:172.16.0.0/16

  • strongSwan设备

    • 网卡eth0: 172.16.20.80,NAT映射公网出口1:120.XX.XX.202

    • (可选)网卡eth1: 172.16.21.248,NAT映射公网出口2: 47.XX.XX.127

      说明

      NAT场景,请参见“strongSwan设备网卡绑定了公网IP地址,如何配置?”。

      无论您的设备有1个公网出口(单出口),还是有2个公网出口(双出口),均可与阿里云建立双隧道模式的IPsec-VPN连接,本文会分别给出示例。

阿里云侧

  • VPC网段:192.168.0.0/16

    • 交换机1网段:192.168.10.0/24

    • 交换机2网段:192.168.10.0/24

    • 交换机3网段:192.168.40.0/24

    • 交换机4网段:192.168.50.0/24

    • 交换机5网段:192.168.55.0/24

  • VPN网关

    • IPsec地址1: 47.XX.XX.151

    • IPsec地址2: 47.XX.XX.87

      说明

      创建VPN网关实例后,系统会自动为VPN网关实例分配两个IPsec地址。

BGP IP地址

本文将分别描述IPsec-VPN连接使用静态路由方式和BGP动态路由方式下如何配置strongSwan设备。如果您不需要使用BGP动态路由方式,可以忽略本部分。以下为本文的BGP网段规划。

资源

隧道

BGP隧道网段

BGP IP地址

BGP AS号(本端自治系统号)

VPN网关实例

隧道1

169.254.10.0/30

说明

一个VPN网关实例下,每个隧道的网段需保持唯一。

169.254.10.1

65535

隧道2

169.254.20.0/30

169.254.20.1

strongSwan设备

隧道1

169.254.10.0/30

169.254.10.2

65530

隧道2

169.254.20.0/30

169.254.20.2

VPN参数配置规划

本文2条隧道使用相同的示例值。注意每条隧道下,strongSwan设备侧和阿里云侧的配置要保持相同。

  • 预共享密钥:ChangeMe***

  • IKE配置

    • IKE版本:ikev2

    • 协商模式:main

    • 加密算法:aes

    • 认证算法:sha1

    • DH分组:group2

    • SA生存周期(秒):86400

  • IPsec配置:

    • 加密算法:aes

    • 认证算法:sha1

    • DH分组:group2

    • SA生存周期(秒):86400

阿里云侧的准备工作

根据您计划使用的公网出口数量和路由方式,参见以下内容,完成阿里云侧的配置:

双出口-BGP动态路由

请参见建立VPC到本地数据中心的连接(双隧道模式和BGP路由),完成创建VPN网关实例创建用户网关创建IPsec连接开启BGP路由自动传播功能的步骤。

  1. strongSwan设备拥有2个公网出口IP,需要创建2个用户网关。

  2. 创建IPsec连接时,隧道1对应公网出口1,隧道2对应公网出口2。路由模式本场景以目的路由模式为例。

双出口-静态路由

请参见建立VPC到本地数据中心的连接(双隧道模式),完成创建VPN网关实例创建用户网关创建IPsec连接配置VPN网关路由的步骤。

  1. strongSwan设备拥有2个公网出口IP,需要创建2个用户网关。

  2. 创建IPsec连接时,隧道1对应公网出口1,隧道2对应公网出口2。路由模式本场景以目的路由模式为例。

单出口-BGP动态路由

请参见建立VPC到本地数据中心的连接(双隧道模式和BGP路由),完成创建VPN网关实例创建用户网关创建IPsec连接开启BGP路由自动传播功能的步骤。

  1. strongSwan设备仅有1个公网出口IP,因此仅需创建1个用户网关。

  2. 创建IPsec连接时,两条隧道关联同1个用户网关。路由模式本场景以目的路由模式为例。

单出口-静态路由

请参见建立VPC到本地数据中心的连接(双隧道模式),完成创建VPN网关实例创建用户网关创建IPsec连接配置VPN网关路由的步骤。其中:

  1. strongSwan设备仅有1个公网出口IP,因此仅需创建1个用户网关。

  2. 创建IPsec连接时,需使用感兴趣流模式,配置如下。两条隧道关联同1个用户网关。

    • 本端网段输入阿里云侧VPC的网段192.168.0.0/16

    • 对端网段输入本地IDC侧的私网网段172.16.0.0/16

说明

对于IPsec连接绑定转发路由器的场景,更推荐您使用BGP动态路由协议,不推荐使用该方式。

开始配置strongSwan设备

说明

下文步骤以运行“CentOS Stream 9 64位操作系统”的strongSwan设备为例。其他操作系统,请参考strongSwan官方文档

1. 放通防火墙策略

strongSwan设备上放通ESP协议(IP协议号50)、UDP500端口、UDP4500端口。

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设备重启后需重新配置该命令。您可以参见以下内容永久开启strongSwan设备的流量转发功能。

单击查看永久配置。

  1. 打开/etc/sysctl.conf文件。

    vi /etc/sysctl.conf
  2. 在文件中添加如下配置。

    net.ipv4.ip_forward = 1
  3. 使配置生效。

    sudo sysctl -p

3. 安装strongSwan软件

dnf install epel-release -y
dnf install strongswan-5.9.10 -y

4. 配置双隧道

双出口-静态路由和BGP动态路由

重要

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

  1. 添加去往阿里云侧2IPsec地址的路由,使IPsec地址1通过eth0出口访问,IPsec地址2通过eth1出口访问。

    ip route add 47.XX.XX.151 via 172.16.20.253 dev eth0  #172.16.20.253eth0私网网关地址
    ip route add 47.XX.XX.87 via 172.16.21.253 dev eth1   #172.16.20.253eth1私网网关地址

    确保下面2IPsec地址能ping通。

    ping 47.XX.XX.151 
    ping 47.XX.XX.87 
  2. 创建2个虚拟网络接口,用于建立IPsec-VPN隧道。

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

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

    单击查看开机自动启动脚本

    1. 执行以下命令创建一个脚本。

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

      sudo ip link add ipsec0 type xfrm dev eth0 if_id 42 # 创建隧道1 XFRM虚拟网络接口,接口ID42,底层接口为公网接口eth0。
      sudo ip link add ipsec1 type xfrm dev eth1 if_id 43 # 创建隧道2 XFRM虚拟网络接口,接口ID43,底层接口为公网接口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命令,将脚本绝对路径添加进/etc/rc.d/rc.local文件。

      按下i键,进入编辑模式;将脚本绝对路径/root/xfrm.sh添加进/etc/rc.d/rc.local文件;按下Esc键,退出编辑模式,然后输入:wq保存配置。

    5. rc.local文件和xfrm.sh脚本添加可执行权限。

      sudo chmod +x /etc/rc.d/rc.local
      sudo chmod +x /root/xfrm.sh
  3. 修改strongSwan配置文件。

    1. 备份原始strongSwan配置文件。

      mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak
    2. 新建strongSwan配置文件。

      vi /etc/strongswan/swanctl/swanctl.conf
    3. 根据场景示例中IPsec参数规划,添加并保存如下配置。

      重要

      如果您计划使用静态路由方式,需要在配置文件中启用以下两条命令updown = /root/connect_1.shupdown = /root/connect_2.sh

      connections {
         vco1 {                            # 添加IPsec-VPN隧道1VPN配置
            version = 2                    # 指定IKE版本,需与阿里云隧道1IKE版本保持一致,2表示IKEv2。
            local_addrs  = 172.16.20.80       # 第1个本地网卡的ip地址
            remote_addrs = 47.XX.XX.151       # 指定隧道1对端的IP地址为阿里云隧道1的网关IP地址,即IPsec地址1。
            dpd_delay = 10
            rekey_time = 84600             # 指定隧道1SA生存周期,需与阿里云隧道1 IKE配置中的SA生存周期保持一致。
            over_time = 1800               
            proposals = aes-sha1-modp1024  # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IKE配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
            encap = yes
      
            local {
               auth = psk                  # 本段认证方式选择PSK模式,即预共享密钥方式。
               id = 120.XX.XX.202             # 第1个本地公网出口IP,需与阿里云隧道1RemoteId保持一致。
            }
            remote {
               auth = psk                  # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
               id = 47.XX.XX.151             # 阿里云侧IPsec地址1,需与阿里云隧道1LocalId保持一致。
            }
            children {
               vco_child1 {
                  local_ts  = 0.0.0.0/0    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0。
                  remote_ts = 0.0.0.0/0    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0。
                  mode = tunnel
                  rekey_time = 85500
                  life_time = 86400        # 指定隧道1SA生存周期,需与阿里云隧道1 IPsec配置中的SA生存周期保持一致。
                  dpd_action = restart
                  start_action = start
                  close_action = start
                  esp_proposals = aes-sha1-modp1024   # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IPsec配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
      
                  if_id_out = 42           # 指定隧道1的出接口和入接口为隧道1 XFRM虚拟网络接口。
                  if_id_in = 42
                  #updown = /root/connect_1.sh         # 根据隧道1UPDOWN状态执行/root/connect_1.sh脚本,以配置路由。仅使用静态路由时需要配置该参数。
               }
            }
         }
        vco2 {                             # 添加IPsec-VPN隧道2VPN配置
            version = 2                    # 指定IKE版本,需与阿里云隧道2IKE版本保持一致,2表示IKEv2。
            local_addrs  = 172.16.21.248        # 第2个本地网卡的ip地址。
            remote_addrs = 47.XX.XX.127       # 指定隧道2对端的IP地址为阿里云隧道2的网关IP地址,即IPsec地址2。
            dpd_delay = 10
            rekey_time = 84600             # 指定隧道2SA生存周期,需与阿里云隧道2 IKE配置中的SA生存周期保持一致。
            over_time = 1800               # 
            proposals = aes-sha1-modp1024  # 指定隧道2的加密算法、认证算法、DH分组,需与阿里云隧道2 IKE配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
            encap = yes
      
            local {
               auth = psk                  # 本端认证方式选择PSK方式,即预共享密钥方式。
               id = 47.XX.XX.87              # 第2个本地公网出口IP,,需与阿里云隧道2RemoteId保持一致。
            }
            remote {
               auth = psk                  # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
               id = 47.XX.XX.127             # 阿里云侧IPsec地址2,需与阿里云隧道2LocalId保持一致。
            }
            children {
               vco_child2 {
                  local_ts  = 0.0.0.0/0    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0
                  remote_ts = 0.0.0.0/0    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0
                  mode = tunnel 
                  rekey_time = 85500
                  life_time = 86400        # 指定隧道2SA生存周期,需与阿里云隧道1 IPsec配置中的SA生存周期保持一致。
                  dpd_action = restart
                  start_action = start
                  close_action = start
                  esp_proposals = aes-sha1-modp1024     # 指定隧道2的加密算法、认证算法、DH分组,需与阿里云隧道2 IPsec配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
                  if_id_out = 43           # 指定隧道2的出接口和入接口为隧道2 XFRM虚拟网络接口。
                  if_id_in = 43
                  #updown = /root/connect_2.sh           # 根据隧道2UPDOWN状态执行/root/connect_2.sh脚本,以配置路由。仅使用静态路由时需要配置该参数。
               }
            }
         }
      }
      
      secrets {
         ike-vco1 {
            secret = ChangeMe***            # 指定隧道1的预共享密钥,需与阿里云隧道1的预共享密钥保持一致。
         }
         ike-vco2 {
            secret = ChangeMe***            # 指定隧道2的预共享密钥,需与阿里云隧道2的预共享密钥保持一致。
         }
      }
  4. 重启strongSwan进程,查看隧道状态。

    sudo systemctl restart strongswan  
    watch swanctl --list-sas  

    如下图所示,strongSwan设备和VPN网关之间已经成功建立IPsec-VPN连接,但网络还无法正常互通,您还需要配置路由。

    IPsec-VPN

  5. 配置路由。

    根据您计划使用的路由方式查看对应内容。

    BGP动态路由

    说明

    strongSwan设备重启后,需要重新添加BGP配置。

    1. 执行以下命令配置BGP IP地址。

      ip address add 169.254.10.2/30 dev ipsec0
      ip address add 169.254.20.2/30 dev ipsec1
    2. 安装frr软件。

      yum install -y frr
    3. 执行vi /etc/frr/daemons命令,编辑配置文件,开启BGP动态路由功能。

      按下i键,进入编辑模式;修改bgpd参数的值为yes,开启BGP动态路由功能;按下Esc键,退出编辑模式,然后输入:wq保存配置。

    4. 运行frr功能。

      systemctl enable frr
      systemctl restart frr
    5. 添加BGP配置。

      1. 执行以下命令进入配置界面。

        vtysh
      2. 执行以下命令进入配置模式。

        config terminal
      3. 添加BGP配置。

        执行命令时,将以下地址替换为您实际使用的地址。

        • “169.254.10.1”、“169.254.20.1”替换为您实际使用的阿里云侧隧道BGP IP地址。

        • “65535”替换为您实际场景中VPN网关实例的BGP AS号。

        • “172.16.20.0/24”、“172.16.21.0/24”替换为您实际场景中本地IDC的网段。

        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.20.0/24                  
          network 172.16.21.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
        
    6. 执行exit命令退出配置模式,然后执行show ip bgp命令查看BGP路由条目。

      可以看到strongswan设备已经成功学习到云上VPC的路由,本地IDC与云上VPC之间已经可以正常互通。BGP路由

    静态路由

    创建2个脚本,供strongSwan调用并配置路由,从而控制流量传输。

    1. 新建并编辑/root/connect_1.sh脚本。

      vi /root/connect_1.sh
    2. 添加并保存如下内容。

      #!/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

      脚本功能:如果隧道1的状态是UP,则添加路由使本地数据中心去往阿里云VPC(192.168.0.0/16)的流量通过隧道1 XFRM虚拟网络接口传输,同时指定该路由的metric值为100,使该路由的优先级高于指向隧道2 XFRM虚拟网络接口的路由。如果隧道1的状态是DOWN,则撤销该路由。

    3. 新建并编辑/root/connect_2.sh脚本。

      vi /root/connect_2.sh
    4. 添加并保存如下内容。

      #!/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

      脚本功能:如果隧道2的状态是UP,则添加路由使本地数据中心去往阿里云VPC(192.168.0.0/16)的流量通过隧道2 XFRM虚拟网络接口传输,同时指定该路由的metric值为101,使该路由的优先级低于指向隧道1 XFRM虚拟网络接口的路由。如果隧道2的状态是DOWN,则撤销该路由。

    5. 2个脚本赋予可执行权限。

      sudo chmod +x /root/connect_1.sh
      sudo chmod +x /root/connect_2.sh
    6. 重启strongSwan进程。

      sudo systemctl restart strongswan
    7. 执行以下命令查看路由是否配置成功。

      route -n

      静态路由

单出口-BGP动态路由

重要

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

  1. 创建2个虚拟网络接口,用于建立IPsec-VPN隧道。

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

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

    单击查看开机自动启动脚本

    1. 执行以下命令创建一个脚本。

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

      sudo ip link add ipsec0 type xfrm dev eth0 if_id 42 # 创建隧道1 XFRM虚拟网络接口,接口ID42,底层接口为公网接口eth0。
      sudo ip link add ipsec1 type xfrm dev eth0 if_id 43 # 创建隧道2 XFRM虚拟网络接口,接口ID43,底层接口为公网接口eth0。
      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命令,将脚本绝对路径添加进/etc/rc.d/rc.local文件。

      按下i键,进入编辑模式;将脚本绝对路径/root/xfrm.sh添加进/etc/rc.d/rc.local文件;按下Esc键,退出编辑模式,然后输入:wq保存配置。

    5. rc.local文件和xfrm.sh脚本添加可执行权限。

      sudo chmod +x /etc/rc.d/rc.local
      sudo chmod +x /root/xfrm.sh
  2. 修改strongSwan配置文件。

    1. 备份原始strongSwan配置文件。

      mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak
    2. 新建strongSwan配置文件。

      vi /etc/strongswan/swanctl/swanctl.conf
    3. 根据场景示例中IPsec参数规划,添加并保存如下配置。

      connections {
         vco1 {                            # 添加IPsec-VPN隧道1VPN配置。
            version = 2                    # 指定IKE版本,需与阿里云隧道1IKE版本保持一致,2表示IKEv2。
            local_addrs  = 172.16.20.80    # eth0接口私网IP地址。
            remote_addrs = 47.XX.XX.151    # 指定隧道1对端的IP地址为阿里云隧道1的网关IP地址,即IPsec地址1。
            dpd_delay = 10
            rekey_time = 84600             # 指定隧道1SA生存周期,需与阿里云隧道1 IKE配置中的SA生存周期保持一致。
            over_time = 1800               
            proposals = aes-sha1-modp1024  # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IKE配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
            encap = yes
      
            local {
               auth = psk                  # 本端认证方式选择PSK模式,即预共享密钥方式。
               id = 120.XX.XX.202          # eth0公网出口IP,需与阿里云隧道1RemoteId保持一致。
            }
            remote {
               auth = psk                  # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
               id = 47.XX.XX.151           # 阿里云侧IPsec地址1,需与阿里云隧道1LocalId保持一致。
            }
            children {
               vco_child1 {
                  local_ts  = 0.0.0.0/0    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0。
                  remote_ts = 0.0.0.0/0    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0。
                  mode = tunnel
                  rekey_time = 85500
                  life_time = 86400        # 指定隧道1SA生存周期,需与阿里云隧道1 IPsec配置中的SA生存周期保持一致。
                  dpd_action = restart
                  start_action = start
                  close_action = start
                  esp_proposals = aes-sha1-modp1024   # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IPsec配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
      
                  if_id_out = 42           # 指定隧道1的出接口和入接口为隧道1 XFRM虚拟网络接口。
                  if_id_in = 42
               }
            }
         }
        vco2 {                             # 添加IPsec-VPN隧道2VPN配置
            version = 2                    # 指定IKE版本,需与阿里云隧道2IKE版本保持一致,2表示IKEv2。
            local_addrs  = 172.16.20.80    # eth0接口的私网IP地址。
            remote_addrs = 47.XX.XX.87     # 指定隧道2对端的IP地址为阿里云隧道2的网关IP地址,即IPsec地址2。
            dpd_delay = 10
            rekey_time = 84600             # 指定隧道2SA生存周期,需与阿里云隧道2 IKE配置中的SA生存周期保持一致。
            over_time = 1800               # 
            proposals = aes-sha1-modp1024  # 指定隧道2的加密算法、认证算法、DH分组,需与阿里云隧道2 IKE配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
            encap = yes
      
            local {
               auth = psk                  # 本端认证方式选择PSK方式,即预共享密钥方式。
               id = 120.XX.XX.202          # eth0公网出口IP,需与阿里云隧道2RemoteId保持一致。
            }
            remote {
               auth = psk                  # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
               id = 47.XX.XX.87            # 阿里云侧IPsec地址2,需与阿里云隧道2LocalId保持一致。
            }
            children {
               vco_child2 {
                  local_ts  = 0.0.0.0/0    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0。
                  remote_ts = 0.0.0.0/0    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0。
                  mode = tunnel 
                  rekey_time = 85500
                  life_time = 86400        # 指定隧道2SA生存周期,需与阿里云隧道1 IPsec配置中的SA生存周期保持一致。
                  dpd_action = restart
                  start_action = start
                  close_action = start
                  esp_proposals = aes-sha1-modp1024     # 指定隧道2的加密算法、认证算法、DH分组,需与阿里云隧道2 IPsec配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
                  if_id_out = 43           # 指定隧道2的出接口和入接口为隧道2 XFRM虚拟网络接口。
                  if_id_in = 43
                
               }
            }
         }
      }
      
      secrets {
         ike-vco1 {
            secret = ChangeMe***            # 指定隧道1的预共享密钥,需与阿里云隧道1的预共享密钥保持一致。
         }
         ike-vco2 {
            secret = ChangeMe***            # 指定隧道2的预共享密钥,需与阿里云隧道2的预共享密钥保持一致。
         }
      }
  3. 重启strongSwan进程,查看隧道状态。

    sudo systemctl restart strongswan  
    watch swanctl --list-sas  

    如下图所示,strongSwan设备和VPN网关之间已经成功建立IPsec-VPN连接,但网络还无法正常互通,您还需要配置路由。

    单出口

  4. 配置BGP动态路由。

    说明

    strongSwan设备重启后,需要重新添加BGP配置。

    1. 执行以下命令配置BGP IP地址。

      ip address add 169.254.10.2/30 dev ipsec0
      ip address add 169.254.20.2/30 dev ipsec1
    2. 安装frr软件。

      yum install -y frr
    3. 执行vi /etc/frr/daemons命令,编辑配置文件,开启BGP动态路由功能。

      按下i键,进入编辑模式;修改bgpd参数的值为yes,开启BGP动态路由功能;按下Esc键,退出编辑模式,然后输入:wq保存配置。

    4. 运行frr功能。

      systemctl enable frr
      systemctl restart frr
    5. 添加BGP配置。

      1. 执行以下命令进入配置界面。

        vtysh
      2. 执行以下命令进入配置模式。

        config terminal
      3. 添加BGP配置。

        执行命令时,将以下地址替换为您实际使用的地址。

        • “169.254.10.1”、“169.254.20.1”替换为您实际使用的阿里云侧隧道BGP IP地址。

        • “65535”替换为您实际场景中VPN网关实例的BGP AS号。

        • “172.16.20.0/24”、“172.16.21.0/24”替换为您实际场景中本地IDC的网段。

        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.20.0/24                  
          network 172.16.21.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
        
    6. 执行exit命令退出配置模式,然后执行show ip bgp命令查看BGP路由条目。

      可以看到strongswan设备已经成功学习到云上VPC的路由,本地IDC与云上VPC之间已经可以正常互通。BGP路由

单出口-静态路由

重要

单出口-静态路由方式下如果阿里云侧判断主隧道有风险,会主动将流量切换至备隧道,有可能会导致流量不通。您可以观察/proc/net/xfrm_stat文件中XfrmInTmplMismatch参数的值来判断阿里云侧是否已将流量切换至备隧道,如果该参数的值一直在变化,则证明阿里云侧已将流量切换至备隧道,您可以在/etc/strongswan/swanctl/swanctl.conf文件中修改备隧道priority的值,使本地IDC上云的流量优先通过备隧道传输。

  1. 备份原始strongSwan配置文件。

    mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak
  2. 新建strongSwan配置文件。

    vi /etc/strongswan/swanctl/swanctl.conf
  3. 根据场景示例中的规划,添加并保存如下配置。

    connections {
       vco1 {                              # 添加IPsec-VPN隧道1VPN配置。
          version = 2                      # 指定IKE版本,需与阿里云隧道1IKE版本保持一致,2表示IKEv2。
          local_addrs  = 172.16.20.80      # eth0私网IP地址。
          remote_addrs = 47.XX.XX.151      # 指定隧道1对端的IP地址为阿里云隧道1的网关IP地址,即IPsec地址1。
          dpd_delay = 10
          rekey_time = 84600               # 指定隧道1SA生存周期,需与阿里云隧道1 IKE配置中的SA生存周期保持一致。
          over_time = 1800               
          proposals = aes-sha1-modp1024    # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IKE配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
          encap = yes
    
          local {
             auth = psk                    # 本端认证方式选择PSK模式,即预共享密钥方式。
             id = 120.XX.XX.202            # 本地公网出口IP,需与阿里云隧道1RemoteId保持一致。
          }
          remote {
             auth = psk                    # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
             id = 120.XX.XX.202            # 阿里云侧IPsec地址1,需与阿里云隧道1LocalId保持一致。
          }
          children {
             vco_child1 {
                local_ts  = 172.16.0.0/16   # 本地侧感兴趣流,填写本地私网网段172.16.0.0/16。
                remote_ts = 192.168.0.0/16  # 阿里云侧感兴趣流,填写VPC网段192.168.0.0/16。
                mode = tunnel
                rekey_time = 85500
                life_time = 86400          # 指定隧道1SA生存周期,需与阿里云隧道1 IPsec配置中的SA生存周期保持一致。
                dpd_action = restart
                start_action = start
                close_action = start
                esp_proposals = aes-sha1-modp1024   # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IPsec配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
                priority = 1                        # 指定隧道1的优先级,优先使用主隧道上云。
             }
          }
       }
      vco2 {                             # 添加IPsec-VPN隧道2VPN配置
          version = 2                    # 指定IKE版本,需与阿里云隧道2IKE版本保持一致,2表示IKEv2。
          local_addrs  = 172.16.20.80    # eth0私网IP地址
          remote_addrs = 47.XX.XX.87     # 指定隧道2对端的IP地址为阿里云隧道2的网关IP地址,即IPsec地址2。
          dpd_delay = 10
          rekey_time = 84600             # 指定隧道2SA生存周期,需与阿里云隧道2 IKE配置中的SA生存周期保持一致。
          over_time = 1800               
          proposals = aes-sha1-modp1024  # 指定隧道2的加密算法、认证算法、DH分组,需与阿里云隧道2 IKE配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
          encap = yes
    
          local {
             auth = psk                  # 本端认证方式选择PSK方式,即预共享密钥方式。
             id = 120.XX.XX.202          # 本地公网出口IP,与阿里云隧道2RemoteId保持一致。
          }
          remote {
             auth = psk                  # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
             id = 47.XX.XX.87            # 阿里云侧IPsec地址2,需与阿里云隧道2LocalId保持一致。
          }
          children {
             vco_child2 {
                local_ts  = 172.16.0.0/16     # 本地侧感兴趣流,填写本地私网网段172.16.0.0/16。
                remote_ts =  192.168.0.0/16   # 阿里云侧感兴趣流,填写VPC网段192.168.0.0/16。
                mode = tunnel 
                rekey_time = 85500
                life_time = 86400        # 指定隧道2SA生存周期,需与阿里云隧道2 IPsec配置中的SA生存周期保持一致。
                dpd_action = restart
                start_action = start
                close_action = start
                esp_proposals = aes-sha1-modp1024     # 指定隧道2的加密算法、认证算法、DH分组,需与阿里云隧道2 IPsec配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
                priority = 2                          # 指定隧道2的优先级,隧道2的优先级低于隧道1。
             }
          }
       }
    }
    
    secrets {
       ike-vco1 {
          secret = ChangeMe***            # 指定隧道1的预共享密钥,需与阿里云隧道1的预共享密钥保持一致。
       }
       ike-vco2 {
          secret = ChangeMe***            # 指定隧道2的预共享密钥,需与阿里云隧道2的预共享密钥保持一致。
       }
    }
  4. 重启strongSwan进程,查看隧道状态。

    sudo systemctl restart strongswan  
    watch swanctl --list-sas  

    如下图所示,strongSwan设备和VPN网关之间已经成功建立IPsec-VPN连接,本地IDCVPC之间已经可以互相通信。

    单出口

5. 验证连通性和高可用性

  1. 验证本地IDCVPC之间的连通性。

    使用本地IDC中的一台客户端ping阿里云VPC内的任意1ECS,如果能ping通,则证明连通正常。

    ping <VPC1ECS的地址>
  2. 验证IPsec-VPN连接的高可用性。

    1. 保持ping通的情况下,中断IPsec-VPN连接下的主隧道。

      您可以通过修改IPsec连接主隧道的预共享密钥来中断主隧道,主隧道两端的预共享密钥不一致,则主隧道会中断。

    2. 中断主隧道后,您可以通过ping命令观察两侧的连通情况。您会发现ping流量在短暂中断后,又重新恢复通信。这表示在主隧道中断后,流量自动通过备隧道进行通信。

常见问题

IPsec连接绑定转发路由器场景下如何配置strongSwan设备?

IPsec连接绑定转发路由器的场景下,strongSwan设备侧的配置与上文相同。推荐您使用BGP动态路由协议,配置完成后,可以在strongSwan设备上看到通过BGP动态路由协议学习到的VPC侧路由,IPsec-VPN连接的两条隧道自动形成ECMP链路。等价路由

IKEv1版本,使用strongSwan建立IPsec-VPN连接时是否支持?

支持。

配置/etc/strongswan/swanctl/swanctl.conf文件时,指定version = 1即可。

如何指定感兴趣流?

配置/etc/strongswan/swanctl/swanctl.conf文件时,在以下配置中指定具体网段即可。请确保阿里云侧IPsec连接也配置了感兴趣流模式。

如果本地数据中心侧或阿里云侧需要指定多个网段,strongSwan设备和阿里云IPsec连接均需要使用IKEv2版本。

children {
         vco_child1 {
            local_ts  = 192.168.20.0/24,192.168.50.0/24    # 本地数据中心网段。
            remote_ts = 10.0.0.0/16    # 阿里云VPC侧网段。
         }
}

strongSwan设备网卡绑定了公网IP地址,如何配置?

对于非NAT的场景,也就是strongSwan设备内部可见的地址为公网IP地址,仅需将/etc/strongswan/swanctl/swanctl.conf配置文件中每条隧道的local_addrs字段改为公网IP地址即可,其他配置不变。

connections {
   vco1 {                            
      local_addrs  = 1.1.XX.XX     # 指定为strongSwan设备网卡绑定的公网IP地址
   }
}

单隧道如何配置?

重要

如果您购买的VPN网关实例仅支持建立单隧道模式的IPsec-VPN连接,推荐您升级IPsec-VPN连接为双隧道模式,双隧道模式的IPsec-VPN连接支持可用区级别的容灾,有效提高了网络的高可用性。

单击此处查看单隧道配置示例

单隧道配置示例

场景示例

以下图场景为例,您可以在本地网关设备上部署strongSwan软件(下文简称为“strongSwan设备”),与阿里云建立双隧道模式的IPsec-VPN连接,实现云上云下网络互通。

image

IP地址规划

本地IDC

阿里云侧

  • VPC网段:172.16.0.0/16

    • 交换机1网段:172.16.1.0/24

    • 交换机2网段:172.16.2.0/24

  • VPN网关

    • IPsec地址:3.3.XX.XX

      说明

      创建VPN网关实例后,系统会自动为VPN网关实例分配IPsec地址。

VPN参数配置规划

注意strongSwan设备侧和阿里云侧的配置要保持相同。

  • 预共享密钥:ChangeMe***

  • IKE配置

    • IKE版本:ikev2

    • 协商模式:main

    • 加密算法:aes

    • 认证算法:sha1

    • DH分组:group2

    • SA生存周期(秒):86400

  • IPsec配置:

    • 加密算法:aes

    • 认证算法:sha1

    • DH分组:group2

    • SA生存周期(秒):86400

阿里云侧的准备工作

配置strongSwan设备之前,请先根据场景示例中的规划,在阿里云侧完成创建VPN网关实例创建用户网关创建IPsec连接配置VPN网关路由的步骤。具体操作,请参见建立VPC到本地数据中心的连接(单隧道模式)

创建IPsec连接时,隧道的路由模式选择感兴趣流模式:

  • 本端网段填写阿里云侧VPC的网段 172.16.0.0/16

  • 对端网段填写本地IDC侧的私网网段 10.0.0.0/16

开始配置strongSwan设备

说明

下文步骤以运行“CentOS Stream 9 64位操作系统”的strongSwan设备为例。其他操作系统,请参考strongSwan的官方文档

1. 放通防火墙策略

放通strongSwan设备的ESP协议(IP协议号50)、UDP500端口、UDP4500端口。

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设备重启后需重新配置该命令。您可以参见以下内容永久开启strongSwan设备的流量转发功能。

单击查看永久配置。

  1. 打开/etc/sysctl.conf文件。

    vi /etc/sysctl.conf
  2. 在文件中添加如下配置。

    net.ipv4.ip_forward = 1
  3. 使配置生效。

    sudo sysctl -p

3. 安装strongSwan软件

dnf install epel-release -y
dnf install strongswan-5.9.10 -y

4. 配置隧道

基于strongSwan感兴趣流进行配置。

  1. 备份原始strongSwan配置文件

    mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak
  2. 新建strongSwan配置文件

    vi /etc/strongswan/swanctl/swanctl.conf
  3. 根据场景示例中的规划,添加并保存如下配置

    connections {
       vco1 {                            # 添加IPsec-VPN隧道1VPN配置
          version = 2                    # 指定IKE版本,需与阿里云隧道1IKE版本保持一致,2表示IKEv2。
          local_addrs  = 10.0.0.1        # 本地网卡的ip地址
          remote_addrs = 3.3.XX.XX       # 指定隧道1对端的IP地址为阿里云隧道1的网关IP地址,即IPsec地址1。
          dpd_delay = 10
          rekey_time = 84600             # 指定隧道1SA生存周期,需与阿里云隧道1 IKE配置中的SA生存周期保持一致。
          over_time = 1800               
          proposals = aes-sha1-modp1024  # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IKE配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
          encap = yes
    
          local {
             auth = psk                  # 本段认证方式选择PSK模式,即预共享密钥方式。
             id = 1.1.XX.XX              # 公网出口IP,与阿里云隧道1RemoteId保持一致。
          }
          remote {
             auth = psk                  # 对端认证方式选择PSK方式,即阿里云使用预共享密钥方式。
             id = 3.3.XX.XX              # 阿里云侧IPsec地址,需与阿里云隧道1LocalId保持一致。
          }
          children {
             vco_child1 {
                local_ts  = 10.0.0.0/16    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0。
                remote_ts = 172.16.0.0/16    # 阿里云目的路由模式对应的感兴趣流是0.0.0.0/0。
                mode = tunnel
                rekey_time = 85500
                life_time = 86400        # 指定隧道1SA生存周期,需与阿里云隧道1 IPsec配置中的SA生存周期保持一致。
                dpd_action = restart
                start_action = start
                close_action = start
                esp_proposals = aes-sha1-modp1024   # 指定隧道1的加密算法、认证算法、DH分组,需与阿里云隧道1 IPsec配置中的加密算法、认证算法、DH分组保持一致,group2对应的是modp1024。
             }
          }
       }
    
    }
    
    secrets {
       ike-vco1 {
          secret = ChangeMe***            # 指定隧道1的预共享密钥,需与阿里云隧道1的预共享密钥保持一致。
       }
    }
    
  4. 重启strongSwan进程

    systemctl restart strongswan
  5. 查看隧道状态

    watch swanctl --list-sas 

    image

    如图,strongSwan设备和VPN网关之间已经正常建立了IPsec-VPN连接。

5. 验证

验证strongSwan设备和VPC之间的连通性:

strongSwan设备ping阿里云VPC内的任意1ECS,如果能Ping通,则证明连通正常。

ping <VPC内1台ECS的地址>