OpenVPN server on Ubuntu 18.06

Install openvpn server on Ubuntu 18.06

Setup server

Leverage an AWS instance

Leverage an instance with:

  • "Source/Destination Check" disabled.

  • Firewall open on port 1194/UDP.

Configure IP forward

Run:

nano /etc/sysctl.conf

Enable net.ipv4.ip_forward:

net.ipv4.ip_forward=1

Apply changes:

sysctl -p

If you are using ufw...

Get your default network card:

ip route | grep default

Output example:

default via 172.31.0.1 dev eth0 proto dhcp src 172.31.10.197 metric 100

Edit ufw config:

nano /etc/ufw/before.rules

Add the block START OPENVPN RULES and END OPENVPN RULES:

#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0] 
# Allow traffic from OpenVPN client to wlp11s0 (change to the interface you discovered!)
-A POSTROUTING -s 10.22.0.0/16 -o eth0 -j MASQUERADE
-A POSTROUTING -s 3.4.3.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

# Don't delete these required lines, otherwise there will be errors
*filter

Edit ufw default config:

nano /etc/default/ufw

Allow forward:

 DEFAULT_FORWARD_POLICY="ACCEPT"

Allow openvpn and SSH:

ufw allow 1194/udp
ufw allow OpenSSH

Install Openvpn

Run:

apt update
apt install openvpn

Download EasyRSA:

wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.4/EasyRSA-3.0.4.tgz
tar xvf EasyRSA-3.0.4.tgz

Copy and edit vars:

cd ~/EasyRSA-3.0.4/
cp vars.example vars
nano vars

Uncomment and change the following config:

set_var EASYRSA_REQ_COUNTRY     "AU"
set_var EASYRSA_REQ_PROVINCE    "New South Wales"
set_var EASYRSA_REQ_CITY        "Sydney"
set_var EASYRSA_REQ_ORG         "Your Company"
set_var EASYRSA_REQ_EMAIL       "hostmaster@yourcompany.com"
set_var EASYRSA_REQ_OU          "Your Company"

Initiate the public key:

./easyrsa init-pki

Build CA certificate. Keep the default Common Name and hit enter:

./easyrsa build-ca nopass

Create a private key for the server and a certificate request:

./easyrsa gen-req server nopass

Copy the server key to the /etc/openvpn/ directory:

cp ~/EasyRSA-3.0.4/pki/private/server.key /etc/openvpn/

Sign the request. Input yes when prompted:

./easyrsa sign-req server server

Sign the request. Input yes when prompted:

./easyrsa sign-req server server

Copy certificates to openvpn dir:

cp ./pki/issued/server.crt /etc/openvpn/
cp ./pki/ca.crt /etc/openvpn/

Create a strong Diffie-Hellman key to use during key exchange (may take a few minutes to complete):

./easyrsa gen-dh

Generate an HMAC signature to strengthen the server's TLS integrity verification capabilities:

openvpn --genkey --secret ta.key

Copy the files to openvpn dir:

sudo cp ~/EasyRSA-3.0.4/ta.key /etc/openvpn/
sudo cp ~/EasyRSA-3.0.4/pki/dh.pem /etc/openvpn/

Configuring the OpenVPN Service

Copy sample config:

sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz

Edit server config:

nano /etc/openvpn/server.conf

Double check tls-auth and add key-direction:

tls-auth ta.key 0
key-direction 0

Double check cipher and add auth:

cipher AES-256-CBC
auth SHA256

Change dh:

#dh dh2048.pem
dh dh.pem

Enable user and group:

user nobody
group nogroup

Enable client-to-client:

client-to-client

Start and enable service:

systemctl enable openvpn@server
systemctl restart openvpn@server
systemctl status openvpn@server

Setup client config

Run:

mkdir -p ~/client-configs/keys
mkdir -p ~/client-configs/files
chmod -R 700 ~/client-configs
cp ~/EasyRSA-3.0.4/ta.key ~/client-configs/keys/
cp ~/EasyRSA-3.0.4/pki/ca.crt ~/client-configs/keys/
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
nano ~/client-configs/base.conf

Config remote server:

#remote my-server-1 1194
remote YOUR-VPN-SERVER-DOMAIN 1194

Double check proto:

proto udp

Enable user and group:

user nobody
group nogroup

Comment out certificates (they are provided in the .ovpn file):

#ca ca.crt
#cert client.crt
#key client.key

Double check cipher and add auth:

cipher AES-256-CBC
auth SHA256

Add these lines in the end of the file. The last ones are commented out (only need to enable them for Linux clients that ship with an /etc/openvpn/update-resolv-conf file):

key-direction 1
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf

Create a script to compile the base config:

nano ~/client-configs/make_config.sh

Add:

#!/bin/bash

# First argument: Client identifier

KEY_DIR=~/client-configs/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '</key>\n<tls-auth>') \
    ${KEY_DIR}/ta.key \
    <(echo -e '</tls-auth>') \
    > ${OUTPUT_DIR}/${1}.ovpn

Set permissions:

chmod 700 ~/client-configs/make_config.sh

Add client certificate

Generate certificate:

cd ~/EasyRSA-3.0.4
./easyrsa gen-req client2 nopass
./easyrsa sign-req client client2
cp pki/private/client2.key ~/client-configs/keys/
cp pki/issued/client2.crt ~/client-configs/keys/
cd ~/client-configs
./make_config.sh client2
ls files/client2.ovpn

References

https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-18-04

https://hackernoon.com/using-a-vpn-server-to-connect-to-your-aws-vpc-for-just-the-cost-of-an-ec2-nano-instance-3c81269c71c2

Revoke certificate

Run EasyRsa revoke command. Type yes when prompted:

cd /root/EasyRSA-3.0.4
./easyrsa revoke client2

Create a certificate revocation list (CRL):

./easyrsa gen-crl

Copy the CRL to the server config folder:

cp pki/crl.pem /etc/openvpn

Edit server config:

nano /etc/openvpn/server.conf

Add the following line to the end of the file:

crl-verify crl.pem

Restart server:

sudo systemctl restart openvpn@server

References

https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-18-04

Multi instances

Copy your current server config:

cd /etc/openvpn/
cp server.conf server2.conf

Edit the new file:

nano server2.conf

Change the following config:

port XXXX
server X.X.X.0 255.255.255.0

Start the server:

systemctl start openvpn@server2.service
systemctl enable openvpn@server2.service

References

https://www.hugeserver.com/kb/openvpn-multiple-ports/

Fixed IP for clients

Edit servers config:

nano /etc/openvpn/server.conf

Uncomment the following line:

client-config-dir ccd

Create the dir:

mkdir /etc/openvpn/ccd/

Create a file with same CN name used in the certificate:

nano /etc/openvpn/ccd/client-cn-name

Define the static IP:

ifconfig-push 10.8.0.2 255.255.0.0

Restart server:

systemctl restart openvpn@server

References

https://www.itsfullofstars.de/2018/09/openvpn-assign-static-ip-to-client/

https://serverfault.com/questions/826560/how-to-set-a-static-ip-client-side-in-openvpn

Restrict Client-to-client

Edit server config:

nano server-cluster.conf

Make sure the option client-to-client is disabled:

;client-to-client

Add the following line in the end of the file to route all traffic to the VPN server:

push "route 10.8.0.0 255.255.0.0"

Configure iptables:

# Allow all traffic from 10.22.0.100 (K8s master)
iptables -A FORWARD -s 10.22.0.100 -j ACCEPT

# Allow all traffic to 10.22.0.100 (K8s master)
iptables -A FORWARD -d 10.22.0.100 -j ACCEPT

# Allow all traffic between two nodes
iptables -A FORWARD -s 10.22.0.101 -d 10.22.0.102 -j ACCEPT
iptables -A FORWARD -s 10.22.0.102 -d 10.22.0.101 -j ACCEPT

# Drop everything else
iptables -A FORWARD -j DROP

References

https://backreference.org/2010/05/02/controlling-client-to-client-connections-in-openvpn/

Debug

Check service:

systemctl status openvpn@server.service

Monitor packets on interface tun0:

tcpdump -i tun0 -nn -s0 -v
tcpdump -i tun0 -nn -s0 -v port 6805

Monitor ping on interface vpn-cluster with buffer size 512 (it is not set, the “packets dropped by kernel” will always be zero):

tcpdump -i vpn-cluster -B 4096 -n icmp

Check open port:

netstat -a |grep 1194

Last updated