All Products
Search
Document Center

VPN Gateway:Configure strongSwan

Last Updated:Sep 15, 2026

Deploy strongSwan on an on-premises Linux device to establish a dual-tunnel IPsec-VPN connection with Alibaba Cloud VPN Gateway for high-availability site-to-site communication.

Example scenario

The following figure shows a typical deployment. A strongSwan device on your on-premises network establishes a dual-tunnel IPsec-VPN connection with Alibaba Cloud, enabling communication between the VPC and your data center.

image

IP address planning

On-premises data center side

  • Private CIDR block: 172.16.0.0/16

  • strongSwan device

    • Network interface card eth0: 172.16.20.80, NAT-mapped public egress 1: 120.XX.XX.202

    • (Optional) Network interface card eth1: 172.16.21.248, NAT-mapped public egress 2: 47.XX.XX.127

      Note

      For a non-NAT scenario, see "How do I configure strongSwan when the network interface has a public IP address (non-NAT)?".

      Whether your device has one public network egress (single egress) or two public network egresses (dual egress), it can establish a dual-tunnel mode IPsec-VPN connection with Alibaba Cloud. This topic provides examples for both cases.

Alibaba Cloud side

  • VPC CIDR block: 192.168.0.0/16

    • vSwitch 1 CIDR block: 192.168.10.0/24

    • vSwitch 2 CIDR block: 192.168.20.0/24

    • vSwitch 3 CIDR block: 192.168.40.0/24

    • vSwitch 4 CIDR block: 192.168.50.0/24

    • vSwitch 5 CIDR block: 192.168.55.0/24

  • VPN Gateway

    • IPsec address 1: 47.XX.XX.151

    • IPsec address 2: 47.XX.XX.87

      Note

      After you create a VPN gateway instance, the system automatically assigns two IPsec addresses to the VPN gateway instance.

BGP IP address

This topic covers both static routing and Border Gateway Protocol (BGP) dynamic routing. Skip this section if you do not plan to use BGP. The following table lists the BGP CIDR block planning used in this topic.

Resource

Tunnel

BGP tunnel CIDR block

BGP IP address

BGP AS number

VPN Gateway

Tunnel 1

169.254.10.0/30

Note

Under a VPN gateway instance, the CIDR block of each tunnel must be unique.

169.254.10.1

65535

Tunnel 2

169.254.20.0/30

169.254.20.1

strongSwan device

Tunnel 1

169.254.10.0/30

169.254.10.2

65530

Tunnel 2

169.254.20.0/30

169.254.20.2

VPN parameter configuration plan

Both tunnels use the same parameter values in this example. For each tunnel, the IKE and IPsec configurations on the strongSwan device must match those on the Alibaba Cloud side.

  • Pre-shared key: ChangeMe***

  • IKE configuration

    • IKE version: ikev2

    • Negotiation mode: main

    • Encryption algorithm: aes

    • Authentication algorithm: sha1

    • DH group: group2

    • SA lifetime (seconds): 86400

  • IPsec configuration:

    • Encryption algorithm: aes

    • Authentication algorithm: sha1

    • DH group: group2

    • SA lifetime (seconds): 86400

Preparations on the Alibaba Cloud side

Complete the Alibaba Cloud configuration based on your number of public egresses and routing method. Select the tab that matches your scenario.

Dual egress-BGP dynamic routing

For more information, see Dual-tunnel mode with BGP. Complete the Create a VPN gateway, Create customer gateways, Create an IPsec-VPN connection, and Enable BGP dynamic routing steps.

  1. Because the strongSwan device has two public egress IP addresses, create two customer gateways.

  2. When you create the IPsec-VPN connection, associate Tunnel 1 with public egress 1 and Tunnel 2 with public egress 2. This example uses Destination Routing Mode.

Dual egress-static routing

For more information, see Standard VPN Gateway quick start. Complete the Create a VPN gateway, Create a customer gateway, Create an IPsec connection, and Configure VPN Gateway routes steps.

  1. Because the strongSwan device has two public egress IP addresses, create two customer gateways.

  2. When you create the IPsec-VPN connection, associate Tunnel 1 with public egress 1 and Tunnel 2 with public egress 2. This example uses Destination Routing Mode.

Single egress - BGP dynamic routing

For more information, see Dual-tunnel mode with BGP. Complete the Create a VPN gateway, Create customer gateways, Create an IPsec-VPN connection, and Enable BGP dynamic routing steps.

  1. The strongSwan device has one public egress IP address. Create one customer gateway.

  2. When you create the IPsec-VPN connection, associate both tunnels with the same customer gateway. This example uses Destination Routing Mode.

Single egress - static routing

For more information, see Standard VPN Gateway quick start. Complete the Create a VPN gateway, Create a customer gateway, Create an IPsec connection, and Configure VPN Gateway routes steps. Note the following points:

  1. The strongSwan device has one public egress IP address. Create one customer gateway.

  2. When you create the IPsec-VPN connection, select Protected Data Flows mode and associate both tunnels with the same customer gateway. Configure the following parameters:

    • Set Local Network to the CIDR block of the VPC on the Alibaba Cloud side, which is 192.168.0.0/16.

    • Set Remote Network to the private CIDR block of the on-premises data center, which is 172.16.0.0/16.

Note

For scenarios where the IPsec-VPN connection is associated with a transit router, we recommend that you use the BGP dynamic routing protocol. We do not recommend this method.

Start to configure the strongSwan device

Note

The following steps use a strongSwan device running "CentOS Stream 9 64-bit operating system" as an example. For other operating systems, see official strongSwan documentation.

1. Configure the firewall policy to allow traffic

Allow ESP protocol (IP protocol 50), UDP port 500, and UDP port 4500 on the strongSwan device.

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. Enable traffic forwarding

echo 1 > /proc/sys/net/ipv4/ip_forward
Important

Enable IP forwarding so that the strongSwan device can route traffic between the on-premises network and the VPC. The following command takes effect immediately and persists across reboots.

Click to view the permanent configuration.

  1. Add the forwarding configuration to /etc/sysctl.conf.

    vi /etc/sysctl.conf
  2. Verify that IP forwarding is enabled.

    net.ipv4.ip_forward = 1
  3. Apply the configuration.

    sudo sysctl -p

3. Install the strongSwan software

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

4. Configure dual tunnels

Dual egress - static routing and BGP dynamic routing

Important

Dual egress requires XFRM virtual network interfaces. Verify the following before you proceed: strongSwan 5.8.0 or later, Linux kernel 4.19 or later, iproute2 5.1.0 or later, and XFRM module support (run lsmod | grep xfrm to check). For more information, see XFRM Interfaces on Linux.

  1. Add routes so that traffic to IPsec address 1 goes through eth0 and traffic to IPsec address 2 goes through eth1.

    ip route add 47.XX.XX.151 via 172.16.20.253 dev eth0  # 172.16.20.253 is the private gateway address of eth0.
    ip route add 47.XX.XX.87 via 172.16.21.253 dev eth1   # 172.16.21.253 is the private gateway address of eth1.

    Verify connectivity to both IPsec addresses.

    ping 47.XX.XX.151 
    ping 47.XX.XX.87 
  2. Create two virtual network interfaces to establish the IPsec-VPN tunnels.

    ip link add ipsec0 type xfrm dev eth0 if_id 42 # Create an XFRM virtual network interface for Tunnel 1. The interface ID is 42 and the underlying interface is the public interface eth0.
    ip link add ipsec1 type xfrm dev eth1 if_id 43 # Create an XFRM virtual network interface for Tunnel 2. The interface ID is 43 and the underlying interface is the public interface eth1.
    ip link set ipsec0 up # Start the XFRM virtual network interface for Tunnel 1.
    ip link set ipsec1 up # Start the XFRM virtual network interface for Tunnel 2.
    Important

    The configuration for creating a virtual network interface is temporary. After the strongSwan device restarts, you need to add the configuration again and run the sudo systemctl restart strongswan;swanctl --load-all command (this command requires root permissions). You can refer to the following content to add a startup script to the strongSwan device, so that the virtual network interface is automatically added again after the strongSwan device restarts.

    Click to view the Startup script.

    1. Create a script file.

      vi xfrm.sh
    2. Add the following content and save the file.

      sudo ip link add ipsec0 type xfrm dev eth0 if_id 42 # Create an XFRM virtual network interface for Tunnel 1. The interface ID is 42 and the underlying interface is the public interface eth0.
      sudo ip link add ipsec1 type xfrm dev eth1 if_id 43 # Create an XFRM virtual network interface for Tunnel 2. The interface ID is 43 and the underlying interface is the public interface eth1.
      sudo ip link set ipsec0 up # Start the XFRM virtual network interface for Tunnel 1.
      sudo ip link set ipsec1 up # Start the XFRM virtual network interface for Tunnel 2.
    3. Find the absolute path of the script.

      sudo find / -name xfrm.sh
    4. Run the sudo vi /etc/rc.d/rc.local command to add the absolute path of the script to the /etc/rc.d/rc.local file.

      Press the i key to enter edit mode; add the absolute path of the script /root/xfrm.sh to the /etc/rc.d/rc.local file; press the Esc key to exit edit mode, and then enter :wq to save the configuration.

    5. Grant executable permissions to the rc.local file and the xfrm.sh script.

      sudo chmod +x /etc/rc.d/rc.local
      sudo chmod +x /root/xfrm.sh
  3. Modify the strongSwan configuration file.

    1. Back up the original strongSwan configuration file.

      mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak
    2. Create a new strongSwan configuration file.

      vi /etc/strongswan/swanctl/swanctl.conf
    3. Add the following configuration. Each parameter value must match the corresponding Alibaba Cloud tunnel configuration.

      Important

      For static routing, uncomment the updown = /root/connect_1.sh and updown = /root/connect_2.sh lines in the configuration.

      connections {
         vco1 {                            # Add the VPN configuration for IPsec-VPN Tunnel 1.
            version = 2                    # Specify the IKE version. It must be the same as the IKE version of Tunnel 1 on the Alibaba Cloud side. 2 indicates IKEv2.
            local_addrs  = 172.16.20.80       # The IP address of the first on-premises network interface card.
            remote_addrs = 47.XX.XX.151       # Specify the peer IP address of Tunnel 1 as the gateway IP address of Tunnel 1 on the Alibaba Cloud side, which is IPsec address 1.
            dpd_delay = 10
            rekey_time = 84600             # Specify the SA lifetime for Tunnel 1. It must be the same as the SA lifetime in the IKE configurations of Tunnel 1 on the Alibaba Cloud side.
            over_time = 1800               
            proposals = aes128-sha1-modp1024  # Specify the encryption algorithm, authentication algorithm, and DH group for Tunnel 1. They must be the same as those in the IKE configurations of Tunnel 1 on the Alibaba Cloud side. group2 corresponds to modp1024.
            encap = yes
      
            local {
               auth = psk                  # Set the authentication method for the on-premises side to PSK, which is the pre-shared key method.
               id = 120.XX.XX.202             # The first on-premises public egress IP address. It must be the same as the RemoteId of Tunnel 1 on the Alibaba Cloud side.
            }
            remote {
               auth = psk                  # Set the authentication method for the peer to PSK. This means Alibaba Cloud uses the pre-shared key method.
               id = 47.XX.XX.151             # IPsec address 1 on the Alibaba Cloud side. It must be the same as the LocalId of Tunnel 1 on the Alibaba Cloud side.
            }
            children {
               vco_child1 {
                  local_ts  = 0.0.0.0/0    # The policy-based traffic selector for the destination-based routing mode on Alibaba Cloud is 0.0.0.0/0.
                  remote_ts = 0.0.0.0/0    # The policy-based traffic selector for the destination-based routing mode on Alibaba Cloud is 0.0.0.0/0.
                  mode = tunnel
                  rekey_time = 85500
                  life_time = 86400        # Specify the SA lifetime for Tunnel 1. It must be the same as the SA lifetime in the IPsec configurations of Tunnel 1 on the Alibaba Cloud side.
                  dpd_action = restart
                  start_action = start
                  close_action = start
                  esp_proposals = aes128-sha1-modp1024   # Specify the encryption algorithm, authentication algorithm, and DH group for Tunnel 1. They must be the same as those in the IPsec configurations of Tunnel 1 on the Alibaba Cloud side. group2 corresponds to modp1024.
      
                  if_id_out = 42           # Specify the egress and ingress interfaces for Tunnel 1 as the XFRM virtual network interface of Tunnel 1.
                  if_id_in = 42
                  #updown = /root/connect_1.sh         # Execute the /root/connect_1.sh script to configure routes based on the UP and DOWN status of Tunnel 1. This parameter is required only when you use static routing.
               }
            }
         }
        vco2 {                             # Add the VPN configuration for IPsec-VPN Tunnel 2.
            version = 2                    # Specify the IKE version. It must be the same as the IKE version of Tunnel 2 on the Alibaba Cloud side. 2 indicates IKEv2.
            local_addrs  = 172.16.21.248        # The IP address of the second on-premises network interface card.
            remote_addrs = 47.XX.XX.87       # IPsec address 2 on the Alibaba Cloud side.
            dpd_delay = 10
            rekey_time = 84600             # SA lifetime. Must match Tunnel 2 IKE configurations.
            over_time = 1800               # 
            proposals = aes128-sha1-modp1024  # group2 = modp1024. Must match Tunnel 2 IKE configurations.
            encap = yes
      
            local {
               auth = psk                  # Pre-shared key authentication.
               id = 47.XX.XX.127              # Second on-premises public egress IP. Must match RemoteId of Tunnel 2.
            }
            remote {
               auth = psk                  # Set the authentication method for the peer to PSK. This means Alibaba Cloud uses the pre-shared key method.
               id = 47.XX.XX.87             # IPsec address 2 on the Alibaba Cloud side. It must be the same as the LocalId of Tunnel 2 on the Alibaba Cloud side.
            }
            children {
               vco_child2 {
                  local_ts  = 0.0.0.0/0    # The policy-based traffic selector for the destination-based routing mode on Alibaba Cloud is 0.0.0.0/0.
                  remote_ts = 0.0.0.0/0    # The policy-based traffic selector for the destination-based routing mode on Alibaba Cloud is 0.0.0.0/0.
                  mode = tunnel 
                  rekey_time = 85500
                  life_time = 86400        # Specify the SA lifetime for Tunnel 2. It must be the same as the SA lifetime in the IPsec configurations of Tunnel 2 on the Alibaba Cloud side.
                  dpd_action = restart
                  start_action = start
                  close_action = start
                  esp_proposals = aes128-sha1-modp1024     # Specify the encryption algorithm, authentication algorithm, and DH group for Tunnel 2. They must be the same as those in the IPsec configurations of Tunnel 2 on the Alibaba Cloud side. group2 corresponds to modp1024.
                  if_id_out = 43           # Specify the egress and ingress interfaces for Tunnel 2 as the XFRM virtual network interface of Tunnel 2.
                  if_id_in = 43
                  #updown = /root/connect_2.sh           # Execute the /root/connect_2.sh script to configure routes based on the UP and DOWN status of Tunnel 2. This parameter is required only when you use static routing.
               }
            }
         }
      }
      
      secrets {
         ike-vco1 {
            id = 47.XX.XX.151               # The public IP address of Tunnel 1 of the VPN gateway on the Alibaba Cloud side.
            secret = ChangeMe***            # Specify the pre-shared key for Tunnel 1. The key must be the same as the pre-shared key of Tunnel 1 on the Alibaba Cloud side.
         }
         ike-vco2 {
            id = 47.XX.XX.87                # The public IP address of Tunnel 2 of the VPN gateway on the Alibaba Cloud side.
            secret = ChangeMe***            # Specify the pre-shared key for Tunnel 2. The key must be the same as the pre-shared key of Tunnel 2 on the Alibaba Cloud side.
         }
      }
  4. Restart the strongSwan process, reload the strongSwan configuration, and check the tunnel status.

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

    As shown below, if the status after both vco1 and vco2 is ESTABLISHED, the IPsec-VPN connection between the strongSwan device and the VPN gateway has been established successfully. However, the networks still cannot communicate normally, and you need to configure routes.

    plugin 'sqlite': failed to load - sqlite_plugin_create not found and no plugin file available
    vco2: #4, ESTABLISHED, IKEv2, 2d3fbef28a433cfd_i 3f1960ea7d80a293_r*
       local  '47.___.127' @ ___[4500]
       remote '47.__ __87' @ ___
       AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
       established 3424s ago, rekeying in 79868s
       vco_child2: #4, reqid 2, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
          installed 3424s ago, rekeying in 81353s, expires in 82976s
          in  c7f56760 (-|0x0000002b),  16396 bytes,   245 packets,   47s ago
          out 2b09776f (-|0x0000002b),   9621 bytes,   149 packets,   47s ago
          local  0.0.0.0/0
          remote 0.0.0.0/0
    vco1: #1, ESTABLISHED, IKEv2, 96ccc381f9e7693e_i* d1a7dec1832e5cb6_r
       local  '120.___.202' @ ___
       remote '47.__ ___.151' @ ___
       AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
       established 3447s ago, rekeying in 79436s
       vco_child1: #1, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
          installed 3447s ago, rekeying in 81457s, expires in 82953s
          in  c8f4286f (-|0x0000002a),  16127 bytes,   239 packets,   43s ago
          out f5bccc3d (-|0x0000002a),   9828 bytes,   152 packets,   43s ago
          local  0.0.0.0/0
    

  5. Configure routes.

    Refer to the section for the routing method that you plan to use.

    BGP dynamic routing

    Note

    After the strongSwan device restarts, you need to add the BGP configuration again.

    1. Configure the BGP IP addresses on the XFRM interfaces.

      ip address add 169.254.10.2/30 dev ipsec0
      ip address add 169.254.20.2/30 dev ipsec1
    2. Install FRR (Free Range Routing) for BGP support.

      yum install -y frr
    3. Run the vi /etc/frr/daemons command to edit the configuration file and enable BGP dynamic routing.

      Press the i key to enter edit mode; change the value of the bgpd parameter to yes to enable BGP dynamic routing; press the Esc key to exit edit mode, and then enter :wq to save the configuration.

    4. Enable and start FRR.

      systemctl enable frr
      systemctl restart frr
    5. Add the BGP configuration. Replace the IP addresses and AS numbers with your actual values.

      1. Enter the FRR configuration interface.

        vtysh
      2. Enter configuration mode.

        config terminal
      3. Add the BGP configuration with the following commands.

        Replace the following values with your actual addresses:

        • Replace "169.254.10.1" and "169.254.20.1" with the actual BGP IP addresses of the tunnels on the Alibaba Cloud side.

        • Replace "65535" with the actual BGP AS number of the VPN Gateway.

        • Replace "172.16.20.0/24" and "172.16.21.0/24" with the actual CIDR blocks of your on-premises data center.

        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. Run exit to leave configuration mode, then run show ip bgp to view the BGP routes.

      You can see that the strongSwan device has successfully learned the routes of the VPC on the cloud, and the on-premises data center and the VPC on the cloud can communicate normally.

           Network          Next Hop            Metric LocPrf    Weight Path
      *>  172.16.20.0/24   0.0.0.0                  0             32768 i
      *>  172.16.21.0/24   0.0.0.0                  0             32768 i
      *   192.168.10.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      *   192.168.20.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      *   192.168.40.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      *   192.168.50.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      *   192.168.55.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      

    Static routing

    Create two scripts that strongSwan calls to configure routes and control traffic flow.

    1. Create and edit the /root/connect_1.sh script.

      vi /root/connect_1.sh
    2. Add and save the following content.

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

      This script adds a route for traffic from the on-premises data center to the Alibaba Cloud VPC (192.168.0.0/16) through the XFRM virtual network interface of Tunnel 1 when the tunnel is up. The metric value of this route is set to 100, which gives it a higher priority than the route for Tunnel 2. If Tunnel 1 is down, the script revokes the route.

    3. Create and edit the /root/connect_2.sh script.

      vi /root/connect_2.sh
    4. Add and save the following content.

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

      This script adds a route for traffic from the on-premises data center to the Alibaba Cloud VPC (192.168.0.0/16) through the XFRM virtual network interface of Tunnel 2 when the tunnel is up. The metric value of this route is set to 101, which gives it a lower priority than the route for Tunnel 1. If Tunnel 2 is down, the script revokes the route.

    5. Grant executable permissions to the two scripts.

      sudo chmod +x /root/connect_1.sh
      sudo chmod +x /root/connect_2.sh
    6. Restart the strongSwan process.

      sudo systemctl restart strongswan
    7. Verify the routes.

      route -n

      Static routing

Single egress - BGP dynamic routing

Important

BGP dynamic routing requires XFRM virtual network interfaces. Verify the following: strongSwan 5.8.0 or later, Linux kernel 4.19 or later, iproute2 5.1.0 or later, and XFRM module support (run lsmod | grep xfrm to check). For more information, see XFRM Interfaces on Linux.

  1. Create two virtual network interfaces to establish the IPsec-VPN tunnels.

    ip link add ipsec0 type xfrm dev eth0 if_id 42 # Create an XFRM virtual network interface for Tunnel 1. The interface ID is 42 and the underlying interface is the public interface eth0.
    ip link add ipsec1 type xfrm dev eth0 if_id 43 # Create an XFRM virtual network interface for Tunnel 2. The interface ID is 43 and the underlying interface is the public interface eth0.
    ip link set ipsec0 up # Start the XFRM virtual network interface for Tunnel 1.
    ip link set ipsec1 up # Start the XFRM virtual network interface for Tunnel 2.
    Important

    The configuration for creating a virtual network interface is temporary. After the strongSwan device restarts, you need to add the configuration again and run the sudo systemctl restart strongswan;swanctl --load-all command (this command requires root permissions). You can refer to the following content to add a startup script to the strongSwan device, so that the virtual network interface is automatically added again after the strongSwan device restarts.

    Click to view the Startup script.

    1. Create a script file.

      vi xfrm.sh
    2. Add and save the following configuration.

      sudo ip link add ipsec0 type xfrm dev eth0 if_id 42 # Create an XFRM virtual network interface for Tunnel 1. The interface ID is 42 and the underlying interface is the public interface eth0.
      sudo ip link add ipsec1 type xfrm dev eth0 if_id 43 # Create an XFRM virtual network interface for Tunnel 2. The interface ID is 43 and the underlying interface is the public interface eth0.
      sudo ip link set ipsec0 up # Start the XFRM virtual network interface for Tunnel 1.
      sudo ip link set ipsec1 up # Start the XFRM virtual network interface for Tunnel 2.
    3. Find the absolute path of the script.

      sudo find / -name xfrm.sh
    4. Run the sudo vi /etc/rc.d/rc.local command to add the absolute path of the script to the /etc/rc.d/rc.local file.

      Press the i key to enter edit mode; add the absolute path of the script /root/xfrm.sh to the /etc/rc.d/rc.local file; press the Esc key to exit edit mode, and then enter :wq to save the configuration.

    5. Grant executable permissions to the rc.local file and the xfrm.sh script.

      sudo chmod +x /etc/rc.d/rc.local
      sudo chmod +x /root/xfrm.sh
  2. Modify the strongSwan configuration file.

    1. Back up the original strongSwan configuration file.

      mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak
    2. Create a new strongSwan configuration file.

      vi /etc/strongswan/swanctl/swanctl.conf
    3. The following configuration is similar to the dual-egress example. Only the differences are annotated. Add and save the following configuration.

      connections {
         vco1 {
            version = 2
            local_addrs  = 172.16.20.80    # Both tunnels use the same eth0 interface (single egress).
            remote_addrs = 47.XX.XX.151
            dpd_delay = 10
            rekey_time = 84600
            over_time = 1800               
            proposals = aes128-sha1-modp1024
            encap = yes
      
            local {
               auth = psk
               id = 120.XX.XX.202
            }
            remote {
               auth = psk
               id = 47.XX.XX.151
            }
            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
                  dpd_action = restart
                  start_action = start
                  close_action = start
                  esp_proposals = aes128-sha1-modp1024
      
                  if_id_out = 42
                  if_id_in = 42
               }
            }
         }
        vco2 {
            version = 2
            local_addrs  = 172.16.20.80    # Same as vco1 (single egress).
            remote_addrs = 47.XX.XX.87
            dpd_delay = 10
            rekey_time = 84600
            over_time = 1800               # 
            proposals = aes128-sha1-modp1024
            encap = yes
      
            local {
               auth = psk
               id = 120.XX.XX.202          # Same public egress IP as vco1 (single egress).
            }
            remote {
               auth = psk
               id = 47.XX.XX.87
            }
            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
                  dpd_action = restart
                  start_action = start
                  close_action = start
                  esp_proposals = aes128-sha1-modp1024
                  if_id_out = 43
                  if_id_in = 43
                
               }
            }
         }
      }
      
      secrets {
         ike-vco1 {
            secret = ChangeMe***
         }
         }
         ike-vco2 {
            secret = ChangeMe***
         }
         }
      }
  3. Restart the strongSwan process, reload the strongSwan configuration, and check the tunnel status.

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

    As shown in the following output, if the status after both vco1 and vco2 is ESTABLISHED, the IPsec-VPN connection between the strongSwan device and the VPN gateway has been established successfully. However, the networks still cannot communicate normally, and you need to configure routes.

    plugin 'sqlite': failed to load - sqlite_plugin_create not found and no plugin file available
    vco2: #5, ESTABLISHED, IKEv2, e9cf2986f8fdcb37_i 6be3688815c6a80f_r*
       local  '120.___.202' @ 172.___[4500]
       remote '47.___.87' @ 47.___[4500]
       AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
       established 1096s ago, rekeying in 82251s
       vco_child2: #5, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
          installed 1096s ago, rekeying in 83517s, expires in 85304s
          in  cbc4e224,      0 bytes,      0 packets
          out 064a42f5,      0 bytes,      0 packets
          local  172.16.0.0/16
          remote 192.168.0.0/16
    vco1: #1, ESTABLISHED, IKEv2, 387cbee015ffc74b_i* 70f63f78844ef7de_r
       local  '120.___.202' @ 172.___
       remote '47.___.151' @ 47.___[4500]
       AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
       established 1128s ago, rekeying in 82830s
       vco_child1: #1, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
          installed 1128s ago, rekeying in 83970s, expires in 85272s
          in  cd130507,      0 bytes,      0 packets
          out 6436d869,      0 bytes,      0 packets
          local  172.16.0.0/16
          remote 192.168.0.0/16
    

  4. Configure BGP dynamic routing.

    Note

    After the strongSwan device restarts, you need to add the BGP configuration again.

    1. Configure the BGP IP addresses on the XFRM interfaces.

      ip address add 169.254.10.2/30 dev ipsec0
      ip address add 169.254.20.2/30 dev ipsec1
    2. Install FRR (Free Range Routing) for BGP support.

      yum install -y frr
    3. Run the vi /etc/frr/daemons command to edit the configuration file and enable BGP dynamic routing.

      Press the i key to enter edit mode; change the value of the bgpd parameter to yes to enable BGP dynamic routing; press the Esc key to exit edit mode, and then enter :wq to save the configuration.

    4. Enable and start FRR.

      systemctl enable frr
      systemctl restart frr
    5. Add the BGP configuration. Replace the IP addresses and AS numbers with your actual values.

      1. Enter the FRR configuration interface.

        vtysh
      2. Enter configuration mode.

        config terminal
      3. Add the BGP configuration with the following commands.

        Replace the following values with your actual addresses:

        • Replace "169.254.10.1" and "169.254.20.1" with the actual BGP IP addresses of the tunnels on the Alibaba Cloud side.

        • Replace "65535" with the actual BGP AS number of the VPN Gateway.

        • Replace "172.16.20.0/24" and "172.16.21.0/24" with the actual CIDR blocks of your on-premises data center.

        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. Run exit to leave configuration mode, then run show ip bgp to view the BGP routes.

      You can see that the strongSwan device has successfully learned the routes of the VPC on the cloud, and the on-premises data center and the VPC on the cloud can communicate normally.

           Network          Next Hop            Metric LocPrf    Weight Path
      *>  172.16.20.0/24   0.0.0.0                  0             32768 i
      *>  172.16.21.0/24   0.0.0.0                  0             32768 i
      *   192.168.10.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      *   192.168.20.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      *   192.168.40.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      *   192.168.50.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      *   192.168.55.0/24  169.254.20.1           200                 0 65535 i
      *>                   169.254.10.1           100                 0 65535 i
      

Single egress - static routing

Important

In single-egress static routing mode, Alibaba Cloud may proactively switch traffic to the standby tunnel if it detects a threat in the active tunnel. Monitor the XfrmInTmplMismatch counter in /proc/net/xfrm_stat. If this value keeps increasing, traffic has been switched. Adjust the priority parameter for the standby tunnel in /etc/strongswan/swanctl/swanctl.conf to route on-premises traffic through the standby tunnel.

  1. Back up the original strongSwan configuration file.

    mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak
  2. Create a new strongSwan configuration file.

    vi /etc/strongswan/swanctl/swanctl.conf
  3. Based on the plan in Example scenario, add and save the following configuration.

    connections {
       vco1 {
          version = 2
          local_addrs  = 172.16.20.80
          remote_addrs = 47.XX.XX.151
          dpd_delay = 10
          rekey_time = 84600
          over_time = 1800               
          proposals = aes128-sha1-modp1024
          encap = yes
    
          local {
             auth = psk
             id = 120.XX.XX.202
          }
          remote {
             auth = psk
             id = 47.XX.XX.151
          }
          children {
             vco_child1 {
                local_ts  = 172.16.0.0/16   # Policy-based: on-premises private CIDR block.
                remote_ts = 192.168.0.0/16  # Policy-based: VPC CIDR block.
                mode = tunnel
                rekey_time = 85500
                life_time = 86400
                dpd_action = restart
                start_action = start
                close_action = start
                esp_proposals = aes128-sha1-modp1024
                priority = 1                # Active tunnel (higher priority).
             }
          }
       }
      vco2 {
          version = 2
          local_addrs  = 172.16.20.80
          remote_addrs = 47.XX.XX.87
          dpd_delay = 10
          rekey_time = 84600
          over_time = 1800               
          proposals = aes128-sha1-modp1024
          encap = yes
    
          local {
             auth = psk
             id = 120.XX.XX.202
          }
          remote {
             auth = psk
             id = 47.XX.XX.87
          }
          children {
             vco_child2 {
                local_ts  = 172.16.0.0/16   # Policy-based: on-premises private CIDR block.
                remote_ts = 192.168.0.0/16  # Policy-based: VPC CIDR block.
                mode = tunnel 
                rekey_time = 85500
                life_time = 86400
                dpd_action = restart
                start_action = start
                close_action = start
                esp_proposals = aes128-sha1-modp1024
                priority = 2                # Standby tunnel (lower priority).
             }
          }
       }
    }
    
    secrets {
       ike-vco1 {
          id = 47.XX.XX.151
          secret = ChangeMe***
       }
       ike-vco2 {
          id = 47.XX.XX.87
          secret = ChangeMe***
       }
    }
  4. Restart the strongSwan process, reload the strongSwan configuration, and check the tunnel status.

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

    As shown in the following output, if the status after both vco1 and vco2 is ESTABLISHED, the IPsec-VPN connection between the strongSwan device and the VPN gateway has been established successfully, and the on-premises data center and the VPC can communicate with each other.

    plugin 'sqlite': failed to load - sqlite_plugin_create not found and no plugin file available
    vco2: #5, ESTABLISHED, IKEv2, e9cf2986f8fdcb37_i 6be3688815c6a80f_r*
       local  '120.___.202' @ 172.___[4500]
       remote '47.___.87' @ 47.___[4500]
       AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
       established 1096s ago, rekeying in 82251s
       vco_child2: #5, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
          installed 1096s ago, rekeying in 83517s, expires in 85304s
          in  cbc4e224,      0 bytes,      0 packets
          out 064a42f5,      0 bytes,      0 packets
          local  172.16.0.0/16
          remote 192.168.0.0/16
    vco1: #1, ESTABLISHED, IKEv2, 387cbee015ffc74b_i* 70f63f78844ef7de_r
       local  '120.___.202' @ 172.___
       remote '47.___.151' @ 47.___[4500]
       AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
       established 1128s ago, rekeying in 82830s
       vco_child1: #1, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
          installed 1128s ago, rekeying in 83970s, expires in 85272s
          in  cd130507,      0 bytes,      0 packets
          out 6436d869,      0 bytes,      0 packets
          local  172.16.0.0/16
          remote 192.168.0.0/16

5. Verify connectivity and high availability

  1. Verify connectivity between the on-premises data center and the VPC.

    From a client in the on-premises data center, ping an ECS instance in the VPC. Echo reply packets confirm a successful connection.

    ping <IP_address_of_an_ECS_instance_in_the_VPC>
  2. Verify high availability of the IPsec-VPN connection.

    1. While ping is running, interrupt the active tunnel.

      One way to interrupt the tunnel is to change its pre-shared key so that the keys on both ends no longer match.

    2. After you interrupt the primary tunnel, you can run the ping command to observe the connectivity between the two sides. You will find that the ping traffic is briefly interrupted and then resumes communication. This indicates that after the primary tunnel is interrupted, traffic automatically communicates through the secondary tunnel.

FAQ

How do I configure a strongSwan device when the IPsec-VPN connection is associated with a transit router?

When the IPsec-VPN connection is associated with a transit router, the configuration on the strongSwan device side is the same as described above. We recommend that you use the BGP dynamic routing protocol. After the configuration is complete, you can see the VPC-side routes learned through the BGP dynamic routing protocol on the strongSwan device, and the two tunnels of the IPsec-VPN connection automatically form an ECMP link.

As shown below, after you enter the show ip bgp command, = multipath indicates multipath. You can see that the status to the left of 192.168.10.0/24 is an equal sign, indicating a multipath candidate.

*********Z# show ip bgp
BGP table version is 42, local router ID is 169.254.13.2, vrf id 0
Default local pref 100, local AS 65530
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf    Weight Path
*>  172.16.20.0/24   0.0.0.0                  0             32768 i
*>  172.16.21.0/24   0.0.0.0                  0             32768 i
*=  192.168.10.0/24  169.254.20.1             0                 0 65535 i
*>                   169.254.10.1             0                 0 65535 i
*=  192.168.20.0/24  169.254.20.1             0                 0 65535 i
*>                   169.254.10.1             0                 0 65535 i
*=  192.168.40.0/24  169.254.20.1             0                 0 65535 i
*>                   169.254.10.1             0                 0 65535 i
*=  192.168.50.0/24  169.254.20.1             0                 0 65535 i
*>                   169.254.10.1             0                 0 65535 i
*=  192.168.55.0/24  169.254.20.1             0                 0 65535 i
*>                   169.254.10.1             0                 0 65535 i

Does strongSwan support IKEv1?

Supported.

When you configure the /etc/strongswan/swanctl/swanctl.conf file, specify version = 1.

How do I specify Protected Data Flows (streams of interest)?

When you configure the /etc/strongswan/swanctl/swanctl.conf file, specify the specific CIDR block in the following configuration. Make sure that the Traffic Selector mode is also configured for the IPsec-VPN connection on the Alibaba Cloud side.

To specify multiple CIDR blocks on either side, both the strongSwan device and the Alibaba Cloud IPsec-VPN connection must use IKEv2.

children {
         vco_child1 {
            local_ts  = 172.16.20.0/24,172.16.21.0/24  # The CIDR blocks of the on-premises data center.
            remote_ts = 192.168.0.0/16    # The CIDR block of the VPC on the Alibaba Cloud side.
         }
}

How do I configure strongSwan when the network interface has a public IP address (non-NAT)?

For a non-NAT scenario, that is, the address visible inside the strongSwan device is a public IP address, you only need to change the local_addrs field of each tunnel in the /etc/strongswan/swanctl/swanctl.conf configuration file to the public IP address. Keep the other configurations unchanged.

connections {
   vco1 {                            
      local_addrs  = 1.1.XX.XX     # Specify the public IP address that is bound to the network interface card of the strongSwan device.
   }
}

How do I configure a single tunnel?

Important

If the VPN Gateway that you purchased supports only single-tunnel IPsec-VPN connections, we recommend that you Upgrade VPN Gateway to dual-tunnel mode. An IPsec-VPN connection in dual-tunnel mode supports zone-disaster recovery, which improves network high availability.

Click here to view a single-tunnel configuration example

Single-tunnel configuration example

Example scenario

The following figure shows a single-tunnel deployment where a strongSwan device establishes an IPsec-VPN connection with Alibaba Cloud.

image

IP address planning

On-premises data center side

Alibaba Cloud side

  • VPC CIDR block: 192.168.0.0/16

    • vSwitch 1 CIDR block: 192.168.10.0/24

    • vSwitch 2 CIDR block: 192.168.20.0/24

  • VPN Gateway

    • IPsec address: 47.XX.XX.151

      Note

      After you create a VPN gateway instance, the system automatically assigns an IPsec address to the VPN gateway instance.

VPN parameter configuration plan

The IKE and IPsec configurations on the strongSwan device must match those on the Alibaba Cloud side.

  • Pre-shared key: ChangeMe***

  • IKE configuration

    • IKE version: ikev2

    • Negotiation mode: main

    • Encryption algorithm: aes

    • Authentication algorithm: sha1

    • DH group: group2

    • SA lifetime (seconds): 86400

  • IPsec configuration:

    • Encryption algorithm: aes

    • Authentication algorithm: sha1

    • DH group: group2

    • SA lifetime (seconds): 86400

Preparations on the Alibaba Cloud side

Before configuring the strongSwan device, complete the following on the Alibaba Cloud side: Create a VPN gateway, Create a customer gateway, Create an IPsec-VPN connection, and Configure routes for the VPN gateway. For more information, see Single-tunnel mode.

When you create the IPsec-VPN connection, set Routing Mode to Protected Data Flows:

  • Set Local Network to the CIDR block of the VPC on the Alibaba Cloud side, which is 192.168.0.0/16.

  • Set Remote Network to the private CIDR block of the on-premises data center, which is 172.16.0.0/16.

Configure the strongSwan device

Note

The following steps use a strongSwan device running "CentOS Stream 9 64-bit operating system" as an example. For other operating systems, see official strongSwan documentation.

1. Configure the firewall policy to allow traffic

Allow ESP protocol (IP protocol 50), UDP port 500, and UDP port 4500 on the strongSwan device.

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. Enable traffic forwarding

echo 1 > /proc/sys/net/ipv4/ip_forward
Important

Enable IP forwarding so that the strongSwan device can route traffic between the on-premises network and the VPC. The following command takes effect immediately and persists across reboots.

Click to view the permanent configuration.

  1. Add the forwarding configuration to /etc/sysctl.conf.

    vi /etc/sysctl.conf
  2. Verify that IP forwarding is enabled.

    net.ipv4.ip_forward = 1
  3. Apply the configuration.

    sudo sysctl -p

3. Install the strongSwan software

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

4. Configure the tunnel

Configure the tunnel based on strongSwan policy-based traffic selectors.

  1. Back up the original strongSwan configuration file.

    mv /etc/strongswan/swanctl/swanctl.conf /etc/strongswan/swanctl/swanctl.conf.bak
  2. Create a new strongSwan configuration file.

    vi /etc/strongswan/swanctl/swanctl.conf
  3. The following configuration is similar to the dual-tunnel examples. Key differences: single connection, policy-based traffic selectors, and no XFRM interfaces. Add and save the following configuration.

    connections {
       vco1 {
          version = 2
          local_addrs  = 172.16.20.80      # On-premises private IP address.
          remote_addrs = 47.XX.XX.151      # IPsec address on the Alibaba Cloud side.
          dpd_delay = 10
          rekey_time = 84600
          over_time = 1800               
          proposals = aes128-sha1-modp1024
          encap = yes
    
          local {
             auth = psk
             id = 120.XX.XX.202            # On-premises public egress IP (NAT-mapped).
          }
          remote {
             auth = psk
             id = 47.XX.XX.151
          }
          children {
             vco_child1 {
                local_ts  = 172.16.0.0/16     # Policy-based: on-premises private CIDR block.
                remote_ts = 192.168.0.0/16    # Policy-based: VPC CIDR block.
                mode = tunnel
                rekey_time = 85500
                life_time = 86400
                dpd_action = restart
                start_action = start
                close_action = start
                esp_proposals = aes128-sha1-modp1024
             }
          }
       }
    
    }
    
    secrets {
       ike-vco1 {
          secret = ChangeMe***
       }
       }
    }
    
  4. Restart the strongSwan process and reload the strongSwan configuration.

    systemctl restart strongswan
    swanctl --load-all
  5. Check the tunnel status.

    watch swanctl --list-sas 

    As shown in the following output, if the status after vco1 is ESTABLISHED, the IPsec-VPN connection between the strongSwan device and the VPN gateway has been established normally.

    Every 2.0s: swanctl --list-sas
    
    plugin 'sqlite': failed to load - sqlite_plugin_create not found and no plugin file available
    vco1: #1, ESTABLISHED, IKEv2, 76231680bedc2279_i* 5c1e6354830e3df7_r
       local  '11.___' @ 10.0.0.1[4500]
       remote '3.3.___' @ 3.3.___[4500]
       AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
       established 3041s ago, rekeying in 81142s
       vco_child1: #1, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
          installed 3041s ago, rekeying in 81881s, expires in 83359s
          in  ca0e6ace, 255276 bytes,  3039 packets,      0s ago
          out c7a8b4c2, 255276 bytes,  3039 packets,      0s ago
          local  10.0.0.0/16
          remote 172.16.0.0/16

    As shown in the figure, an IPsec-VPN connection is successfully established between the strongSwan device and the VPN gateway.

5. Verify

Verify connectivity between the strongSwan device and the VPC:

From the strongSwan device, ping an ECS instance in the VPC. Echo reply packets confirm a successful connection.

ping <IP_address_of_an_ECS_instance_in_the_VPC>