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:
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 user@your_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 user@your_server_ip:/tmp
$ sudo scp pki/ca.crt user@your_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 user@your_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 user@IP_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):
$ sudo nano /etc/ufw/before.rules
Add the commands as in the figure below, replacing "eth0" with the name of your network interface.
# 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
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"
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 user@IP_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 openvpn@server
Restart the Server to implement the changes.