Install the packages:

sudo apt install openvpn easy-rsa

Copy an example config file:

gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | \
sudo tee /etc/openvpn/server.conf
# Listen on UDP port 1194
port 1194
proto udp
proto udp6
# Use a tun device and push an IPv6 tunnel to clients
dev tun
# Certificate settings
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
# Create subnets for the clients
topology subnet
server-ipv6 2001:db8::/64
# Client config directory
client-config-dir ccd
# Have all traffic go through the VPN
push "redirect-gateway def1 bypass-dhcp"
## OpenDNS is used in this example, but anything reachable by the VPN server will work
push "dhcp-option DNS 2620:0:ccc::2"
push "dhcp-option DNS 2620:0:ccd::2"
push "dhcp-option DNS"
push "dhcp-option DNS"
# Allow direct client-to-client connections
# Ping every 10 seconds, assume disconnect after 120 seconds
keepalive 10 120
# TLS parameters
## This is the server
tls-auth ta.key 0
key-direction 0
## Use strong ciphers
cipher AES-256-CBC
auth SHA512
# Run the daemon with minimal privileges
user nobody
group nogroup
# Logging settings
status openvpn-status.log
verb 3
explicit-exit-notify 1

Allow packet forwarding and enable the IPv6 neighbour detection proxy:


Load the kernel parameters:

sudo sysctl -p


If your server gets its IPv6 configuration through SLAAC, also do this:


Load the kernel parameters:

sudo sysctl -p

Firewall rules

Allow masquerading for the OpenVPN subnet:

# OpenVPN
# OpenVPN
-A POSTROUTING -s 2001:db8::/32 -o eth0 -j MASQUERADE

Allow forwarding traffic from the tun0 interface, incoming connections on UDP port 1194, and restart the firewall:

sudo ufw route allow in on tun0 out on eth0
sudo ufw allow 1194/udp
sudo ufw disable && sudo ufw enable

Create a working directory:

make-cadir openvpn-ca
cd openvpn-ca/

Fill in these variables as desired (saves time):

set_var KEY_COUNTRY="..."
set_var KEY_PROVINCE="..."
set_var KEY_CITY="..."
set_var KEY_ORG="..."
set_var KEY_EMAIL="..."
set_var KEY_OU="..."

Initialize the directory:

./easyrsa init-pki

Build a certificate authority:

./easyrsa build-ca nopass

Build a server key called server:

./easyrsa build-server-full server nopass

Build a Diffie-Hellman key:

./easyrsa gen-dh

Generate a pre-shared key:

/usr/sbin/openvpn --genkey secret pki/ta.key

Copy the generated keys to the server configuration directory:

cd pki/
sudo cp ca.crt private/ca.key issued/server.crt private/server.key ta.key dh.pem /etc/openvpn/
sudo cp dh.pem /etc/openvpn/dh2048.pem

Restart the server:

sudo systemctl daemon-reload
sudo systemctl restart openvpn@server.service

Create a working directory next to openvpn-ca:

cd ../../
mkdir -p client-configs/files/
cd client-configs/

Client configuration

Add a base configuration file for your clients:

# Specify that we are a client
# Use the same setting as you are using on the server
dev tun
# Connect to the server on UDP port 1194
proto udp
remote 1194
# Run the daemon with minimal privileges
user nobody
group nogroup
# Unset these defaults (certificates will be provided by the .ovpn file)
#ca ca.crt
#cert client.crt
#key client.key
# Use strong ciphers
cipher AES-256-CBC
auth SHA512
# This is the client
key-direction 1
# Run these scripts after connecting (sets up DNS)
script-security 2
up /etc/openvpn/update-systemd-resolved
down /etc/openvpn/update-systemd-resolved
dhcp-option DNSSEC allow-downgrade
dhcp-option DOMAIN-ROUTE .

Build script

Add a configuration build script:
cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${KEY_DIR}/issued/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${KEY_DIR}/private/${1}.key \
    <(echo -e '</key>\n<tls-auth>') \
    ${KEY_DIR}/ta.key \
    <(echo -e '</tls-auth>') \
    > ${OUTPUT_DIR}/${1}.ovpn

Make it executable:

chmod 750 ./

Build a client certificate with password:

cd openvpn-ca/
./easyrsa build-client-full $name

Create a client configuration file:

cd ../client-configs/
./ $name

The resulting configuration will be in client-configs/files/$name.ovpn

Copy this to your client with SFTP. Repeat as many times as desired.

Generation script

cd ~

You can also use a script to automatically generate certificates and configurations:
cd $root/openvpn-ca/
./easyrsa build-client-full $name nopass
cd $root/client-configs/
./ $name
echo Generated $root/client-configs/files/$name.ovpn
exit 0

Make it executable:

chmod 750 ./

Revoke the certificate:

cd openvpn-ca/
./easyrsa revoke $name
./easyrsa gen-crl

Copy the revocation list to the server configuration directory:

sudo cp ./pki/crl.pem /etc/openvpn/

Make sure that the OpenVPN server configuration file contains this line:

crl-verify crl.pem

Then restart the server:

sudo systemctl restart openvpn@server

sudo apt install network-manager-openvpn-gnome

Then simply import the .ovpn file with NetworkManager.