HowtoForge

How to Setup IKEv2 IPSec VPN Using strongSwan and Let's Encrypt on Rocky Linux 9

If you are looking for a client-to-site VPN solution, then you might prefer an IKEv2 EAP solution over OpenVPN or Wireguard. Such a solution is extremely helpful if you are constantly on the move and require a VPN solution you can connect to easily without downloading a client or needing a key. strongSwan is an open-source cross-platform IPSec-based VPN that can prove useful in such a case. It can provide authentication based on X.509 certificates or the secure IKEv2 EAP user authentication.

In this tutorial, you will learn how to set up an IKEv2 IPSec VPN using strongSwan using EAP-MSCHAPv2 authentication along with Let's Encrypt SSL certificates on a Rocky Linux 9 server. You will also learn how to connect to the VPN using Windows, macOS, Linux, and Android clients.

Prerequisites

Step 1 - Configure Networking and Firewall

Enable IP Packet forwarding in the kernel options.

$ echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.conf
$ sudo sysctl -p 

Add IPSec service to Firewalld firewall.

$ sudo firewall-cmd --permanent --add-service=ipsec

We also need HTTP and HTTPS ports to function. Open them.

$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --permanent --add-service=https

Allow NAT packet forwarding, also known as IP masquerade.

$ sudo firewall-cmd --permanent --add-masquerade

Reload the firewall to apply the changes.

$ sudo firewall-cmd --reload

Step 2 - Install SSL

We need to install Certbot to generate the SSL certificate.

We will use the Snapd package installer for that. Since Rocky Linux doesn't ship with it, install the Snapd installer. It requires the EPEL repository to work.

$ sudo dnf install -y epel-release

Install Snapd.

$ sudo dnf install -y snapd

Enable and Start the Snap service.

$ sudo systemctl enable snapd --now

Install the Snap core package, and ensure that your version of Snapd is up to date.

$ sudo snap install core && sudo snap refresh core

Create necessary links for Snapd to work.

$ sudo ln -s /var/lib/snapd/snap /snap
$ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh

Issue the following command to install Certbot.

$ sudo snap install --classic certbot

Use the following command to ensure that the Certbot command can be run by creating a symbolic link to the /usr/bin directory.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Verify the installation.

$ certbot --version
certbot 2.3.0

Run the following command to generate an SSL Certificate.

$ sudo certbot --key-type rsa certonly --standalone --agree-tos --no-eff-email --preferred-challenges http -m name@example.com -d vpn.example.com

The above command will download a certificate to the /etc/letsencrypt/live/vpn.example.com directory on your server.

To check whether the SSL renewal is working fine, do a dry run of the process.

$ sudo certbot renew --dry-run

If you see no errors, you are all set. Your certificate will renew automatically.

Step 3 - Install strongSwan

strongSwan requires the EPEL repository for installation but since we have already installed it in the previous step, you can skip it. Install strongSwan using the following command.

$ sudo dnf install strongswan

Create a symlink for the certificates in the /etc/strongswan/swanctl directory.

$ sudo ln -s /etc/letsencrypt/live/vpn.example.com/fullchain.pem /etc/strongswan/swanctl/x509
$ sudo ln -s /etc/letsencrypt/live/vpn.example.com/privkey.pem /etc/strongswan/swanctl/private
$ sudo ln -s /etc/letsencrypt/live/vpn.example.com/chain.pem /etc/strongswan/swanctl/x509ca

Create a strongSwan configuration file and open it for editing.

$ sudo nano /etc/strongswan/swanctl/conf.d/my_vpn.conf

Paste the following code in it.

connections {
    ikev2-eap-mschapv2 {
        version = 2
        proposals = aes256-sha256-modp4096,aes256-sha256-modp2048,aes256gcm16-sha256-modp1024
        rekey_time = 0s
        pools = pool-ipv4
        fragmentation = yes
        dpd_delay = 30s
        send_cert=always
        unique = never
        local {
            id = vpn.example.com
            certs = fullchain.pem
        }
        remote {
            auth = eap-mschapv2
            eap_id = %any
        }
        children {
            ikev2-eap-mschapv2 {
                local_ts = 0.0.0.0/0
                rekey_time = 0s
                dpd_action = clear
                esp_proposals = aes256-sha256-sha1
            }
        }
    }
}

pools {
    pool-ipv4 {
        addrs = 10.1.1.0/24
        dns = 1.1.1.1, 8.8.8.8
    }
}

secrets {
    eap-User1 {
        id = username1
        secret = "password1"
    }
}

Save the file by pressing Ctrl + X and entering Y when prompted once finished.

If you wish to tunnel both IPv4 and IPv6 through the VPN, you need to assign an IPv6 pool, DNS, and local subnet. Replace the values of the variables local_ts, addrs, and dns with the following values.

local_ts = 0.0.0.0/0,::/0
....
addrs = 10.1.1.0/24,2a00:1450:400c:c05::/112
dns = 8.8.8.8,2001:4860:4860::8888

Disable the OpenSSL plugin because OpenSSL on Rocky Linux 9 doesn't allow RSA signatures with SHA-1 causing authentication failures.

$ sudo sed -i "s/load = yes/load = no/" /etc/strongswan/strongswan.d/charon/openssl.conf

Enable and start the strongSwan service.

$ sudo systemctl enable strongswan
$ sudo systemctl start strongswan

Step 4 - Connecting via Windows

Open the Settings application and select Network and Internet menu option. Select the VPN menu and then click the Add a VPN connection button.

Click the Save button and then select the VPN you added and click the Connect button to start the VPN.

Step 5 - Connecting via macOS

Open System Preferences >> Network and click the plus (+) sign on the top right to add a new service.

Select VPN as the Interface, IKEv2 as the VPN Type and give your service a name. Click the Create button to proceed.

Enter your domain name as the Server Address and Remote ID. Leave the Local ID field empty. Click the Authentication Settings button to open a new popup.

Select Username as Authentication Settings and then enter the credentials created earlier. Click the Ok button to save the setting. Click the Apply button at the bottom to save the setting. And then click the Connect button to connect to the VPN.

Once you have added it, macOS will create a shortcut for the VPN on the menu bar. You can connect to the VPN from there directly.

Step 6 - Connecting via Android

Open Android Settings >> Network and Internet >> VPN menu. Click the plus (+) sign on the top right of the screen to add the VPN profile.

Give the connection a name. Select IKEv2/IPSec MSCHAPv2 as the VPN type. Enter your domain as the server address. Give any random string as the IPSec Identifier. Enter the username and password you gave before. Click the Save button to finish.

Select the Connection name and click Connect to start using the VPN.

Step 7 - Connecting via iOS

Open the iOS settings, and click on the General menu. Click the VPN menu and you will get a similar menu shown below. Select IKEv2 as the VPN Type.

Give your VPN a description. Enter your domain as the value for theĀ Server and Remote ID fields. Leave the Local ID field blank. Select User Authentication as Username and enter your credentials. Select Done when finished and tap on the switch to connect to the VPN.

Conclusion

This concludes our tutorial on setting up IKEv2 VPN using strongSwan and Let's Encrypt SSL on a Rocky Linux 9 server. You also connected to the VPN using multiple clients. If you have any questions, post them in the comments below.

How to Setup IKEv2 IPSec VPN Using strongSwan and Let's Encrypt on Rocky Linux 9