Tutorials > How to set up and configure a VPN with OpenVPN on Ubuntu 18.04

How to set up and configure a VPN with OpenVPN on Ubuntu 18.04

Published on: 20 January 2020

Security Ubuntu VPN

A VPN is a Virtual Private Network that allows you to access the Internet or certain services even from an untrusted network.  Basically, it is as if you were physically connected to a private network: for example, you can access your bank account or make payments without fearing that someone is intercepting the traffic generated by your device.

OpenVPN is a VPN based on TLS (Transport Layer Security) and SSL (Secure Sockets Layer) protocols. OpenVPN uses some certificates to encrypt the traffic between the server and the client.

In this tutorial you will see how to configure OpenVPN on a server with Ubuntu 18.04.

To implement this tutorial a server machine and another machine acting as CA (Certification Authority), which will assess the validity of the certificates, are needed. 

You will need to connect to your server and your CA via an SSH connection. If you haven’t done so yet, following our guide is recommendedto connect securely with the SSH protocol.

Installing OpenVPN

Access your server.

OpenVPN is already available on the official Ubuntu repository of Ubuntu , therefore, there is no need to add anything else.

Type:

sudo apt update
sudo apt install openvpn

By this point,  OpenVPN will have been successfully installed on your server.

Installing EasyRSA 

Continue by downloading EasyRSA on your Server and on your CA by typing on both machines:

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

The latest version can be downloaded from https://github.com/OpenVPN/easy-rsa/releases

$ cd ~
$ sudo tar xvf EasyRSA-3.0.4.tgz

The name may be different depending on the version downloaded 

Configuration of the server

Complete the server configuration by typing:

$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
$ sudo gzip -d /etc/openvpn/server.conf.gz
$ sudo nano /etc/openvpn/server.conf
  • Find the section that refers to HMAC ("tls-auth"). If the line is commented, remove the ";".

  • Find the section on encryption ("cipher"). If commented, remove the ";". Add a new line containing the text "auth SHA256" right below .

  • Find the "dh" section defining the Diffie-Hellman parameters and remove "2048" from the name ( "dh dh.pem" should be obtained).

  • Find the "user" and "group" section and remove the ";" to uncomment the lines.

Configuring EasyRSA on the CA

After installing EasyRSA, a configuration file to define the variables for your CA has been created on your CA. Type:

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

Remove the "#" to the instructions shown in the figure below:

EasyRSA Variables

Start the "easyrsa" script to initialize the Public Key Infrastructure (PKI):

$ sudo ./easyrsa init-pki
$ sudo ./easyrsa build-ca nopass

with this command two files will be created:

  • ca.crt: public CA certificate used by servers and clients to mutually notify that they are part of the same trusted network.

  • ca.key: private key that the CA machine uses to sign keys and certificates for servers and clients. This file must be kept only on the CA machine (which is not accessible by third parties)otherwise network security may be compromised.

You will be required to enter a name. Leave it blank and press Enter.

Requesting a server certificate from the CA

Now that the CA Machine is configured,  have the server generate a private key and a certificate request and send them to the CA Machine to have them signed:

$ cd ~/EasyRSA-3.0.4
$ ./easyrsa init-pki
$ ./easyrsa gen-req server nopass

For simplicity, leave "server" as name for the machine, to avoid making several changes later.

You have just created a private key for the server and a certificate request called "server.req":

$ sudo cp ~/EasyRSA-v3.0.6/pki/private/server.key /etc/openvpn/

Copy the server.req file to the CA machine:

$ sudo scp ~/EasyRSA-3.0.4/pki/reqs/server.req [email protected]_CA_ip:/tmp

Generating and signing the certificate

On your CA in the EasyRSA folder, import the file you just copied and sign it:

$ cd ~/EasyRSA-3.0.4/
$ sudo ./easyrsa import-req /tmp/server.req server
$ sudo ./easyrsa sign-req server server

Type “yes” and press Enter.

Transfer the signed certificate and the ca.crt to the VPN Server:

$ sudo scp pki/issued/server.crt [email protected]_server_ip:/tmp
$ sudo scp pki/ca.crt [email protected]_server_ip:/tmp

Then in your Server 

copy the files received in the appropriate directories:

$ sudo cp /tmp/{server.crt,ca.crt} /etc/openvpn/
$ cd ~/EasyRSA-3.0.4/

Generate a strong exchange key based on Diffie-Hellman.

$ sudo ./easyrsa gen-dh
$ sudo openvpn --genkey --secret ta.key

Copy the files generated  to the "/ etc / openvpn /" folder

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

Configuration of a client

Create a folder to store certificates and keys of the client (since this guide presents only one client, it is here called ‘client1’, but the operation has to be repeated for each client, using a different denomination)

$ sudo mkdir -p ~/client-configs/keys
$ sudo chmod -R 700 ~/client-configs
$ cd ~/EasyRSA-3.0.4/
$ sudo ./easyrsa gen-req client1 nopass

Press Enter to accept the proposed standard name.

$ sudo cp pki/private/client1.key ~/client-configs/keys/

Copy the client’s key to the previously created folder.

$ sudo scp pki/reqs/client1.req [email protected]_CA_IP:/tmp

Send the client1.req file to the CA Machine.

Import the certificate request on your CA:

$ cd ~/EasyRSA-3.0.4/
$ sudo ./easyrsa import-req /tmp/client1.req client1
$ sudo ./easyrsa sign-req client client1

Type "yes" to authorize the signature.

Upload client1.crt on you server:

scp pki/issued/client1.crt [email protected]_SERVER:/tmp

On your Server, copy the following files into the appropriate folders.

$ sudo mkdir -p ~/client-configs/keys

$ sudo chmod -R 700 ~/client-configs

$ sudo cp /tmp/client1.crt ~/client-configs/keys/

$ sudo cp ~/EasyRSA-3.0.4/ta.key ~/client-configs/keys/

$ sudo cp /etc/openvpn/ca.crt ~/client-configs/keys/

Now both the certificates and the keys of the server and client have been generated.

Configuring IP routing and firewall

 Change the IP forwarding rules:

$ sudo nano /etc/sysctl.conf

Find the "net.ipv4.ip_forward" section and remove the "#" to make the instruction "not commented".

 Change some firewall rules in order to correctly route client connections.

$ ip route | grep default

Store the name after "dev" ( named "eth0" in the figure below):

Network Interface

$ sudo nano /etc/ufw/before.rules

Add the commands as in the figure below, replacing "eth0" with the name of your network interface.

OpenVPN Rules

# START OPENVPN RULES

# NAT table rules

*nat

:POSTROUTING ACCEPT [0:0] 

# Allow traffic from OpenVPN client to eth0 

-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE

COMMIT

# END OPENVPN RULES

Save and exit. Now edit the UFW config file:

$ sudo nano /etc/default/ufw

Change the value of the parameter "DEFAULT_FORWARD_POLICY" with "ACCEPT".

$ sudo ufw allow 1194/udp

Add port 1194 for UDP traffic.

$ sudo ufw allow OpenSSH

Restart UFW:

$ sudo ufw disable

$ sudo ufw enable

Start the OpenVPN service:

$ sudo systemctl start openvpn

Check the service status:

$ sudo systemctl status openvpn

OpenVPN Service Status

Set service at server startup.

$ sudo systemctl enable openvpn

Create the configuration file for the client:

$ sudo mkdir -p ~/client-configs/files
$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
$ sudo nano ~/client-configs/base.conf

Find the "remote" section and make sure it says "remote IP_Server 1194"

  • IP_Server: write the Server IP

  • 1194: port previously selected.

Find the "proto" section to make sure the server is set to UDP (you'll find the TCP line commented with a ";").

Find the "user" and "group" section and remove the ";" to make them "no comments".

Find the sections "ca.crt" - "client.crt" - "client.key" - "ta.key" and comment them with a "#" at the beginning of each line.

Find the "cipher" section and add the "auth SHA256" statement under the "cipher AES-256-CBC" statement.

Add the "key-direction 1" instruction at any point.

Add these commented lines at any point. If the client is a Linux machine,  make them "no comments".

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

Save and exit.

Generating the configuration for clients

On your Server, create a script to automatically compile a client's configuration.

nano ~/client-configs/make_config.sh

Copy and paste the text:

#!/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

Save and exit.

chmod 700 ~/client-configs/make_config.sh

Try now to generate the client client "configuration".

$ cd ~/client-configs
$ sudo ./make_config.sh client1

A file called “client1.ovpn” will be created.

Now transfer this file to the device you want to use. It will be used by the VPN software for the connection. 

Revoking Client certificates

$ cd EasyRSA-3.0.4/
$ sudo ./easyrsa revoke client1

client1 is name of the client to which authorizations are to be revoked

Type "yes" to confirm.
Generate and upload the crl.pem file to your server:

$ sudo ./easyrsa gen-crl
$ sudo scp ~/EasyRSA-3.0.4/pki/crl.pem [email protected]_Server:/tmp

Update the configuration of your server machine to verify the revocation.

$ sudo cp /tmp/crl.pem /etc/openvpn
$ sudo nano /etc/openvpn/server.conf

At the end of the file add "crl-verify crl.pem".

Save and exit.

$ sudo systemctl restart [email protected]

Restart the Server to implement the changes.