Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
install_24_4_strongswan [2026/01/11 11:26] – created systeminstall_24_4_strongswan [2026/01/12 06:08] (current) – [Create PKI] system
Line 6: Line 6:
   * The following instructions should work well on any of the recent versions of StrongSwan   * The following instructions should work well on any of the recent versions of StrongSwan
  
 +-----------
 +===== Install StrongSwan  =====
 +  * As stated on the StrongSwan Primer wiki page, StrongSwan has gone through an aggressive redesign and you should take care when installing it not to install the older legacy version.
 +  * The natural behavior would be to install the StrongSwan meta package. <color #ed1c24>This should **not** be done</color>
 +  * Instead we install **charon-systemd** and **strongswan-swanctl**
 +<code bash>
 +#Make sure the old StrongSwan versions are not installed or running
 +sudo systemctl disable strongswan.service
 +sudo systemctl stop strongswan
 +sudo apt-get remove strongswan-starter
 +sudo apt-get remove strongswan-charon
 +#Install the new style StrongSwan
 +sudo apt-get install charon-systemd strongswan-swanctl
 +#Enable its startup
 +sudo systemctl enable strongswan.service
 +#This will link the strongswan-swanctl
 +#Created symlink /etc/systemd/system/strongswan-swanctl.service → /usr/lib/systemd/system/strongswan.service.
 +#Created symlink /etc/systemd/system/multi-user.target.wants/strongswan.service → /usr/lib/systemd/system/strongswan.service.
 +
 +#Start it up
 +sudo systemctl start strongswan-swanctl.service
 +#=== Or for the same result alternatively ===
 +sudo systemctl start strongswan
 +sudo service strongswan start
 + 
 +#Check Its status
 +sudo systemctl status strongswan-swanctl.service
 +#=== Or for the same result alternatively ===
 +sudo systemctl status strongswan
 +sudo service strongswan status
 +</code>
 +  * This is the result of the status command on our server:
 +<code bash>
 +● strongswan.service - strongSwan IPsec IKEv1/IKEv2 daemon using swanctl
 +     Loaded: loaded (/usr/lib/systemd/system/strongswan.service; enabled; preset: enabled)
 +     Active: active (running) since Sun 2026-01-11 10:17:49 UTC; 11min ago
 +   Main PID: 1777399 (charon-systemd)
 +     Status: "charon-systemd running, strongSwan 5.9.13, Linux 6.8.0-90-generic, x86_64"
 +      Tasks: 17 (limit: 1107)
 +     Memory: 4.6M (peak: 20.0M)
 +        CPU: 2.445s
 +     CGroup: /system.slice/strongswan.service
 +             └─1777399 /usr/sbin/charon-systemd
 +
 +</code>
 +  * As you can see it has the **charon-systemd** program running.
 +
 +------
 +===== Create PKI  =====
 +  * Next we will create the PKI.
 +  * We need to install a helper package that is part of StrongSwan first.
 +<code bash>
 +sudo apt-get install strongswan-pki
 +</code>
 +  * We issue the following commands.
 +<code bash>
 +mkdir -p ~/pki/{ca,certs,private}
 +chmod 700 ~/pki
 +cd ~/pki
 +
 +#Create the CA Certificate
 +pki --gen --type rsa --size 4096 --outform pem > ca/ca.key
 +pki --self --ca --lifetime 3650 --in ca/ca.key --type rsa --dn "CN=VPN Root CA" --outform pem > ca/ca.crt
 +
 +#Create the server certificate:
 +pki --gen --type rsa --size 4096 --outform pem > private/server.key
 +pki --issue --lifetime 825 --in private/server.key --type rsa --cacert ca/ca.crt --cakey ca/ca.key --dn "CN=cloud.radiusdesk.com" --san cloud.radiusdesk.com --flag serverAuth --flag ikeIntermediate --outform pem > certs/server.crt
 +
 +#Create a client certificate
 +pki --gen --type rsa --size 4096 --outform pem > private/carol.key
 +pki --issue --lifetime 825 --in private/carol.key --type rsa --cacert ca/ca.crt --cakey ca/ca.key --dn "CN=Carol" --san carol@strongswan.org --flag clientAuth --outform pem > certs/carolCert.pem
 +
 +#View it
 +pki --print --in certs/carolCert.pem
 +
 +</code>
 +<WRAP center round tip 100%>
 +  * StrongSwan has some very good documentation on managing certificates
 +  * https://docs.strongswan.org/docs/latest/pki/pkiQuickstart.html
 +</WRAP>
 +
 +
 +--------
 +===== Configure Swanctl  =====
 +  * The way we configure StrongSwan is again a bit different compared to the 'traditional' way of configuring services running on a server.
 +  * With StrongSwan we have the **/etc/swanctl** folder.
 +  * Inside this folder are various sub-folders that are pre-installed.
 +  * This setup relies strong on convention where **swanctl** expect certain items to be located under certain folders.
 +  * We also have the **swanctl.conf** config file which we will cover in this section.
 +
 +---------
 +==== Config File ====
 +  * The config file has a JSON like structure.
 +  * Please note that it is not valid JSON but rather a JSON like structure.
 +  * Below is our demo server's config:
 +<code JavaScript>
 +connections {
 +    xfrm-gw {
 +
 +        local_addrs = %any
 +        remote_addrs = %any
 +        pools = rw_pool
 +        # XFRM interface binding - CRITICAL
 +        if_id_in = 100
 +        if_id_out = 100
 +        version = 2
 +        proposals = aes128-sha1-modp2048
 +        local {
 +            auth = pubkey
 +            certs = server.crt
 +            id = cloud.radiusdesk.com
 +         }
 +        remote {
 +            auth = pubkey
 +      }
 +      children {
 +        xfrm-gw {
 +          local_ts  = 0.0.0.0/0
 +          remote_ts = 0.0.0.0/0
 +          if_id_in  = 100
 +          if_id_out = 100
 +          esp_proposals =  aes128-sha1-modp2048
 +          start_action = start
 +          dpd_action = restart
 +        }
 +      }
 +      send_cert = always
 +      dpd_delay = 30s
 +      rekey_time = 1h
 +      #send_certreq = no
 +    }
 +}
 +pools {
 +    rw_pool {
 +      addrs = 10.3.1.0/16
 +    }
 +}
 +</code>
 +
 +------------
 +==== Cert and Key Files ====
 +  * As we stated there are some pre-installed sub folders under the **/etc/swanctl** folder.
 +  * The following should be used to contain the CA, server cert and server key files.
 +  * Copy the **ca.crt** file to **/etc/swanctl/x509ca**.
 +  * Copy the **server.key** file to **/etc/swanctl/private**.
 +  * Copy the **server.crt** file to **/etc/swanctl/x509**.
 +
 +----------
 +===== Xfrm Interface Prep =====
 +  * When a client connects establishes a connection to the StrongSwan server, it is referred to as a Security Association (SA).
 +  * We can use the swanctl command to see if there are any existing SAs.
 +<code bash>
 +sudo swanctl --list-sa
 +xfrm-gw: #11, ESTABLISHED, IKEv2, 8c4f8f2882625d72_i* f423c783942a5006_r
 +  local  'cloud.radiusdesk.com' @ 164.160.89.129[4500]
 +  remote 'carol@strongswan.org' @ 197.64.146.11[4500] [10.3.1.0]
 +  AES_CBC-128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
 +  established 679s ago, rekeying in 2626s
 +  xfrm-gw: #7, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96/MODP_2048
 +    installed 1372s ago, rekeying in 2128s, expires in 2588s
 +    in  c9f9936f (-|0x00000064),   2645 bytes,    29 packets,   139s ago
 +    out c33bfaa6 (-|0x00000064),  22938 bytes,    38 packets,   139s ago
 +    local  0.0.0.0/0
 +    remote 0.0.0.0/0
 +</code>
 +  * We implement a route based IPsec VPN (The other option is policy based).
 +  * Route based IPsec specify a **if_id_in** and **if_id_out**.
 +  * This is used to tag traffic inside a SA.
 +  * With Wireguard, you can have multiple instances running on different ports.
 +  * With StrongSwan there is one instance, but you can have multiple connections defined in the config file each using a unique **if_id_in** and **if_id_out**.
 +  * The **if_id_in** and **if_if_out** in tern have to terminate into a **xfrm** interface.
 +  * We will create a startup script that prepare this interface for us **BEFORE** we start StrongSwan.
 +  * Create the file **/usr/local/sbin/xfrm-up.sh** with the following contents.
 +  * We assume eth0 is the interface name where the server gets it Internet from. Please adapt if your server is different.
 +<code bash>
 +#!/bin/sh
 +set -e
 +#
 +IFACE=xfrm0
 +IF_ID=100
 +ADDR=10.3.0.1/32
 +SUBNET=10.3.0.0/24
 +
 +# Create XFRM interface
 +ip link show "$IFACE" >/dev/null 2>&1 || \
 +ip link add "$IFACE" type xfrm if_id "$IF_ID"
 +
 +# Assign IP
 +ip addr show "$IFACE" | grep -q "$ADDR" || \
 +ip addr add "$ADDR" dev "$IFACE"
 +
 +# Bring interface up
 +ip link set "$IFACE" up
 +
 +# Route for remote side
 +ip route show "$SUBNET" | grep -q "$IFACE" || \
 +ip route add "$SUBNET" dev "$IFACE"
 +
 +# ---- NAT via nftables ----
 +
 +# Create table if missing
 +nft list table ip nat >/dev/null 2>&1 || \
 +nft add table ip nat
 +
 +# Create postrouting chain if missing
 +nft list chain ip nat postrouting >/dev/null 2>&1 || \
 +nft add chain ip nat postrouting { type nat hook postrouting priority 100\; }
 +
 +# Add SNAT/MASQUERADE rule (idempotent)
 +nft list chain ip nat postrouting | grep -q "$IFACE" || \
 +nft add rule ip nat postrouting oifname "$IFACE" masquerade
 +nft add rule ip nat postrouting oifname "eth0" masquerade
 +
 +</code>
 +  * Create a startup script called **/etc/systemd/system/xfrm0.service** which calls the script above.
 +<code bash>
 +[Unit]
 +Description=XFRM Interface xfrm0
 +Before=strongswan.service
 +Wants=network-online.target
 +After=network-online.target
 +
 +[Service]
 +Type=oneshot
 +ExecStart=/usr/local/sbin/xfrm-up.sh
 +RemainAfterExit=yes
 +
 +[Install]
 +WantedBy=multi-user.target
 +</code>
 +  * Enable the startup script and start it up
 +<code bash>
 +systemctl enable xfrm0
 +systemctl start xfrm0
 +</code>
 +  * Everything is now prepared on the server side.
 +  * We can now configure clients in APdesk and MESHdesk to route certain traffic through the IPsec tunnel.
 +  * These are covered in a dedicated Wiki page.
  • install_24_4_strongswan.1768123609.txt.gz
  • Last modified: 2026/01/11 11:26
  • by system