IKEv2 with strongSwan

IKEv2 is defined by the Internet Engineering Task Force standard RFC 7296. It uses fixed port numbers. It is therefore easily blocked by censors. Nevertheless, it may work in some countries.

This article shows you how to create an IKEv2 server using strongSwan on Debian 10. In the examples we give, the client is at IP address xx.xx.xx.xx, and the server is at IP address yy.yy.yy.yy. Wherever you see these values in the examples, you will need to change them to match your actual IP addresses. If you do not know your workstation’s IP address, you can determine it by opening a browser and visiting IPchicken.com.

We will also give instructions for the example of a Windows client device.

1. Server

1.1. Install and Configure Firewall

We begin by installing a firewall and configuring it to accept packets using AH protocol and ESP protocol, plus 500/udp and 4500/udp, which will be used with clients behind Network Address Translation. We also masquerade outgoing IP addresses. Issue the commands that follow:

apt update && apt upgrade -y
apt install nftables -y
systemctl enable nftables
systemctl start nftables
nft add rule inet filter input ct state related,established counter accept
nft add rule inet filter input iif lo counter accept
nft add rule inet filter input ip protocol icmp counter accept
nft add rule inet filter input ip6 nexthdr icmpv6 counter accept
nft add rule inet filter input tcp dport ssh counter accept
nft add rule inet filter input ip protocol ah counter accept
nft add rule inet filter input ip protocol esp counter accept
nft add rule inet filter input udp dport 500 counter accept
nft add rule inet filter input udp dport 4500 counter accept
nft add rule inet filter input counter drop
nft add table nat
nft add chain nat prerouting { type nat hook prerouting priority 0 \; }
nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
nft add rule nat postrouting masquerade

Save these firewall rules:

nft list ruleset > /etc/nftables.conf

For better security, restrict port 22 access to trusted IP addresses only. For example, if you always log in from IP address xx.xx.xx.xx:

vi /etc/nftables.conf

Edit the line for the SSH port, and restrict it to accept only your personal source IP address:

tcp dport ssh ip saddr xx.xx.xx.xx/32 counter accept

Save the file. Restart the firewall:

systemctl restart nftables

1.2. Allow Forwarding

Now enable packet forwarding in the Linux kernel. Create a new configuration file in /etc/sysctl.d:

vi /etc/sysctl.d/40-ipv4-forward.conf

Insert a single line:


Save the file. Make this change effective immediately.:

sysctl -p /etc/sysctl.d/40-ipv4-forward.conf

1.3. Install Packages

Install strongSwan by entering the command:

apt install strongswan libstrongswan strongswan-pki libstrongswan-standard-plugins libstrongswan-extra-plugins strongswan-swanctl strongswan-charon strongswan-starter strongswan-libcharon libcharon-extra-plugins charon-systemd -y

1.4. Create Certificate Authority Certificate

We will create a self-signed Certificate Authority (CA) certificate. Issue the command that follows, replacing country US, organization Example, and common name Example CAwith your own choices for values:

ipsec pki --gen --outform pem > /etc/swanctl/private/ca.pem
chmod 600 /etc/swanctl/private/ca.pem
ipsec pki --self --ca --lifetime 3650 --in /etc/swanctl/private/ca.pem --dn "C=US, O=Example, CN=Example CA" --outform pem > /etc/swanctl/x509ca/ca.pem

1.5. Create Server Certificate

Generate the server certificate. Issue the next command, replacing Example with your own choice of organization name. Also replace yy.yy.yy.yy wherever it appears by your server’s actual IP address.

ipsec pki --gen --outform pem > /etc/swanctl/private/yy.yy.yy.yy.pem
chmod 600 /etc/swanctl/private/yy.yy.yy.yy.pem
ipsec pki --pub --in /etc/swanctl/private/yy.yy.yy.yy.pem | ipsec pki --issue --lifetime 730 --cacert /etc/swanctl/x509ca/ca.pem --cakey /etc/swanctl/private/ca.pem --dn "C=US, O=Example, CN=yy.yy.yy.yy" --san yy.yy.yy.yy --flag serverAuth --flag ikeIntermediate --outform pem > /etc/swanctl/x509/yy.yy.yy.yy.pem

1.6. Create Client Certificate

Generate the client certificate, similar to the way you generated the server certificate. In the following example, replace win10, example.com, and Example wherever they appear by your own values:

ipsec pki --gen --outform pem > /etc/swanctl/private/win10.pem
chmod 600 /etc/swanctl/private/win10.pem
ipsec pki --pub --in /etc/swanctl/private/win10.pem | ipsec pki --issue --lifetime 730 --cacert /etc/swanctl/x509ca/ca.pem --cakey /etc/swanctl/private/ca.pem --dn "C=US, O=Example, CN=win10.example.com" --san win10.example.com --flag clientAuth --outform pem > /etc/swanctl/x509/win10.pem

1.7. Configure strongSwan

Create a new file for IKEv2 connections with machine certificate authenticaton:

vi /etc/swanctl/swanctl.conf

Insert a configuration like this. Replace yy.yy.yy.yy by your server’s IP address wherever it appears. Also replace any other values as you wish, for example the virtual IP address pool or the DNS servers.

connections {
  ikev2-pubkey {
    version = 2
    proposals = aes192gcm16-aes128gcm16-prfsha256-ecp256-ecp521,aes192-sha256-modp3072,default
    rekey_time = 0s
    pools = primary-pool-ipv4,primary-pool-ipv6
    fragmentation = yes
    dpd_delay = 30s
    local {
      certs = yy.yy.yy.yy.pem
      id = yy.yy.yy.yy
    remote {
    children {
      ikev2-pubkey-child {
        local_ts =
        rekey_time = 0s
        dpd_action = clear
        esp_proposals = aes192gcm16-aes128gcm16-prfsha256-ecp256-modp3072,aes192-sha256-ecp256-modp3072,default
pools {
  primary-pool-ipv4 {
    addrs =
    dns =,
  primary-pool-ipv6 {
    addrs = fec3::/120
    dns = 2001:4860:4860::8888,2001:4860:4860::8844
secrets {
  private {
    file = yy.yy.yy.yy.pem

Save the file.

1.8. Start strongSwan

Start strongSwan with your new configuration:

systemctl restart strongswan-swanctl

1.9. Check strongSwan

Check that strongSwan is active and running:

systemctl status strongswan-swanctl

If there are errors you need to check:

journalctl -xe
journalctl -u strongswan-swanctl

1.10. Create Client P12 File

Many types of client prefer a P12 file over separate certificate and key files. A P12 file follows the Public Key Cryptography Standard #12 format, and include keys and certificates in one file.

Convert your client certificate and key to PKCS12 format:

openssl pkcs12 -export -in /etc/swanctl/x509/win10.pem -inkey /etc/swanctl/private/win10.pem -out ~/win10.p12

Make sure you enter and confirm an export/import password when you create the p12 file.

Also convert your CA certificate to crt format, which is sometimes preferred by client devices:

openssl x509 -outform der -in /etc/swanctl/x509ca/ca.pem -out ~/ca.crt

Your server work is done for now.


We will continue on your workstation.

1.11. Securely Download Certificates to Workstation

The easiest way to securely download certificates to your device(s) is to first download them to a workstation on your LAN, where they will be behind a firewall, then transfer them from the workstation to your final clients.

To download to a Linux workstation, go to your workstation and use the scp command. For example:

scp root@yy.yy.yy.yy:win10.p12 ~/Downloads/win10.p12
scp root@yy.yy.yy.yy:ca.crt ~/Downloads/ca.crt

To download to a Windows workstation, you can use the pscp.exe command that comes with PuTTY. Here are some samples of the commands that you would enter into a Windows Command Prompt:

"C:\Program Files\PuTTY\pscp.exe" root@yy.yy.yy.yy:win10.p12 Downloads\win10.p12
"C:\Program Files\PuTTY\pscp.exe" root@yy.yy.yy.yy:ca.crt Downloads\ca.crt

For onward transfer to mobile devices, it is often convenient to create a secure website that presents the certificate to the final client.

2. Windows Client

2.1. Import Certificates

Use the Microsoft Management Console to import the CA certificate and the P12 file. Press the Win+r keys, type mmc, then press Enter. Do File, Add/Remove Snap-in, then choose Certificates. You must select Computer Account.

Import the CA certificate into Trusted Root Certification Authorities.

Import the P12 file into Personal. You will need to enter the password for the P12 file when you import it.

2.2. Add VPN Connection

Add the new VPN connection in Settings > Network & Internet > VPN. The VPN provider is Windows (built-in). The Connection name is (for example) win10. The Server name or address in our example is yy.yy.yy.yy. The VPN type is IKEv2. The Type of sign-in info is Certificate.

2.3. Set Authentication Method to Machine Certificate

Once you have added the new connection, check that the authentication method is set to machine certificate. For example, if you named the connection win10, then open PowerShell and issue the command:

Get-VpnConnection -Name "win10"

If necessary, set the authentication method to machine certificate:

Set-VpnConnection -Name "win10" -AuthenticationMethod "MachineCertificate"

2.4. Enable MODP2048 in Registry

Now edit the registry to allow use of modp2048. Press the Win+r keys, type regedit, then press Enter. Navigate to HKEY_LOCAL_MACHINE > SYSTEM > CurrentControlSet > Services > Rasman > Parameters. Insert a new DWORD (32-bit value). The name is NegotiateDH2048_AES256. The value is 1, which means enable AES-256-CBC and MODP-2048.

2.5. Route Traffic through VPN

Route all traffic through your VPN connection as follows. Open the Control Panel > Network and Internet > Network and Sharing Center. Click Change adapter settings. Select your IKEv2 interface. Right-click, and select Properties. Go to the Networking tab. Select the row for Internet Protocol Version 4 (TCP/IPv4). Click Properties. Click Advanced. Check the box for Use default gateway on remote network.

2.6. Connect

Now you can connect your client to your server from Settings > Network & Internet > VPN. Select your VPN and connect.

3. Get Help and Report Issues

For your client device in general, seek support through the normal channels for that device. For strongSwan in particular, support arrangements are listed on the strongSwan support page.

If you would like instructions for a hardened strongSwan installation, or for iOS and macOS clients, see the blog post by Sun Knudsen.