Setup IPSEC VPN using StrongSwan on Debian 10

Last Updated:

In this guide, we are going to learn how to setup IPSec VPN using StrongSwan on Debian 10. StrongSwan is an opensource VPN software for Linux that implements IPSec. It supports various IPsec protocols and extensions such IKE, X.509 Digital Certificates, NAT Traversal…

Setting up IPSEC VPN using StrongSwan on Debian

Run System Update

To update your Debian 10 system packages, run the command below;

apt update

Install strongSwan on Debian 10 Buster

strongSwan is available on the default Debian 10 Buster repositories. Thus, the command below can be executed to install it and other required tools;

apt install strongswan strongswan-pki libcharon-extra-plugins

Generate VPN Certificate and Key

For VPN clients to verify the authenticity of the VPN server, you need to generate the VPN server certificate and key and sign them using your CA.

Generate Local CA Certificate

In this demo, we will be singing our VPN Certificates with a self-signed CA. Thus the local CA can be generated using the strongSwan PKI utility installed above.

Generate a Private Key

The first step is to generate a private key for creating the self-signed CA certificate.

ipsec pki --gen --size 4096 --type rsa --outform pem > vpn_ca_key.pem

Keep the key as private as possible.

Generate the self-signed CA Certificate

Next, generate the VPN server CA and self-sign with the key generated above.

ipsec pki --self --in vpn_ca_key.pem --type rsa \
--dn "C=US, O=Kifarunix-Demo, CN=Kifarunix VPN Server Root CA" \
--ca --lifetime 365 --outform pem > vpn_ca_cert.pem

Generate VPN server private key

Next, generate your VPN server private key by running the command below;

ipsec pki --gen --size 4096 --type rsa --outform pem > vpn_server_key.pem

Generate VPN server Certificate

To generate the VPN Certificate, you need to extract the public key from the VPN private generated above. The public key will be included in the certificate to be generated.

ipsec pki --pub --in vpn_server_key.pem --type rsa > vpn_server_pub_key.pem

Next, generate the certificate.

ipsec pki --issue --in vpn_server_pub_key.pem --lifetime 365 \
--cacert vpn_ca_cert.pem \
--cakey vpn_ca_key.pem \
--dn "" \
--san="" \
--flag serverAuth --flag ikeIntermediate --outform pem > vpn_server_cert.pem

Adjust the distinguished name (dn), subjectAltName(san) and flags accordingly. Refer to man pki –issue.

Install the VPN Certificates and Keys

Install the VPN certificates and keys in their respective IPSec directory locations.

mv vpn_ca_cert.pem /etc/ipsec.d/cacerts/
mv vpn_server_cert.pem /etc/ipsec.d/certs/
mv {vpn_ca_key.pem,vpn_server_key.pem} /etc/ipsec.d/private/

Configure strongSwan on Debian 10

The next step is to configure strongSwan on Debian 10. The main default configuration file is /etc/ipsec.conf. Edit this file and make any relevant changes based on your environment setup.

Create a backup copy of the original file before you can proceed.

cp /etc/ipsec.conf /etc/ipsec.conf.old

Open the configuration file for editing;

vi /etc/ipsec.conf

The configuration file contains three sections;

  • CONFIG SECTIONS (config setup)
    – Defines general configuration parameters
  • CONN SECTIONS (conn <name>)
    – Contains a connection specification, defining a network connection to be made using IPsec.
  • CA SECTION (ca <name>)
    – Defines a certification authority.

Define the CONFIGURATION parameters;

config setup
        charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2, mgr 2"
  • The charondebug = <debug list>  parameter defines the charon debug loggin where the debug list can be dmn, mgr, ike, chd, job, cfg, knl, net, asn, enc, lib, esp, tls, tnc, imc, imv, pts. The logging levels can one of -1, 0, 1, 2, 3, 4 (for silent, audit, control, controlmore, raw, private). By default, the level is set to 1 for all types. For a description of the debug lists, check the LOGGER CONFIGURATION section on strongswan.conf(5).
  • strictcrlpolicy parameter defines if a fresh CRL must be available in order for the peer authentication based on RSA signatures to succeed.
  • uniqueids defines whether a particular participant ID should be kept unique
  • cachecrls defines whether to or not cache the certificate revocation lists (CRLs) fetched via HTTP or LDAP.

Define the CONNECTION parameters;

conn ipsec-ikev2-vpn
      type=tunnel  # defines the type of connection, tunnel.
      [email protected]    #If using IP, define it without the @ sign
      leftcert=vpn_server_cert.pem  #Reads the VPN server cert in /etc/ipsec.d/certs
      rightsourceip=  #IP address Pool to be assigned to the clients
      rightdns=  # DNS to be assigned to clients
      eap_identity=%identity  #Defines the identity the client uses to reply to an EAP Identity request.

To see a comprehensive description of the connection parameters and the values used in the above configuration, see man ipsec.conf.

Setup Secrets for IKE/IPsec authentication

Next, setup the secrets to be used by the strongSwan Internet Key Exchange (IKE) daemons to authenticate other hosts. These credentials are set in the /etc/ipsec.secrets configuration file.

Thus open this file and define the RSA private keys for authentication. You can also setup the EAP user credentials by defining a random username and its password. Note the Spacing.

vim /etc/ipsec.secrets
# This file holds shared secrets or RSA private keys for authentication.

# RSA private key for this host, authenticating it to any other host which knows the public part.

: RSA vpn_server_key.pem ## Specify the VPN Server Key

# Define the list of IDs followed by a secret for authentication
# user id : EAP secret
vpnsecure : EAP "P@sSw0Rd"   # Random
koromicha : EAP "mypassword"

# this file is managed with debconf and will contain the automatically created private key
include /var/lib/strongswan/

Running strongSwan

Save the configuration file above and restart strongswan for the changes above to take effect.

systemctl restart strongswan

To check the status;

systemctl status strongswan
● strongswan.service - strongSwan IPsec IKEv1/IKEv2 daemon using ipsec.conf
   Loaded: loaded (/lib/systemd/system/strongswan.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-02-24 13:37:50 EST; 1min 11s ago
 Main PID: 2667 (starter)
    Tasks: 18 (limit: 1149)
   Memory: 3.0M
   CGroup: /system.slice/strongswan.service
           ├─2667 /usr/lib/ipsec/starter --daemon charon --nofork
           └─2681 /usr/lib/ipsec/charon --debug-ike 2 --debug-knl 2 --debug-cfg 2 --debug-net 2 --debug-esp 2 --debug-dmn 2 --debug-mgr 2

Feb 24 13:37:50 debian charon[2681]: 05[CFG]   eap_identity=%identity
Feb 24 13:37:50 debian charon[2681]: 05[CFG]   dpddelay=300
Feb 24 13:37:50 debian charon[2681]: 05[CFG]   dpdtimeout=150
Feb 24 13:37:50 debian charon[2681]: 05[CFG]   dpdaction=1
Feb 24 13:37:50 debian charon[2681]: 05[CFG]   sha256_96=no
Feb 24 13:37:50 debian charon[2681]: 05[CFG]   mediation=no
Feb 24 13:37:50 debian charon[2681]: 05[CFG]   keyexchange=ikev2
Feb 24 13:37:50 debian charon[2681]: 05[CFG] adding virtual IP address pool
Feb 24 13:37:50 debian charon[2681]: 05[CFG]   loaded certificate "" from 'vpn_server_cert.pem'
Feb 24 13:37:50 debian charon[2681]: 05[CFG] added configuration 'ipsec-ikev2-vpn'

Configure VPN Server Firewall and Routing

If UFW is enabled and running, configure it to allow and forward the VPN traffic. For IPsec to work through firewall, you need to open UDP ports 500 and 4500.

  • 500/udp – Allows Internet Security Association and Key Management Protocol (ISAKMP) traffic to be forwarded
  • 4500/udp – Allows handling of IPsec between natted devices
ufw allow 500/udp
ufw allow 4500/udp

Next, find your server default route interface.

ip route show default
default via dev enp0s3  

In this case, our interface for routing traffic is enp0s3. This interface will be used next while configuring UFW routing as shown below.

Edit the UFW before rules file, /etc/ufw/before.rules and add the lines highlighted below immediately before and after the *filter.

vim /etc/ufw/before.rules
-A POSTROUTING -s -o enp0s3 -m policy --pol ipsec --dir out -j ACCEPT
-A FORWARD --match policy --pol ipsec --dir in -s -o enp0s3 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360

# Don't delete these required lines, otherwise there will be errors
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines
-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d -j ACCEPT

Disable and enable ufw for the changes to take effect.

ufw disable && ufw enable

Configure Kernel IP forwarding

Next, you need to configure routing by enabling Kernel IP forwarding by editing the file, /etc/ufw/sysctl.conf and making the changes as highlighted below. If the lines do not exist, add them.

vim /etc/ufw/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
# Do not accept ICMP redirects (prevent MITM attacks)
net/ipv4/conf/all/accept_redirects = 0
# Do not send ICMP redirects (we are not a router)
net/ipv4/conf/all/send_redirects = 0
Disable Path MTU discovery to prevent packet fragmentation by adding the line below

Save the configuration and reload the kernel runtime parameters.

sysctl -p

Restart strongSwan;

systemctl restart strongswan

You can check that status by using the command;

ipsec statusall
Status of IKE charon daemon (strongSwan 5.7.2, Linux 4.19.0-8-amd64, x86_64):
  uptime: 3 minutes, since Feb 24 14:08:54 2020
  malloc: sbrk 1748992, mmap 0, used 527984, free 1221008
  worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 0
  loaded plugins: charon aesni aes rc2 sha2 sha1 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp agent xcbc hmac gcm attr kernel-netlink resolve socket-default connmark stroke updown counters
Virtual IP pools (size/online/offline): 254/0/0
Listening IP addresses:
ipsec-ikev2-vpn:  %any...%any  IKEv2, dpddelay=300s
ipsec-ikev2-vpn:   local:  [] uses public key authentication
ipsec-ikev2-vpn:    cert:  ""
ipsec-ikev2-vpn:   remote: uses EAP_MSCHAPV2 authentication with EAP identity '%any'
ipsec-ikev2-vpn:   child: === dynamic TUNNEL, dpdaction=clear
Security Associations (0 up, 0 connecting):

Testing strongSwan VPN Connection

strongSwan VPN server has been setup. You can now proceed to test the IP assignment and local connection via the VPN server.

See our next guide on how to setup strongSwan VPN client on Ubuntu 18.04 and CentOS 8.

Configure strongSwan VPN Client on Ubuntu 18.04/CentOS 8

That marks the end of our guide on how to setting up IPSEC VPN using StrongSwan on Debian 10 Buster.

Related Tutorials

Install and Setup OpenVPN Server on Fedora 29/CentOS 7

Install Cisco AnyConnect Client on CentOS 8

Configure IPSEC VPN using StrongSwan on Ubuntu 18.04


We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
I am the Co-founder of, Linux and the whole FOSS enthusiast, Linux System Admin and a Blue Teamer who loves to share technological tips and hacks with others as a way of sharing knowledge as: "In vain have you acquired knowledge if you have not imparted it to others".

2 thoughts on “Setup IPSEC VPN using StrongSwan on Debian 10”

  1. Hi your guide is not working. Im getting auth failed for any devices. I tried Windows, Android and iOS…

    Please help fix it. Thanks

  2. Hi, greetings from Brazil.

    The article helps me set up my VPN and it is working perfectly fine.

    thank you for that.

    I only have one debt regarding the file: vpn_server_pub_key.pem because it was “left” in the folder and was not transferred.

    What is the function of this file since it has already been used in vpn_server_cert.pem?


Leave a Comment