All Products
Search
Document Center

VPN Gateway:Configure strongSwan

Last Updated:Mar 10, 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.

strongSwan is an open-source, IPsec-based VPN solution that runs on mainstream Linux distributions. It supports IKEv1/IKEv2 negotiation, route-based and policy-based traffic selectors, and BGP dynamic routing through XFRM virtual interfaces, making it a flexible choice for connecting on-premises networks to Alibaba Cloud.

The examples in this topic use the default dual-tunnel mode of a VPN Gateway instance. For more information, see What is an IPsec-VPN connection?. If your VPN Gateway instance supports only single-tunnel mode, see How do I configure a single tunnel? at the end of this topic.

Prerequisites

Before you begin, make sure that you have:

  • A VPN Gateway instance that supports dual-tunnel mode

  • A Linux device running CentOS Stream 9 (64-bit) or a compatible distribution

  • strongSwan 5.8.0 or later (required for XFRM virtual interfaces in dual-egress and BGP scenarios)

  • Linux kernel 4.19 or later with XFRM module support, and iproute2 5.1.0 or later (for XFRM-based configurations)

  • Network connectivity on UDP ports 500 and 4500, and ESP protocol (IP protocol 50) allowed through any intermediate firewalls

Scenario example

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

      For non-NAT scenarios, see How do I configure strongSwan when the network interface has a public IP address (non-NAT)?.
      You can establish a dual-tunnel IPsec-VPN connection with Alibaba Cloud from a device with either one public egress (single egress) or two public egresses (dual egress). This topic provides examples for both scenarios.

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.30.0/24

    • vSwitch 4 CIDR block: 192.168.40.0/24

    • vSwitch 5 CIDR block: 192.168.50.0/24

  • VPN Gateway

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

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

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

BGP IP addresses

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

The CIDR block of each tunnel under a VPN Gateway instance 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 planning

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***

Parameter

IKE

IPsec

Version / Mode

IKEv2 / main

-

Encryption algorithm

aes128

aes128

Authentication algorithm

sha1

sha1

DH group

group2 (modp1024)

group2 (modp1024)

SA lifetime (seconds)

86400

86400

The encryption parameters in this example (aes128-sha1-modp1024) are chosen for broad compatibility. For production environments, consider using stronger algorithms such as aes256-sha256-modp2048 or aes256gcm16-sha384-ecp384.

Prepare 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 Connect a VPC to an on-premises data center in dual-tunnel mode and use BGP routing. 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 Connect a VPC to an on-premises data center in dual-tunnel mode. 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 Connect a VPC to an on-premises data center in dual-tunnel mode and use BGP routing. 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 Connect a VPC to an on-premises data center in dual-tunnel mode. 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.

If an IPsec-VPN connection is associated with a Transit Router, use BGP dynamic routing. Static routing is not recommended for this scenario.

Configure the strongSwan device

The following steps use CentOS Stream 9 (64-bit) as an example. For other distributions, see the official strongSwan documentation.

1. Configure firewall policies

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
These iptables rules do not persist across reboots. To make them permanent, use iptables-save, firewall-cmd --permanent, or your distribution's preferred firewall management tool.

2. Enable traffic forwarding

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.

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

    echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
  2. Apply the configuration.

    sudo sysctl -p
  3. Verify that IP forwarding is enabled.

    cat /proc/sys/net/ipv4/ip_forward

    The output should be 1.

3. Install strongSwan

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

    XFRM interfaces do not persist across reboots. You must configure the following startup script so that the interfaces are automatically re-created and strongSwan is reloaded on every boot.

    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. Add the script path to /etc/rc.d/rc.local so it runs on startup. Replace /path/to/xfrm.sh with the actual path returned by the previous find command.

      echo '/path/to/xfrm.sh' | sudo tee -a /etc/rc.d/rc.local
    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 /path/to/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

    The following output confirms that the IPsec-VPN connection is established. However, network connectivity requires route configuration in the next step.

    IPsec-VPN tunnel established between strongSwan and VPN Gateway

  5. Configure routes.

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

    BGP dynamic routing

    The BGP IP addresses assigned to XFRM interfaces (ip address add) do not persist across reboots. Add these commands to the XFRM startup script described earlier. The FRR BGP configuration persists automatically after you run write memory in vtysh (see the last step below).
    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. Edit vi /etc/frr/daemons and set the bgpd parameter to yes to enable BGP.

      Edit the file, make the change, and save.

    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.

      The output confirms that the strongSwan device has learned VPC routes. The on-premises data center and VPC can now communicate.BGP routes learned from VPC

    7. Save the BGP configuration so that it persists across FRR restarts.

      write memory

    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 routes configured successfully

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

    XFRM interfaces do not persist across reboots. You must configure the following startup script so that the interfaces are automatically re-created and strongSwan is reloaded on every boot.

    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. Add the script path to /etc/rc.d/rc.local so it runs on startup. Replace /path/to/xfrm.sh with the actual path returned by the previous find command.

      echo '/path/to/xfrm.sh' | sudo tee -a /etc/rc.d/rc.local
    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 /path/to/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 {
            id = 47.XX.XX.151
            secret = ChangeMe***
         }
         ike-vco2 {
            id = 47.XX.XX.87
            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

    The following output confirms that the IPsec-VPN connection is established. Configure routes in the next step to enable network connectivity.

    Single-egress IPsec-VPN tunnel established

  4. Configure BGP dynamic routing.

    The BGP IP addresses assigned to XFRM interfaces (ip address add) do not persist across reboots. Add these commands to the XFRM startup script described earlier. The FRR BGP configuration persists automatically after you run write memory in vtysh (see the last step below).
    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. Edit vi /etc/frr/daemons and set the bgpd parameter to yes to enable BGP.

      Edit the file, make the change, and save.

    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.

      The output confirms that the strongSwan device has learned VPC routes. The on-premises data center and VPC can now communicate.BGP routes learned from VPC

    7. Save the BGP configuration so that it persists across FRR restarts.

      write memory

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. The following configuration is similar to the dual-egress example. Key differences: policy-based traffic selectors (local_ts/remote_ts) and priority for active/standby failover. 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

    The following output confirms that the IPsec-VPN connection is established. The on-premises data center and VPC can now communicate.

    Single-egress static routing tunnel established

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. Monitor ping traffic after interrupting the active tunnel. A brief interruption followed by recovery confirms that traffic automatically fails over to the standby tunnel.

FAQ

How do I configure strongSwan when the IPsec-VPN connection is associated with a Transit Router?

The strongSwan configuration is the same as described in this topic. Use BGP dynamic routing for Transit Router scenarios. After configuration, the strongSwan device learns VPC routes through BGP, and the two tunnels automatically form an Equal-Cost Multi-Path (ECMP) link.ECMP routes through Transit Router

Does strongSwan support IKEv1?

Yes. Set version = 1 in the /etc/strongswan/swanctl/swanctl.conf file.

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

Set the local_ts and remote_ts fields in /etc/strongswan/swanctl/swanctl.conf. Make sure Protected Data Flows mode is also configured 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)?

Change the local_addrs field for each tunnel in /etc/strongswan/swanctl/swanctl.conf to the public IP address. All other configurations remain the same.

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 troubleshoot tunnel negotiation failures?

Run journalctl -u strongswan -f or swanctl --log to view real-time negotiation logs. Common causes of negotiation failure include:

  • Pre-shared key mismatch between the strongSwan device and Alibaba Cloud

  • Algorithm mismatch (encryption, authentication, or DH group)

  • IKE version mismatch (IKEv1 vs. IKEv2)

  • Firewall blocking UDP port 500 or 4500, or ESP protocol (IP protocol 50)

Why is the tunnel established but traffic does not flow?

If swanctl --list-sas shows an established tunnel but ping fails, check the following:

  • Verify that IP forwarding is enabled: cat /proc/sys/net/ipv4/ip_forward (output should be 1)

  • Verify XFRM policies and state: ip xfrm policy and ip xfrm state

  • Verify the route table: ip route show

  • Verify that iptables FORWARD chain allows traffic: iptables -L FORWARD -n

How do I resolve frequent tunnel flapping (DPD timeouts)?

Dead Peer Detection (DPD) timeouts cause tunnel flapping when the network between endpoints is unstable. To mitigate this:

  • Increase dpd_delay (for example, from 10 to 30) in /etc/strongswan/swanctl/swanctl.conf to reduce sensitivity to transient packet loss

  • Make sure the DPD settings on both ends are compatible

  • Check network stability between endpoints (packet loss and latency) using mtr or ping -c 100

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 the IPsec-VPN connection to dual-tunnel mode. An IPsec-VPN connection in dual-tunnel mode supports zone-disaster recovery, which improves network high availability.

Single-tunnel configuration guide (for legacy VPN Gateway instances)

This section applies to VPN Gateway instances that support only single-tunnel IPsec-VPN connections. If your instance supports dual-tunnel mode, use the configuration described in the main sections above.

Single-tunnel configuration

Scenario example

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

    • vSwitch 3 CIDR block: 192.168.30.0/24

    • vSwitch 4 CIDR block: 192.168.40.0/24

    • vSwitch 5 CIDR block: 192.168.50.0/24

  • VPN Gateway

    • IPsec address: 47.XX.XX.151

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

VPN parameter planning

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

Pre-shared key: ChangeMe***

Parameter

IKE

IPsec

Version / Mode

IKEv2 / main

-

Encryption algorithm

aes128

aes128

Authentication algorithm

sha1

sha1

DH group

group2 (modp1024)

group2 (modp1024)

SA lifetime (seconds)

86400

86400

Prepare 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 Connect a VPC to an on-premises data center in 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

The following steps use CentOS Stream 9 (64-bit) as an example. For other distributions, see the official strongSwan documentation.

1. Configure firewall policies

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
These iptables rules do not persist across reboots. To make them permanent, use iptables-save, firewall-cmd --permanent, or your distribution's preferred firewall management tool.

2. Enable traffic forwarding

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.

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

    echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
  2. Apply the configuration.

    sudo sysctl -p
  3. Verify that IP forwarding is enabled.

    cat /proc/sys/net/ipv4/ip_forward

    The output should be 1.

3. Install strongSwan

dnf install epel-release -y
dnf install strongswan -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 {
          id = 47.XX.XX.151
          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 

    image

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

5. Verify connectivity

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>