Set Up a VPN Server with StrongSwan on Ubuntu 16.04

  VPN

About VPN

A virtual private network extends a private network across a public network, and enables users to send and receive data across shared or public networks as if their computing devices were directly connected to the private network.

Install strongswan on your machine. Here we also insatlling the strongswan EAP plugin, which allows password authentication for clients.

apt-get install strongswan strongswan-plugin-eap-mschapv2 moreutils iptables-persistent

Creating certificates for authentication

First, create a directory to save the certificate files.

mkdir certs
cd certs

Execute the following commands to generate and secure the key:

ipsec pki --gen --type rsa --size 4096 --outform pem > server-root-key.pem
chmod 600 server-root-key.pem

We already have a key, now we can create our root certificate authority:

ipsec pki --self --ca --lifetime 3650 \
--in server-root-key.pem \
--type rsa --dn "C=IN, O=Spotfixcrew, CN=Spotfixcrew CA" \
--outform pem > server-root-ca.pem

You can change the –dn values, such as country, organization, and common name, to anything you like.

You have to copy server-root-ca.pem to your client devices so they can verify the authenticity of the server when they connect.

Now we have to create a private key and certificate for the use of VPN server.

First, create a private key for the VPN server with the following command:

ipsec pki --gen --type rsa --size 4096 --outform pem > vpn-server-key.pem

Then create and sign the VPN server certificate with the certificate authority’s key you created in the previous step.

ipsec pki --pub --in vpn-server-key.pem \
--type rsa | ipsec pki --issue --lifetime 1825 \
--cacert server-root-ca.pem \
--cakey server-root-key.pem \
--dn "C=IN, O=Spotfixcrew, CN=your_ip" \
--san your_ip \
--flag serverAuth --flag ikeIntermediate \
--outform pem > vpn-server-cert.pem

Note: Change the Common Name (CN) and the Subject Alternate Name (SAN) field to your VPN server’s IP address.

Copy the certificates to a path where StrongSwan look for the certificates:

cp ./vpn-server-cert.pem /etc/ipsec.d/certs/vpn-server-cert.pem
cp ./vpn-server-key.pem /etc/ipsec.d/private/vpn-server-key.pem

Secure the keys:

chown root /etc/ipsec.d/private/vpn-server-key.pem
chgrp root /etc/ipsec.d/private/vpn-server-key.pem
chmod 600 /etc/ipsec.d/private/vpn-server-key.pem

Configure Strongswan

First, take a backup of default configuration file.

cp /etc/ipsec.conf /etc/ipsec.conf.original

Remove all the contents from default configuration file to avoid the mix up of configuration.

echo ' ' | tee /etc/ipsec.conf

Open the configuration file

vi /etc/ipsec.conf

Add the following entries:     

config setup
    charondebug="ike 1, knl 1, cfg 0"
    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
    [email protected]_ip
    leftcert=/etc/ipsec.d/certs/vpn-server-cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=%any
    rightauth=eap-mschapv2
    rightdns=8.8.8.8,8.8.4.4
    rightsourceip=10.10.10.0/24
    rightsendcert=never
    eap_identity=%identity

Replace the entry @your_ip with your machine’s ip.

Configure VPN Authentication

vi /etc/ipsec.secrets

Add the following entries:

Path to Private key

your_ip : RSA "/etc/ipsec.d/private/vpn-server-key.pem

Username and password combination

your_username %any% : EAP "your_password"

Reload the VPN service

ipsec reload

Configure the Firewall

Disable UFW

ufw disable
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -Z

Firewall settings for SSH (Port 22):

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Accept connections on the local loopback interface:

iptables -A INPUT -i lo -j ACCEPT

Accept IPSec connections:

iptables -A INPUT -p udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp --dport 4500 -j ACCEPT

IPTables to forward ESP (Encapsulating Security Payload)

iptables -A FORWARD --match policy --pol ipsec --dir in  --proto esp -s 10.10.10.10/24 -j ACCEPT

iptables -A FORWARD --match policy --pol ipsec --dir out --proto esp -d 10.10.10.10/24 -j ACCEPT

VPN server only have a single public IP address, you need to configure masquerading to allow the server to request data from the internet on behalf of the clients.

iptables -t nat -A POSTROUTING -s 10.10.10.10/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT

iptables -t nat -A POSTROUTING -s 10.10.10.10/24 -o eth0 -j MASQUERADE

To avoid IP packet fragmentation on some clients, set IPTables to reduce the size of packets by adjusting the packets maximum segment size.

iptables -t mangle -A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.10/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360

For better security, we’ll drop every other rules.

iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP

Save all firewall configuration.

netfilter-persistent save
netfilter-persistent reload

Edit the file /etc/sysctl.conf

vi /etc/sysctl.conf

Add the following entries:

...
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
...
# 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
...
net.ipv4.ip_no_pmtu_disc = 1

Then restart the server.

reboot

Testing the VPN Connection on Ubuntu

First, update system packages

apt update

Install Charon-cmd and the related software

apt install charon-cmd libcharon-extra-plugins

Move to the directory where you copied the CA certificate

cd /path/to/CA.pem

Connect to the VPN server with charon-cmd using the CA certificate, the server’s IP address and the username.

charon-cmd --cert CA.pem --host server_ip --identity username

Provide VPN user’s password when prompted.

LEAVE A COMMENT