Prerequisites:
Two VPS running Ubuntu 18.04, one to host the OpenVPN service and another to serve as your Certificate Authority (CA). It is not recommended to use your OpenVPN Server as your CA, this opens up your VPN to security vulnerabilities.
A regular (non-root) account with sudo privileges. See our SSH keys tutorial for more information.
NOTE:
If you disable password authentication while configuring these servers, you may run into difficulties when transferring files between them. To resolve this issue, you can re-enable password authentication on each server. Or, can generate an SSH keypair for each server, then add the OpenVPN server’s public SSH key to the CA machine’s authorized_keys file and vice versa.
Step 1: Install OpenVPN and EasyRSA
Let’s start by updating our apt cache and installing openvpn.
$ sudo apt-get update $ sudo apt-get install openvpn
OpenVPN uses SSL/TLS for authentication and key exchange to encrypt traffic between the server and clients.
To issue trusted certificates, you will set up your simple certificate authority (CA).
To do this, we’ll download the latest version of EasyRSA, which we’ll use to build our CA public key infrastructure (PKI), from the project’s official GitHub repository.
NOTE:
It is recommended that you keep the CA server turned off when not being used to sign keys as a further precautionary measure.
To begin building the CA and PKI infrastructure, use wget to download the latest version of EasyRSA on both your CA machine and your OpenVPN server.
wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.6/EasyRSA-unix-v3.0.6.tgz
Then extract the tarball:
cd ~ tar xvf EasyRSA-unix-v3.0.6.tgz
You have successfully installed all the required software on your server and CA machine.
Continue to configure the variables used by EasyRSA and to set up a CA directory, from which you will generate the keys and certificates needed for your server and clients to access the VPN.
Step 2: Set up the certificate authority
EasyRSA comes packaged with a configuration file that can be edited to define several variables for your CA.
On your CA machine, navigate to the EasyRSA directory:
cd ~/EasyRSA-v3.0.6/
We can utilize the easy-rsa template by making a copy of an existing vars.example file in this directory and renaming it vars:
cp vars.example vars
We need to edit some of the variables that help decide how to create the certificates. Use nano — or another favorite editor—to open the file. We’ll be editing some variables toward the end of the file.
nano vars
Find the settings that set field defaults for new certificates. It will look something like this:
#set_var EASYRSA_REQ_COUNTRY "US" #set_var EASYRSA_REQ_PROVINCE "California" #set_var EASYRSA_REQ_CITY "San Francisco" #set_var EASYRSA_REQ_ORG "Copyleft Certificate Co" #set_var EASYRSA_REQ_EMAIL "me@example.net" #set_var EASYRSA_REQ_OU "My Organizational Unit"
Uncomment these lines and update the highlighted values to whatever you’d prefer, but do not leave them blank:
set_var EASYRSA_REQ_COUNTRY "US" set_var EASYRSA_REQ_PROVINCE "NewYork" set_var EASYRSA_REQ_CITY "New York City" set_var EASYRSA_REQ_ORG "RootAdminz" set_var EASYRSA_REQ_EMAIL "vyga@example.net" set_var EASYRSA_REQ_OU "Marketing"
Save and close the file after editing.
Inside the EasyRSA directory is a script called easyrsa which is used to perform a variety of tasks involved with building and managing the CA. Run this script with the init-pki option to initiate the public key infrastructure on the CA server:
./easyrsa init-pki
After this, call the easyrsa script again, following it with the build-ca option. This builds the CA and creates two important files — ca.crt and ca.key — which make up the public and private sides of an SSL certificate.
If you don’t want to be prompted for a password every time you interact with your CA, you can run the build-ca command with the nopass option:
./easyrsa build-ca nopass
In the output, you’ll be asked to confirm the common name for your CA:
The common name is the name used to refer to this machine in the context of the certificate authority. You can enter any string of characters for the CA’s common name but, for simplicity’s sake, press ENTER to accept the default name.
With that, your CA is in place and it’s ready to start signing certificate requests.
Step 3: Create the server certificate and public/private keys
With the CA set up correctly, you can generate a private key and certificate request from your server and then transfer the request over to your CA to be signed, creating the required certificate.
Navigate to the EasyRSA directory on your OpenVPN server:
cd EasyRSA-v3.0.6/
From here, run the easyrsa script with the init-pki option. Although you already ran this command on the CA machine, it’s necessary to run it here because your server and CA will have separate PKI directories:
./easyrsa init-pki
Then call the easyrsa script again, this time with the gen-req option followed by a common name for the machine.
This can be anything you like but for the sake of this tutorial, we’re choosing vpnserver. Include the nopass option, failing to do so will password-protect the request file which could lead to permissions issues later on:
Note: If you choose a name other than “server” here, you will have to adjust some of the instructions below. For instance, when copying the generated files to the /etc/openvpn directory, you will have to substitute the correct names. You will also have to modify the /etc/openvpn/server.conf file later to point to the correct .crt and .key files.
./easyrsa gen-req vpnserver nopass
This will create a private key for the server and a certificate request file called server.req. Copy the server key to the /etc/openvpn/ directory:
sudo cp ~/EasyRSA-v3.0.6/pki/private/vpnserver.key /etc/openvpn/
Using a secure method (like SCP, in our example below), transfer the vpnserver.req file to your CA machine:
scp ~/EasyRSA-v3.0.6/pki/reqs/vpnserver.req vyga@your_CA_ip:/tmp
Next, on your CA machine, navigate to the EasyRSA directory:
cd EasyRSA-v3.0.6/
Using the easyrsa script again, import the vpnserver.req file, following the file path with its common name:
./easyrsa import-req /tmp/vpnserver.req vpnserver
Then sign the request by running the easyrsa script with the sign-req option, followed by the request type and the common name. The request type can either be client or server, so for the OpenVPN server’s certificate request, be sure to use the server request type:
./easyrsa sign-req server vpnserver
If you encrypted your CA key, you’ll be prompted for your password at this point.
Next, transfer the signed certificate back to your VPN server using a secure method:
scp pki/issued/vpnserver.crt vyga@your_server_ip:/tmp
Before logging out of your CA machine, transfer the ca.crt file to your server as well:
scp pki/ca.crt vyga@your_server_ip:/tmp
Next, log back into your OpenVPN server and copy the server.crt and ca.crt files into your /etc/openvpn/ directory:
sudo cp /tmp/{vpnserver.crt,ca.crt} /etc/openvpn/
Then navigate to your EasyRSA directory:
cd EasyRSA-v3.0.6/
From there, create a strong Diffie-Hellman key to use during the key exchange by typing:
./easyrsa gen-dh
This may take a few minutes to complete. Once it does, generate an HMAC signature to strengthen the server’s TLS integrity verification capabilities:
openvpn --genkey --secret ta.key
When the command finishes, copy the two new files to your /etc/openvpn/ directory:
sudo cp ~/EasyRSA-v3.0.6/ta.key /etc/openvpn/ sudo cp ~/EasyRSA-v3.0.6/pki/dh.pem /etc/openvpn/
With all the needed certificate and key files generated, you are set to create the corresponding certificates and keys which will be used by your client machine to access your OpenVPN server.
Step 4: Generate a client certificate and key pair
Create a directory structure within your home directory to store the client certificate and key files:
mkdir -p ~/client-configs/keys
Since your clients’ certificate/key pairs and configuration files will be stored in this directory, lockdown its permissions as a security measure:
chmod -R 700 ~/client-configs
Next, navigate back to the EasyRSA directory and run the easyrsa script with the gen-req and nopass options, along with the common name for the client:
NOTE:
You will need to pass a unique name value to the script for every client. Throughout this tutorial, the first certificate/key pair is referred to as clienta
cd ~/EasyRSA-v3.0.6/ ./easyrsa gen-req clienta nopass
Press ENTER to confirm the common name. Then, copy the clienta.key file to the /client-configs/keys/ directory you created earlier:
cp pki/private/clienta.key ~/client-configs/keys/
Next, securely transfer the clienta.req file to your CA machine:
scp pki/reqs/clienta.req vyga@your_CA_ip:/tmp
Log in to your CA machine, navigate to the EasyRSA directory, and import the certificate request:
ssh vyga@your_CA_ip cd EasyRSA-v3.0.6/ ./easyrsa import-req /tmp/clienta.req clienta
Then sign the request as you did for the server in the previous step. This time, though, be sure to specify the client request type:
./easyrsa sign-req client clienta
At the prompt, enter yes to confirm that you intend to sign the certificate request and that it came from a trusted source. you’d get the following output
Type the word 'yes' to continue, or any other input to abort. Confirm request details: yes
Again, if you encrypted your CA key, you’ll be prompted for your password here.
This will create a client certificate file named clienta.crt. Transfer this file back to the server:
scp pki/issued/clienta.crt vyga@your_server_ip:/tmp
SSH back into your OpenVPN server and copy the client certificate to the /client-configs/keys/ directory:
cp /tmp/clienta.crt ~/client-configs/keys/
Next, copy the ca.crt and ta.key files to the /client-configs/keys/ directory as well:
cp ~/EasyRSA-v3.0.6/ta.key ~/client-configs/keys/ sudo cp /etc/openvpn/ca.crt ~/client-configs/keys/
Your server and client’s certificates and keys have all been generated and are stored in the appropriate directories on your server.
Step 5: Configure the OpenVPN service
Now that both your client and server’s certificates and keys have been generated, you can start configuring the OpenVPN service to run on Ubuntu 18.04 using these credentials.
Begin by copying a sample OpenVPN configuration file into the configuration directory and then extract it to use it as a basis for your setup:
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/ sudo gzip -d /etc/openvpn/server.conf.gz
Open the server configuration file in your preferred text editor:
sudo nano /etc/openvpn/server.conf
Find the HMAC section by looking for the tls-auth directive. This line should already be uncommented, but if isn’t then remove the “;” to uncomment it. Below this line, add the key-direction parameter, set to “0”:
tls-auth ta.key 0 # This file is secret key-direction 0
Next, find the section on cryptographic ciphers by looking for the commented out cipher lines. The AES-256-CBC cipher offers a good level of encryption and is well supported. Again, this line should already be uncommented, but if it isn’t then just remove the “;” preceding it:
cipher AES-256-CBC
Below this, add an auth directive to select the HMAC message-digest algorithm. For this, SHA256 is a good choice:
auth SHA256
If like in this tutorial you selected a different name during the ./build-key-server command earlier, modify the cert and key lines that you see to point to the appropriate .crt and .key files. The default is server, while vpnserver is used in this guide.
cert vpnserver.crt key vpnserver.key
Next, find the line containing a dh directive which defines the Diffie-Hellman parameters. Because of some recent changes made to EasyRSA, the filename for the Diffie-Hellman key may be different than what is listed in the example server configuration file. If necessary, change the file name listed here by removing the 2048 so it aligns with the key you generated in the previous step:
dh dh.pem
Finally, find the user and group settings and remove the “;” at the beginning of each to uncomment these lines:
user nobody group nogroup
The changes you’ve made to the sample server.conf file up to this point are necessary for OpenVPN to function.
When you are finished, save and close the file.
After going through and making whatever changes to your server’s OpenVPN configuration are required for your specific use case, you can begin making some changes to your server’s networking.
Step 6: Start and enable the OpenVPN service
Before we configure our clients, let’s make sure the OpenVPN server is running as we hope it will.
Make sure to turn on TUN/TAP in the SSD Nodes dashboard.
$ sudo systemctl enable openvpn@server $ sudo systemctl start openvpn@server
You can double-check that OpenVPN is running with the systemctl status command:
$ sudo systemctl status openvpn@server
You will also need to set up iptables to properly direct traffic. First, look for the default interface.
$ sudo ip route | grep default
Your output will look like this:
default via 198.51.100.0 dev eth0 proto static
The eth0 field is what we’re looking for. And then we set up iptables. To ensure this rule is persistent between reboots, install the iptables-persistent package, which will prompt you to save existing rules. Choose Yes and your rules will be persisted moving forward.
$ sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE $ sudo apt-get install iptables-persistent
Step 7: Configure clients
Lastly, you need to create client configurations. You can store these in any folder you’d like—they don’t need to be kept secret—as long as it isn’t the /etc/openvpn folder. We’ll create a directory in home for this purpose.
$ cd ~ $ mkdir openvpn-clients cd openvpn-clients
Now, copy the sample client configuration into this new directory, and then open it in nano for editing.
$ cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/openvpn-clients/base.conf $ nano base.conf
Look for the following block of lines. You’ll need to change the my-server-1 to the public IP address of this VPS. You can find this information in the SSD Nodes dashboard, or by typing in the ifconfig command and looking for the inet field that does not look like 127.0.0.x.
# The hostname/IP and port of the server. # You can have multiple remote entries # to load balance between the servers. remote my-server-1 1194 ;remote my-server-2 1194
Next, uncomment the following two lines by removing the semicolon.
Before:
# Downgrade privileges after initialization (non-Windows only) ;user nobody ;group nogroup
After:
# Downgrade privileges after initialization (non-Windows only) user nobody group nogroup
Because we’ll be adding keys and certificates directly into the .ovpn file, let’s comment out the following lines by adding semicolons to the beginning.
Before:
# SSL/TLS parms. # See the server config file for more # description. It's best to use # a separate .crt/.key file pair # for each client. A single ca # file can be used for all clients. ca ca.crt cert client.crt key client.key
After:
# SSL/TLS parms. # See the server config file for more # description. It's best to use # a separate .crt/.key file pair # for each client. A single ca # file can be used for all clients. ;ca ca.crt ;cert client.crt ;key client.key
Finally, jump to the bottom of the file and add the following lines. The first two mirror the cipher/auth options we added to the server.conf file earlier, and the third establishes that this files will be used to connect to the server, not the other way around.
We’re also adding three commented-out files that should be uncommented for Linux-based systems that use update-resolv-conf.
# Added lines via SSD Nodes tutorial cipher AES-256-CBC auth SHA512 key-direction 1 # script-security 2 # up /etc/openvpn/update-resolv-conf # down /etc/openvpn/update-resolv-conf
Finally, you need to embed the keys and certificates into an .ovpn file using base.conf as a framework. Copy this entire command and execute it to embed the keys and create a final client1.ovpn file.
$ cat base.conf <(echo -e '') ~/openvpn-ca/keys/ca.crt <(echo -e '') <(echo -e '') ~/openvpn-ca/keys/client1.crt <(echo -e 'n') <(echo -e '') ~/openvpn-ca/keys/client1.key <(echo -e 'n') <(echo -e '') ~/openvpn-ca/keys/ta.key <(echo -e '') >> client1.ovpn
This tutorial won’t cover client configurations in detail, but we’ll share one easy way to transfer the .ovpn file to your Linux or OS X client. This command will ssh into your VPS, and then use cat to write a new client1.ovpn file on your local machine.
$ ssh USER@SERVER-IP "cat ~/openvpn-clients/client1.ovpn" > client1.ovpn
Once you configure your client, you should be able to connect to the VPN and access the wider internet through it.
You’re now using OpenVPN on Ubuntu 18.04 to protect your data. Your VPN can keep your ISP from seeing your browsing data and add an extra level of of encryption for critical information.