Introduction
In today’s mobile world, securely connecting to the internet from public places like Starbucks or other free Wi-Fi spots is crucial. Hence, I will discuss setting up a personal VPN server. As many are aware, a VPN encrypts your internet traffic, safeguarding it on untrusted networks such as those in coffee shops, conferences, or airports.
First, let’s delve into why I chose IKEv2 over other VPN protocols such as PPTP, L2TP/IPSec, and SSL-VPN. Through extensive testing, I found IKEv2 to be the most stable, fast, and robust option. However, it is slightly more complex to configure compared to its counterparts.
An IKEv2 connection mandates a server certificate. While many tutorials suggest using a self-signed certificate, this requires manual installation on the client, complicating the process. To streamline client connections, I opted for a certificate from Let’s Encrypt.
IKEv2, or Internet Key Exchange version 2, allows for direct IPSec tunneling between the server and client. In IKEv2 VPN implementations, IPSec encrypts the network traffic. IKEv2 is natively supported on most modern platforms (OS X 10.11+, iOS 9.1+, and Windows 10) without additional applications, although Android requires an official VPN client. It also gracefully handles client disconnections.
Today, I will guide you through setting up an IKEv2 VPN server using strongSwan on an Ubuntu 22.04 LTE server and connecting to it from Windows and iOS.
Prerequisites
To complete this set up, you will need:
- Ubuntu 22.04 LTE
- Let’s Encrypt
- Personal domain (for the Let’s Encrypt certificate)
- strongSwan 5.9.5
- Perseverance 😛
Step 1: Setting Up Let’s Encrypt
Install certbot to automatically configure HTTPS using Let’s Encrypt:
$ sudo apt-get install certbot
$ sudo certbot certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log
How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
Plugins selected: Authenticator standalone, Installer None
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel): vpn.yourdomain.com
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for vpn.yourdomain.com
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/vpn.yourdomain.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/vpn.yourdomain.com/privkey.pem
Your cert will expire on 2021-09-16. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-leFollow the prompts to select your authentication method and enter your domain name (e.g., vpn.yourdomain.com). Once complete, your certificate and key files will be saved in /etc/letsencrypt/live/vpn.yourdomain.com/.
Ensure your firewall allows HTTPS traffic to enable certbot verification:
$ sudo ufw status
Status: active
To Action From
-- ------ ----
Anywhere ALLOW my.ip.address
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere Option: Verify certbot auto-renewal:
$ sudo systemctl status certbot.timer
● certbot.timer - Run certbot twice daily
Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Fri 2021-06-18 07:20:58 UTC; 13h ago
Trigger: Fri 2021-06-18 22:53:11 UTC; 1h 50min left
Jun 18 07:20:58 example systemd[1]: Started Run certbot twice daily.To test the renewal process, you can do a dry run with certbot:
$ sudo certbot renew --dry-runAdd a cron job to copy the new certificates and reload the IPsec configuration monthly:
cron job will be run on 1st of every month at 00:00 AM.
$ sudo crontab -e
# m h dom mon dow command
0 0 1 * * root cp –f /etc/letsencrypt/live/vpn.yourdomain.com/fullchain.pem /etc/ipsec.d/certs/fullchain.pem && cp -f /etc/letsencrypt/live/vpn.yourdomain.com/privkey.pem /etc/ipsec.d/private/privkey.pem && cp -f /etc/letsencrypt/live/vpn.yourdomain.com/chain.pem /etc/ipsec.d/cacerts/chain.pem && ipsec rereadallStep 2: Setting Up strongSwan
Install strongSwan:
$ sudo apt-get update
$ sudo apt-get install strongSwanConfigure strongSwan by editing the ipsec.conf file:
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
# strictcrlpolicy=yes
charondebug="all"
uniqueids=no
conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
ike=aes256-sha1-modp1024,3des-sha1-modp1024!
esp=aes256-sha1,3des-sha1!
dpdaction=clear
dpddelay=300s
rekey=no
left=%any
leftid=@vpn.yourdomain.com
leftcert=fullchain.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
right=%any
rightid=%any
rightauth=eap-mschapv2
rightsourceip=192.168.1.0/24
rightdns=8.8.8.8,8.8.4.4
rightsendcert=never
eap_identity=%identity
mobike=yesConfigure VPN authentication in 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 privkey.pem
username : EAP "password"Restart the strongSwan service:
$ sudo systemctl restart strongSwanStep 3: Configuring the Firewall & Kernel IP Forwarding
Allow VPN traffic through the firewall:
$ sudo ufw allow 500/udp
$ sudo ufw allow 4500/udpAdd the following rules to /etc/ufw/before.rules:
$ ip route | grep default
default via my.server.ip.address dev ens3 proto static# For IPSecVPN
*nat
-A POSTROUTING -s 192.168.1.0/24 -o ens3 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 192.168.1.0/24 -o ens3 -j MASQUERADE
COMMIT
*mangle
-A FORWARD --match policy --pol ipsec --dir in -s 192.168.1.0/24 -o ens3 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT
# End
# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines
# For IPSecVPN
-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 192.168.1.0/24 -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 192.168.1.0/24 -j ACCEPT
# End
Ensure kernel parameters in /etc/ufw/sysctl.conf are configured to allow IP forwarding:
net/ipv4/ip_forward=1
net/ipv4/conf/all/accept_redirects=0
net/ipv4/conf/all/send_redirects=0
net/ipv4/ip_no_pmtu_disc=1
Restart the firewall to apply changes:
$ sudo ufw disable
$ sudo ufw enable
Step 4: Deploying Certificate Files
Copy the Let’s Encrypt certificate files to the IPSec directory:
$ sudo cp -f /etc/letsencrypt/live/vpn.mydomain.com/fullchain.pem /etc/ipsec.d/certs/fullchain.pem
$ sudo cp -f /etc/letsencrypt/live/vpn.mydomain.com/chain.pem /etc/ipsec.d/cacerts/chain.pem
$ sudo cp -f /etc/letsencrypt/live/vpn.mydomain.com/privkey.pem /etc/ipsec.d/private/privkey.pem
Step 5: Client Configuration
Windows
- Add the VPN connection in “Settings” > “Network and Internet” > “VPN”.
- Edit the VPN connection: Right-click the VPN connection in “Change adapter options” and select “Properties”.
- On the Security tab, set “Data Encryption” to “Maximum strength encryption (disconnect if server declines)”.
- On the Networking tab, uncheck “Internet Protocol Version 6 (TCP/IPv6)” and check “Use default gateway on remote network” in IPv4 properties.
iOS and macOS
- Create a new VPN connection and set the required items.
- Follow similar steps as for Windows to configure the connection.
Android
- Download the strongSwan VPN client from the Play Store.
- Follow the instructions within the app.
Conclusion
Setting up an IKEv2 VPN server can be complex, particularly with IPSec configurations. However, the security and stability benefits make it worthwhile. By using Let’s Encrypt certificates, the process is simplified, eliminating the need for additional client-side certificate installations. Additionally, the setup allows for secure and unrestricted internet access, even in geographically restricted scenarios. Use this guide to ensure your online activities remain secure wherever you go!