IPsec on Debian Bookworm with Swanctl

Strongswan-swanctl introduces the new configuration format for IPsec on Debian Bookworm. Unfortunately the configuration is more convoluted. Start by installing charon-systemd, which will bring in the required packages:

sudo apt install charon-systemd

Key component packages:

  • charon-systemd – provides the systemd and apparmor files.
  • strongswan-swanctl – provides the swanctl management application and primary configuration file /etc/swanctl/swanctl.conf.
  • strongswan-libcharon – the charon library, for IKE.
  • libstrongswan – the strongswan library, for other VPN tasks.

Example road-warrior config shown below, using IKEv2 with a certificate to authenticate the server and a user ID and password for the client:

/etc/systemctl/systemctl.conf:

connections {
  mobile-clients {
    version = 2
    dpd_delay = 60s
    send_cert = always
    pools = pool-rw-ikev2
    #local_addrs = 192.168.1.250 # Server local IP address
    local {
      id = your.server.net
      # Local side auth      # (pubkey, psk, eap-mschapv2, eap-md5, etc.)      auth = pubkey
      certs = /etc/swanctl/pubkey/vpn_server_cert.pem
    }
    remote {
      auth = eap-mschapv2
      #eap_id=%any
    }
    children {
      mobile-clients {
        start_action = none # none(listen), trap, start
        local_ts = 192.168.1.0/24
      }
    }
  }
}pools {
        pool-rw-ikev2 {
                # VPN subnet:
                addrs=192.168.200.0/24
        }
}
secrets {
        eap-user1 {
                id = bob
                secret = PasswordForBob
        }
        eap-user2 {
                id = alice
                secret = PasswordForAlice
        }

Notes:

  • Private key for the server certificate needs to be copied to
    /etc/swanctl/private/
    (name of file does not need to match they pubkey certificate)
  • If using Lets Encrypt certificate with Strongswan on Android, you need to download and import the Lets Encrypt Intermediate R3 PEM certificate to the client. (https://letsencrypt.org/certificates/)
  • Remember to add routes and adjust firewalls for the chosen VPN IP subnet pool.
  • To temporarily disable a connection, rather than comment all the lines move it out from “connections { }” to a section titled “disabled { }”.

The default configuration produces warnings that a number of plugins are not available, to disable these warnings set them not to load:

/etc/swanstrong.d/swanctl.conf:

swanctl {
    # Plugins to load in swanctl.
    # load =

    # VICI socket to connect to by default.
    # socket = unix://${piddir}/charon.vici

    # Disable plugins that default config tries to load:
    plugins {
        af-alg { load=no }
        ccm { load=no }
        chapoly { load=no }
        cmac { load=no }
        ctr  { load=no }
        curl { load=no }
        curve25519 { load=no }
        gcrypt { load=no }
        ldap { load=no }
        pkcs11 { load=no }
        rdrand { load=no }
        test-vectors { load=no }
    }
}

Verify the configuration has no obvious errors with:

sudo systemctl --load-all
sudo systemctl --load-creds

# Monitor for connections:
sudo systemctl --monitor-sa

# List Security Associations:
sudo systemctl --list-sas