Setting up IPsec VPN with StrongSwan and Swanctl on OpenWrt

Setting up IPsec VPN with StrongSwan and Swanctl on OpenWrt

In this guide, we'll detail the process of establishing an IPsec VPN tunnel using StrongSwan with Swanctl on OpenWrt. Specifically, OpenWrt operates on the Panther X2 device as the client-side, while StrongSwan runs on Ubuntu as the server-side. Follow these steps carefully to configure your VPN:

1. Adding XFRM Interface

Edit the network configuration file /etc/config/network to add the XFRM interface:

config interface 'xfrm0'
        option ifid '301'
        option tunlink 'lan'
        option mtu '1300'
        option proto 'xfrm'
br-lan    Link encap:Ethernet  HWaddr 92:01:0A:61:81:70
          inet addr:192.168.80.79  Bcast:192.168.80.255  Mask:255.255.255.0
          inet6 addr: fdaa:fb8:a8b1::a14/128 Scope:Global
          inet6 addr: fe80::9001:aff:fe61:8170/64 Scope:Link
          inet6 addr: fdaa:fb8:a8b1:0:9001:aff:fe61:8170/64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6585 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4768 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2594168 (2.4 MiB)  TX bytes:3503460 (3.3 MiB)

eth0      Link encap:Ethernet  HWaddr 92:01:0A:61:81:70
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9320 errors:0 dropped:7 overruns:0 frame:0
          TX packets:6352 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2978257 (2.8 MiB)  TX bytes:3890528 (3.7 MiB)
          Interrupt:41

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:532 errors:0 dropped:0 overruns:0 frame:0
          TX packets:532 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:63682 (62.1 KiB)  TX bytes:63682 (62.1 KiB)

xfrm0     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet6 addr: fe80::c825:ec99:d5a7:9120/64 Scope:Link
          UP RUNNING NOARP MULTICAST  MTU:1438  Metric:1
          RX packets:1475 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1507 errors:0 dropped:22 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:123900 (120.9 KiB)  TX bytes:126588 (123.6 KiB)

2. Configuring IPsec

Modify the IPsec configuration file /etc/config/ipsec with your VPN settings:

config crypto_proposal 'ike1'
        option dh_group 'modp1024'
        option prf_algorithm 'prfsha256'
        option encryption_algorithm 'aes128'
        option hash_algorithm 'sha256'

config crypto_proposal 'ike2'
        option is_esp '1'
        option dh_group 'modp1024'
        option encryption_algorithm 'aes128'
        option hash_algorithm 'sha256'

config tunnel 'site2site'
        option startaction 'start'
        option closeaction 'start'
        list crypto_proposal 'ike2'
        option dpdaction 'start'
        option if_id '301'
        list local_subnet '0.0.0.0/0'
        list remote_subnet '0.0.0.0/0'

config remote 'panther'
        option enabled '1'
        option gateway 'your server ip'
        option local_gateway '192.168.80.79'
        option local_sourceip '192.168.80.79'
        list crypto_proposal 'ike1'
        list tunnel 'site2site'
        option authentication_method 'psk'
        option pre_shared_key '0sFpZAZqEN6Ti9sqt4ZP5EWcqx'
        option fragmentation 'yes'
        option keyingretries '3'
        option dpddelay '30s'
        option keyexchange 'ikev2'

3. Swanctl Configuration

/etc/init.d/swanctl start

/var/swanctl/swanctl.conf file content is

connections {
  panther {
    local_addrs = %any
    remote_addrs = your_server_ip
    fragmentation = yes
    local {
      auth = psk
    }
    remote {
      auth = psk
    }
    children {
      site2site {
        local_ts = 0.0.0.0/0
        remote_ts = 0.0.0.0/0
        if_id_in = 301
        if_id_out = 301
        start_action = start
        close_action = start
        esp_proposals = aes128-sha256-modp1024
        mode = tunnel
        dpd_action = start
      }
    }
    version = 2
    mobike = yes
    proposals = aes128-sha256-prfsha256-modp1024
    dpd_delay = 30s
    keyingtries = 3
  }
}

secrets {
  ike-panther {
    secret = 0sFpZAZqEN6Ti9sqt4ZP5EWcqx
  }
}

pools {
}

4. Server-Side Configuration

Create the XFRM interface ipsec0 on the server-side:

ip link add ipsec0 type xfrm dev eth0 if_id 301
ip link set ipsec0 up

swanctl.conf file content

```bash
connections {

   rw {
      local_addrs  = 10.0.24.2

      local {
         auth = psk
      }
      remote {
         auth = psk
      }
      children {
         net {
                local_ts  = 0.0.0.0/0
                remote_ts = 0.0.0.0/0

                if_id_out = 301
                if_id_in = 301
                esp_proposals = aes128-sha256-modp1024
         }
      }
      version = 2
      proposals = aes128-sha256-modp1024
   }
}

secrets {

   ike-panther {
      id = 192.168.80.79
      secret = 0sFpZAZqEN6Ti9sqt4ZP5EWcqx
   }
   ike-dave {
      id = 192.168.80.254
      secret = 0sjVzONCF02ncsgiSlmIXeqhGN
   }
}
```
ubuntu@VM-24-2-ubuntu:~/work/strongswan-5.9.14$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:2d:7c:ff:59  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.24.2  netmask 255.255.252.0  broadcast 10.0.27.255
        inet6 fe80::5054:ff:fe74:5f6f  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:74:5f:6f  txqueuelen 1000  (Ethernet)
        RX packets 1501931901  bytes 223267967770 (223.2 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1178769587  bytes 204631345701 (204.6 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ipsec0: flags=193<UP,RUNNING,NOARP>  mtu 1500
        inet6 fe80::afaa:3a8a:d6ff:da7f  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
        RX packets 1507  bytes 126588 (126.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1476  bytes 123984 (123.9 KB)
        TX errors 0  dropped 31 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 24285706  bytes 4469807277 (4.4 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 24285706  bytes 4469807277 (4.4 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

5. Adding Route Rules

Add route rules on both the OpenWrt and server-side:

OpenWrt:

ip route add 172.17.0.0/16 dev xfrm0
ip route add 10.0.24.0/24 dev xfrm0

Server-Side (Ubuntu):

ip route add 192.168.80.0/24 dev ipsec0

6. Verification

Verify the tunnel status and connectivity:

OpenWrt:

swanctl -l
ping 172.17.0.1
ip xfrm state
ip -s link show xfrm0

Ubuntu:

sudo swanctl -l
ping 192.168.80.79
sudo ip xfrm state
sudo ip -s link show ipsec0

Ensure the tunnel is established and functional by verifying connectivity and checking the XFRM states.

By following these steps, you should have successfully set up an IPsec VPN tunnel using StrongSwan with Swanctl on OpenWrt.

For more updates and discussions, follow me on X at @staylightblow8.

1 Like