How to Setup an IKEv2 VPN Connection on Arch Linux (Example: NordVPN)
Tags: linux, devtools, vpn
Published: 2020-02-16 13:26:03

---
title: How to Setup an IKEv2 VPN Connection on Arch Linux (Example: NordVPN)
published: true
date: 2020-02-16 00:00:00 UTC
tags: Linux, DevTools, VPN
cover_image: https://live.staticflickr.com/1732/40828818410_f981d35e76_c_d.jpg
canonical_url: https://www.rockyourcode.com/how-to-setup-an-ikev2-vpn-connection-on-arch-linux-example-nordvpn/
---

_cover image by [Richard Patterson](http://www.comparitech.com/)_


> Connect your Linux machine to a VPN Gateway using strongSwan

In this blog post I'll show you how to connect your local machine to a remote VPN server using the IKEv2 and IPSec protocol. Instead of the deprecated `ipsec.conf` we'll use the modern `swanctl.conf`.

# Why IPSec/IKEv2?

IKEv2 offers [high speed and good data security with a stable connection][1]. The protocol is one of the best.

**[strongSwan][2]** provides an open-source implementation of IPSec. strongSwan works on Linux, Android, FrreBSD, macOS, iOs, and Windows.

The tool natively supports [forwarding and split-tunneling][7], thus enabling you to selectively [route your traffic through the VPN connection][17].

Why is that useful?  
With split-tunneling you can exclude your local subnets (your home network, or local Docker bridge) from the VPN gateway.  
Now you can connect your local machine to the VPN server, but still have access to your wifi-connected printer.

# 1. Installation

Usually, the [Arch wiki][3] is a mine of gold. Unfortunately, the wiki solely describes how to setup a connection with [ipsec.conf and ipsec starter][4].

The newly available [swanctl and vici plugin][5] provide a better experience in combination with [systemd][6] and strongSwan's plugins.

In this article, I'll show you a sample `ipsec.conf` with [pre-shared keys (EAP)][8], and how to migrate the configuration to swanctl.

We'll assume that you have access to a remote VPN server, either your own implementation or a commercial provider like [NordVPN][9].

We'll use [yay][11] to install strongSwan:

```bash
yay -S strongswan
```

# 2. Configuration

### 1. ipsec/swanctl

Example `ipsec.conf` with username and password (NordVPN uses a different approach, see below):

```
conn vpn
  keyexchange=ikev2
  dpdaction=clear
  dpddelay=300s
  eap_identity="<your-username>"
  leftauth=eap-mschapv2
  left=%defaultroute
  leftsourceip=%config
  right=<server.name.com>
  rightauth=pubkey
  rightsubnet=0.0.0.0/0
  rightid=%any
  type=tunnel
  auto=add
```

Here's how the configuration [translates to `swanctl.conf`][12] (on your machine: `/etc/swanctl/swanctl.conf` or similar):

```
connections {
    vpn {
        version = 2
        proposals = aes192gcm16-aes128gcm16-prfsha256-ecp256-ecp521,aes192-sha256-modp3072,default
        rekey_time = 0s
        fragmentation = yes
        dpd_delay = 300s
        local_addrs = %defaultroute
        remote_addrs = <server.name.com>
        vips=0.0.0.0,::
        local {
            auth = eap-mschapv2
            eap_id = "<your-username>"
        }
        remote {
            auth = pubkey
            id = %any
        }
        children {
            vpn {
                remote_ts = 0.0.0.0/0,::/0
                rekey_time = 0s
                dpd_action = clear
                esp_proposals = aes192gcm16-aes128gcm16-prfsha256-ecp256-modp3072,aes192-sha256-ecp256-modp3072,default
            }
        }
    }

secrets {
    eap-vpn {
        id = "<your-username>"
        secret = "<your-password>"
    }
}
```

Don't forget to replace the `remote_addr` with the real server name.  
Replace `<your-username>` and `<your-password>`, too.

Here's another example configuration where we use a username and certifictate instead of username/password in the `ipsec.conf` (**[NordVPN][9]**):

```
conn NordVPN
  keyexchange=ikev2
  dpdaction=clear
  dpddelay=300s
  eap_identity="<your-username>"
  leftauth=eap-mschapv2
  left=%defaultroute
  leftsourceip=%config
  right=<server.name.com>
  rightauth=pubkey
  rightsubnet=0.0.0.0/0
  rightid=%any
  rightca=/etc/ipsec.d/cacerts/NordVPN.pem
  type=tunnel
  auto=add
```

For `etc/swanctl/swanctl.conf`:

```
connections {
    nordvpn {
        version = 2
        proposals = aes192gcm16-aes128gcm16-prfsha256-ecp256-ecp521,aes192-sha256-modp3072,default
        rekey_time = 0s
        fragmentation = yes
        dpd_delay = 300s
        local_addrs = %defaultroute
        remote_addrs = <server.name.com>
        vips=0.0.0.0,::
        local {
            auth = eap-mschapv2
            eap_id = "<your-username>"
        }
        remote {
            auth = pubkey
            cacerts=/etc/ipsec.d/cacerts/NordVPN.pem
            id = %any
        }
        children {
            nordvpn {
                remote_ts = 0.0.0.0/0,::/0
                rekey_time = 0s
                dpd_action = clear
                esp_proposals = aes192gcm16-aes128gcm16-prfsha256-ecp256-modp3072,aes192-sha256-ecp256-modp3072,default
            }
        }
    }
```

### 2. Constraints Plugin

You might also want to disable the [constraints plugin][13]:

```bash
sudo sed -i 's/load = yes/load = no/g' /etc/strongswan.d/charon/constraints.conf
```

Make sure that your strongSwan basic configuration respects that setting (`/etc/strongswan.conf`):

```
# strongswan.conf - strongSwan configuration file
#
# Refer to the strongswan.conf(5) manpage for details
#
# Configuration changes should be made in the included files

charon-systemd {
  threads = 16
  plugins {
  	include strongswan.d/charon/*.conf
	}
}
include strongswan.d/*.conf
```

### 3. Get Certificates

Your local machine needs a [certificate for the VPN server][14].

With NordVPN you have to download their certificate:

```bash
sudo wget https://downloads.nordvpn.com/certificates/root.der -O /etc/ipsec.d/cacerts/NordVPN.der
```

```bash
sudo openssl x509 -inform der -in /etc/ipsec.d/cacerts/NordVPN.der -out /etc/ipsec.d/cacerts/NordVPN.pem
```

With other providers it might suffice to link the standard OpenSSL certificates with the IPSec certs:

```bash
sudo rmdir /etc/ipsec.d/cacerts
sudo ln -s /etc/ssl/certs /etc/ipsec.d/cacerts
```

### 4. Restart strongSwan

strongSwan has a [systemd script][6]:

```bash
sudo systemctl restart strongswan
```

You can also enable the script for starting strongSwan on boot:

```bash
sudo systemctl enable strongswan
```

You can use the tool via the [`swanctl` command line utility][15]. For example:

```bash
# starts the connection and the remote children setup
sudo swanctl -i -c <name-of-children-connection>
# stops the complete connection
sudo swanctl -t -i <name-of-the-connection>
```

Example:

```bash
sudo swanctl -i -c nordvpn
```

### 5. Test Connection

In your browser, go to [ipleak.net](https://ipleak.net/).

## Further Reading

- [strongSwan][2]
- [Arch Wiki strongSwan][3]
- [NordVPN Tutorial][9]
- [Migration from ipsec.conf to swanctl.conf][12]
- [strongSwan Configuration Examples][16]
- [Use bypass-lan plugin to fix localhost and Docker with strongSwan][17]

[1]: https://restoreprivacy.com/openvpn-ipsec-wireguard-l2tp-ikev2-protocols/
[2]: https://www.strongswan.org/
[3]: https://wiki.archlinux.org/index.php/StrongSwan
[4]: https://wiki.strongswan.org/projects/strongswan/wiki/UserDocumentation#Used-by-starter-and-the-deprecated-stroke-plugin
[5]: https://wiki.strongswan.org/projects/strongswan/wiki/UserDocumentation#Used-by-swanctl-and-the-preferred-vici-plugin
[6]: https://wiki.archlinux.org/index.php/Systemd
[7]: https://wiki.strongswan.org/projects/strongswan/wiki/ForwardingAndSplitTunneling
[8]: https://en.wikipedia.org/wiki/Extensible_Authentication_Protocol
[9]: https://nordvpn.com/de/tutorials/linux/ikev2ipsec/
[11]: https://github.com/Jguer/yay
[12]: https://wiki.strongswan.org/projects/strongswan/wiki/Fromipsecconf
[13]: https://wiki.strongswan.org/projects/strongswan/wiki/ConstraintsPlugin
[14]: https://wiki.archlinux.org/index.php/StrongSwan#Certificates
[15]: https://wiki.strongswan.org/projects/strongswan/wiki/Swanctl
[16]: https://wiki.strongswan.org/projects/strongswan/wiki/UserDocumentation#Configuration-Examples
[17]: https://www.rockyourcode.com/til-strongswan-using-bypass-lan-plugin-can-fix-docker-routing/