How to Install and Configure OpenVPN Server on Ubuntu 22.04

A Virtual Private Network (VPN) allows you to access the internet by masking your location, allowing you to access the internet safely on untrusted networks and circumvent geographical restrictions and censorship. OpenVPN is an open-source Transport Layer Security (TLS) VPN solution to achieve this goal.

In our tutorial, we will install OpenVPN on a Ubuntu 22.04 server, configure it to be accessible from a client machine, and create a VPN connection between them to redirect all the traffic from the client through the OpenVPN server.

Prerequisites

  • A server running Ubuntu 22.04 supporting both IPv4 and IPv6 connections. We will refer to this as the OpenVPN server. The uncomplicated Firewall(UFW) is enabled and running on it.

  • A server running Ubuntu 22.04 supporting both IPv4 and IPv6 connections. We will set this up as a private Certificate Authority (CA), which we will refer to as the CA server.

  • A non-root user with sudo privileges on both OpenVPN and the CA server.

  • A client machine to connect to the OpenVPN server. You can use your local device as the client machine. OpenVPN has clients for Windows, Linux, macOS, Android, and iOS. You can use either of them to connect. We will use a Ubuntu 22.04 client PC for the tutorial.

  • Everything is updated on the OpenVPN and the CA server.

    $ sudo apt update && sudo apt upgrade
    

Step 1 - Setting up the CA server

A Certificate Authority (CA) is an entity responsible for issuing digital certificates to verify identities on the Internet. In this tutorial, we will use a standalone server as the private CA server which will validate the OpenVPN server and client certificates. Your CA server should not run any other services other than importing, signing, and validating certificates.

Step 1.1 - Install Easy-RSA

The first step is to install the easy-rsa set of scripts. easy-rsa is a Certificate Authority management tool used to generate a private key, and public root certificate.

$ sudo apt install easy-rsa

Step 1.2 - Create a Public Key Infrastructure Directory

The next step is to create a skeleton Public Key Infrastructure (PKI) on the CA server.

$ mkdir ~/easy-rsa

Create symbolic links pointing to the installed easy-rsa package files.

$ ln -s /usr/share/easy-rsa/* ~/easy-rsa/

Restrict access to the PKI directory.

$ chmod 700 /home/<username>/easy-rsa

Initialize the PKI.

$ cd ~/easy-rsa
$ ./easyrsa init-pki

You will get the following output.

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/<username>/easy-rsa/pki

Step 1.3 - Create a Certificate Authority

Before you can create your CA's private key and certificate, you need to configure the organization information for it. Create vars file to store the information inside the easy-rsa directory and open it for editing.

$ cd ~/easy-rsa
$ nano vars

Paste the following code in it.

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        "Howtoforge"
set_var EASYRSA_REQ_EMAIL      "[email protected]"
set_var EASYRSA_REQ_OU         "Community"
set_var EASYRSA_ALGO           "ec"
set_var EASYRSA_DIGEST         "sha512"

Save the file by pressing Ctrl + X and entering Y when prompted.

Run the following command to create the root public and private key pair for your Certificate Authority.

$ ./easyrsa build-ca

You will be prompted to enter a passphrase for your key pair. Choose a strong passphrase, and note it for later. You will also be asked for the Common Name (CN) for your CA. You can enter any string but for simplicity stake, press ENTER to accept the default name.

Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/home/<username>/easy-rsa/pki/ca.crt

If you don't want to be prompted for a password every time you interact with your CA, you can use the following command instead.

$ ./easyrsa build-ca nopass

This will create two files:

  • ~/easy-rsa/pki/ca.crt is the CA's public certificate file. Every user and the OpenVPN server will need a copy of this file.
  • ~/easy-rsa/pki/ca.key is the private key used by the CA to sign certificates for the OpenVPN server and client. If an attacker gains access to your CA and, in turn, your ca.key file, you will need to destroy your CA. This is why your ca.key file should only be on your CA machine and that, ideally, your CA machine should be kept offline when not signing certificate requests as an extra security measure.

Step 2 - Installing OpenVPN and Easy-RSA on the OpenVPN server

Log in to your OpenVPN server and install OpenVPN and Easy-RSA packages.

$ sudo apt install openvpn easy-rsa

Create the directory ~/easy-rsa.

$ mkdir ~/easy-rsa

Create a symbolic link from the easy-rsa script that we installed just like on the CA server.

$ ln -s /usr/share/easy-rsa/* ~/easy-rsa/

Restrict access to the directory.

$ chmod 700 ~/easy-rsa

Step 3 - Creating a PKI for OpenVPN Server

Create a vars file inside the ~/easy-rsa directory to store the required information to create the PKI and open it for editing.

$ cd ~/easy-rsa
$ nano vars

Paste the following lines in it.

set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "sha512"

Since we are not using this server as the CA, these are the only values we need. This configures your OpenVPN & CA servers to use ECC which means when a client and server attempt to establish a shared symmetric key, they use Elliptic Curve algorithms to do their exchange. It is significantly faster than using plain Diffie-Hellman with the classic RSA algorithm since the numbers are much smaller and the computations are faster.

The next step is to create the PKI directory by using the init-pki option. Although you already ran this command on the CA server as part of the prerequisites, it’s necessary to run it here because your OpenVPN server and CA server have separate PKI directories.

$ ./easyrsa init-pki

The PKI on the OpenVPN server is used as a centralized place to store certificate requests and public certificates.

Step 4 - Create OpenVPN Server Certificate Request and Private Key

Switch to the ~/easy-rsa directory on the OpenVPN server.

$ cd ~/easy-rsa

The next step is to generate a private key and Certificate Signing Request (CSR) on your OpenVPN server. Run the easy-rsa command with the gen-req option followed by a Common Name (CN) for the server. For our tutorial, we will use server as the CN for the OpenVPN server. We will also use the nopass option to avoid any permission issues.

$ ./easyrsa gen-req server nopass

You will get the following output.

Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
..........+.....+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....................+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+..+......+.......+...+..+.+.....+....+..+...+............+.+...+.....+....+...........+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+...+......+.....+....+...........+...+..........+..+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*............+.+..+....+..............+.....................+....+......+..............+.+.....+....+............+..+............+....+..+...+.......+.....+....+...+..+.........+.+.........+..+...+.+..............+.+.........+...........+.+.....+.........+...+......+.+......+.....+..........+...+..............+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [server]:

Keypair and certificate request completed. Your files are:
req: /home/<username>/easy-rsa/pki/reqs/server.req
key: /home/<username>/easy-rsa/pki/private/server.key

This creates a private key for the server and a certificate request file called server.req. Copy the server key to the /etc/openvpn/server directory.

$ sudo cp /home/<username>/easy-rsa/pki/private/server.key /etc/openvpn/server/

The Certificate Signing Request (CSR) is now ready for signing by the CA.

Step 5 - Signing the OpenVPN Server's CSR

The next step is to copy the CSR file to the CA server for signing. If your servers have password authentication enabled, you can simply use the following command to copy the file.

$ scp /home/username/easy-rsa/pki/reqs/server.req username@your_ca_server_ip:/tmp

If you don't want to use password authentication, you will need to 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.

If you don't want to go through all this, you can simply copy the files. Open the file on the OpenVPN server, copy its contents, and then create the file on the CA server and paste the contents.

Log back into the CA Server, and switch to the ~/easy-rsa directory and import the CSR file.

$ cd ~/easy-rsa
$ ./easyrsa import-req /tmp/server.req server

You will get the following output.

Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

The request has been successfully imported with a short name of: server
You may now use this name to perform signing operations on this request.

Sign the request using the following command. Since we are signing the OpenVPN server's CSR, we will use its Common Name (CN).

$ ./easyrsa sign-req server server

You will be prompted to verify if the request comes from a trusted source. Type yes then press ENTER key to confirm.

Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)


You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a server certificate for 825 days:

subject=
    commonName                = server


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes

Next, you will be prompted for the CA private key passphrase which you set up earlier.

Using configuration from /home/<username>/easy-rsa/pki/easy-rsa-13476.9IC4QC/tmp.lPVwQo
Enter pass phrase for /home/<username>/easy-rsa/pki/private/ca.key:
40975B6A677F0000:error:0700006C:configuration file routines:NCONF_get_string:no value:../crypto/conf/conf_lib.c:315:group=<NULL> name=unique_subject
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until May  8 12:41:46 2025 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /home/<username>/easy-rsa/pki/issued/server.crt

The resulting certificate contains the OpenVPN server's public encryption key as well as the signature from the CA server. Copy the certificates back to the OpenVPN server.

$ scp pki/issued/server.crt username@your_vpn_server_ip:/tmp
$ scp pki/ca.crt username@your_vpn_server_ip:/tmp

On your OpenVPN server, copy the files to the /etc/openvpn/server directory.

$ sudo cp /tmp/{server.crt,ca.crt} /etc/openvpn/server

Step 6 - Configure OpenVPN Cryptographic Material

We will add an extra shared secret key that the server and all clients will use with OpenVPN's tls-crypt directive. This ensures that the OpenVPN server is able to cope with unauthenticated traffic, port scans, and Denial of Service attacks. It also makes it harder to identify OpenVPN network traffic.

Switch to the ~/easy-rsa directory.

$ cd ~/easy-rsa

Generate the tls-crypt pre-shared key. This will create a file called ta.key

$ openvpn --genkey secret ta.key

Copy the ta.key to the /etc/openvpn/server directory.

$ sudo cp ta.key /etc/openvpn/server

Step 7 - Generate a Client Certificate and Key Pair

Create a directory to store the client certificate and key files.

$ mkdir -p ~/client-configs/keys

Restrict the permissions on the directory to protect it.

$ chmod -R 700 ~/client-configs

Next, switch to the ~/easy-rsa directory.

$ cd ~/easy-rsa

Generate a client key with client1 as the Common Name for the client. You can use any CN for the client.

$ ./easyrsa gen-req client1 nopass

Press ENTER to confirm the common name. You will get the following output.

Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
.......+.+.....+.+........+.+...+...+........+....+..+....+.........+....................+......+.......+...+.....+.+.........+...............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*............+......+.........+......+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+........+...+...................+...........+....+...........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...........+......+.......+..+..........+.....+.......+.....+....+.....+....+...+.....+...+....+...........+....+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [client1]:

Keypair and certificate request completed. Your files are:
req: /home/username/easy-rsa/pki/reqs/client1.req
key: /home/username/easy-rsa/pki/private/client1.key

Next, copy the client1.key file to the ~/client-configs/keys directory.

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

Transfer the client1.req file to the CA server.

$ scp pki/reqs/client1.req username@your_ca_server_ip:/tmp

Log back into the CA server and import the server request.

$ cd ~/easy-rsa
$ ./easyrsa import-req /tmp/client1.req client1

You will get the following output.

Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

The request has been successfully imported with a short name of: client1
You may now use this name to perform signing operations on this request.

Sign the request using the following command. We are using client as the request type.

$ ./easyrsa sign-req client client1

When prompted, enter yes to confirm to sign the request and that it came from a trusted source.

Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)


You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a client certificate for 825 days:

subject=
    commonName                = client1


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes

You will