36 C
Jaipur
Wednesday, May 12, 2021

How to Set Up OpenVPN on Ubuntu 20.04

Must read

OpenVPN is a feature-rich open-source Secure Socket Layer (SSL) VPN. VPN allows to securely connect untrusted networks such as WIFI network in hotels or airports or malls. VPN also allows a secure connection to the corporate network to access resources. The tunnels are secured by using SSL/TLS authentication, certificates, credentials.

In this tutorial, I will show you how to setup a VPN using OpenVPN on Ubuntu 20.04.

Pre requisites

We will use two Ubuntu servers running on version 20.04:

  • A Certificate Authority (CA) server that will validate the request and sign the certificates of the clients.
  • The OpenVPN server on which we will install the VPN.

Configure CA server

It recommended keeping a standalone server to serve as your CA (certificate authority). This is because of security reasons. Let’s proceed to configure the CA server.

First make sure system is updated. Run the following the command:

 $ sudo apt update

You will need to create a non root user for the configurations of the Certificate Authority server.

$ sudo adduser malain

Now give to the user the sudo privileges:

$ sudo usermod -aG sudo malain

Now logout and then login back with the non-root user.

Install EasyRSA on CA server

Easy-rsa is a CLI utility to build and manage a PKI CA. Easy-RSA will be used by the CA server to generate a private key and public root certificate which will be used to sign the requests from clients and servers that will rely on our CA.

To install easy-rsa, download the PKI management tool from github using wget:

$ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz

Then uncompress tgz file:

$ tar xvf EasyRSA-3.0.8.tgz

To restrict the access to the user only, use:

$ chmod 700 EasyRSA-3.0.8

Now move EasyRSA to the opt directory

$ sudo mv EasyRSA-3.0.8 /opt/

We are using EasyRSA 3.0.8 version for this configuration.

Create CA using EasyRSA

First, you need to create a file named vars to store the organization information. For this, we can use the example file available in EasyRSA-3.0.8 directory.

To list files under EasyRSA directory, use:

$ cd EasyRSA-3.0.8/ && ls -l

Output:

-rw-rw-r-- 1 malain malain  1305 Sep  9  2020 COPYING.md
-rw-rw-r-- 1 malain malain  5056 Sep  9  2020 ChangeLog
-rw-rw-r-- 1 malain malain  2049 Sep  9  2020 README.md
-rw-rw-r-- 1 malain malain  3335 Sep  9  2020 README.quickstart.md
drwxrwxr-x 2 malain malain  4096 Sep  9  2020 doc
-rwxrwxr-x 1 malain malain 76946 Sep  9  2020 easyrsa
-rw-rw-r-- 1 malain malain 18093 Sep  9  2020 gpl-2.0.txt
-rw-rw-r-- 1 malain malain  1036 Sep  9  2020 mktemp.txt
-rw-rw-r-- 1 malain malain  4616 Sep  9  2020 openssl-easyrsa.cnf
-rw-rw-r-- 1 malain malain  8925 Sep  9  2020 vars.example
drwxrwxr-x 2 malain malain  4096 Mar 28 14:14 x509-types

Make a copy of the file vars.example as vars:

$ cp vars.example vars

Now open vars file and adding the organization information at the end of the file:

$ vim vars
    set_var EASYRSA_REQ_COUNTRY    "CM"
    set_var EASYRSA_REQ_PROVINCE   "Littoral"
    set_var EASYRSA_REQ_CITY       "Douala"
    set_var EASYRSA_REQ_ORG        "OPEN-SHARE"
    set_var EASYRSA_REQ_EMAIL      "[email protected]"
    set_var EASYRSA_REQ_OU         "Com"
    set_var EASYRSA_ALGO           "ec"
    set_var EASYRSA_DIGEST         "sha512"

Now initialize our PKI on our CA server which will create the pki folder.

$ ./easyrsa init-pki

We can now generate the root public and private key pair for our CA. During the process, normally you will be asked to enter a passphrase for the key pair anytime that you will need to sign or revoke a certificate. In our case, we will use the command so that we will be not prompted for a passphrase. You will also be prompted to indicate a Common Name (CN) but we will leave the default one by pressing Enter key.

$ ./easyrsa build-ca nopass

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
read EC key
writing EC key
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:
/opt/EasyRSA-3.0.8/pki/ca.crt

This will create root certificate named ca.crt file in the pki directory and the private key ca.key in the pki/private directory.

$ ls -l pki/
total 52
-rw------- 1 malain malain  749 Mar 28 14:30 ca.crt
drwx------ 2 malain malain 4096 Mar 28 14:29 certs_by_serial
drwx------ 2 malain malain 4096 Mar 28 14:29 ecparams
-rw------- 1 malain malain    0 Mar 28 14:29 index.txt
-rw------- 1 malain malain    0 Mar 28 14:29 index.txt.attr
drwx------ 2 malain malain 4096 Mar 28 14:29 issued
-rw------- 1 malain malain 4616 Mar 28 14:24 openssl-easyrsa.cnf
drwx------ 2 malain malain 4096 Mar 28 14:30 private
drwx------ 5 malain malain 4096 Mar 28 14:29 renewed
drwx------ 2 malain malain 4096 Mar 28 14:24 reqs
drwx------ 5 malain malain 4096 Mar 28 14:29 revoked
-rw------- 1 malain malain 4575 Mar 28 14:24 safessl-easyrsa.cnf
-rw------- 1 malain malain    3 Mar 28 14:29 serial
$ ls -l pki/private/
total 4
-rw------- 1 malain malain 288 Mar 28 14:29 ca.key

With this, our CA server is ready.

Install and Configure Openvpn Server

Lets jump on to the second server to install and configure openvpn. You will also need to create a non-root user in this server and give him the sudo privileges.

To install openvpn on ubuntu, run the following commands:

$ sudo apt update
$ sudo apt install openvpn

On the openvpn server, easyrsa will be used to generate a certificate request that will be verified and signed by the CA Server. Follow the same steps we followed in the last section to install Easyrsa.

$ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz

Now uncompress the downloaded tgz file:

$ tar xvf EasyRSA-3.0.8.tgz

Restrict the access to the user only:

$ chmod 700 EasyRSA-3.0.8

Move EasyRSA-3.0.8 to the opt directory:

$ sudo mv EasyRSA-3.0.8 /opt/

Create a PKI

Now we need to create PKI that will help to request and manage TLS certificates for the clients and the other servers that will connect to our VPN.

Lets create a vars file using the already available examples file:

$ cp vars.example vars

Now edit vars file by adding the following lines at the end of the file:

$ vim vars
    set_var EASYRSA_ALGO "ec"
    set_var EASYRSA_DIGEST "sha512"

To create the PKI folder on the openvpn server, run the easyrsa script file:

$ ./easyrsa init-pki

Output:

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /opt/EasyRSA-3.0.8/pki

Create the server certificate request and the private key

Now we will generate a private key and certificate request on the OpenVPN server. Then we will transfer the certificate request file to the CA server to be signed in order to create the required certificate

Being in the same folder, we can generate the request with the nopass option. The following command creates a private key file named openvpn-server.key and a certificate request file named openvpn-server.req.

$ ./easyrsa gen-req openvpn-server nopass

Output:

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating an EC private key
writing new private key to '/opt/EasyRSA-3.0.8/pki/easy-rsa-4737.CGhQHN/tmp.UGQ9wi'
-----
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) [openvpn-server]:

Keypair and certificate request completed. Your files are:
req: /opt/EasyRSA-3.0.8/pki/reqs/openvpn-server.req
key: /opt/EasyRSA-3.0.8/pki/private/openvpn-server.key

Now, copy the server key file named openvpn-server.key to the directory named /etc/openvpn/server.

$ sudo cp /opt/EasyRSA-3.0.8/pki/private/openvpn-server.key /etc/openvpn/server

Then copy certificate request file to the CA server:

$ scp /opt/EasyRSA-3.0.8/pki/reqs/openvpn-server.req  [email protected]:/tmp

On the CA server, change to the easyrsa directory,

$ cd /opt/EasyRSA-3.0.8/

To import the request, run the following command:

$ ./easyrsa import-req /tmp/openvpn-server.req openvpn-server

Output:

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020

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

Now sign the request. As we are signing the request of the server, we should use the directive server before the Common Name of our openvpn server. If it was a request of a client, we should be using the directive client instead.

To sign the request:

$ ./easyrsa sign-req server openvpn-server

Output:

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020


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                = openvpn-server


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /opt/EasyRSA-3.0.8/pki/easy-rsa-4100.IbygpP/tmp.hJY2T5
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'openvpn-server'
Certificate is to be certified until Jul  1 19:50:36 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /opt/EasyRSA-3.0.8/pki/issued/openvpn-server.crt

Now the OpenVPN server’s certificate request has been signed by the CA server, we need to transfer the signed request and the public certificate to the OpenVPN server.

$ scp pki/{ca.crt,issued/openvpn-server.crt} [email protected]:/tmp   
$ sudo cp /tmp/{ca.crt,openvpn-server.crt} /etc/openvpn/server

We will now generate the tls-crypt pre-shared key to ensure that our OpenVPN server is able to cope with unauthenticated traffic, port scans, and some attacks which can use a lot of the server’s resources.

$ ./easyrsa gen-dh

Output:

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
....................................+..........................
...............................................................
...............................................................
...........................................+.......+.......+...
.....+..........................................................
...............................++*++*++*++*

DH parameters of size 2048 created at /opt/EasyRSA-3.0.8/pki/dh.pem
$ openvpn --genkey --secret ta.key

Now copy the key and pem files to the directory /etc/openvpn/server:

$ sudo cp ta.key pki/dh.pem /etc/openvpn/server

Generate a client certificate and key pair

We will need to create a directory to keep the certificates and the keys of the clients. Make sure to give permission to the non-root user.

$ sudo mkdir -p /opt/client-configs/keys
$ sudo chown franck:franck -R /opt/client-configs
$ sudo chmod 700 -R /opt/client-configs

Generate the request for the client certificate:

$ cd /opt/EasyRSA-3.0.8
$ ./easyrsa gen-req my-pc nopass

Output:

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating an EC private key
writing new private key to '/opt/EasyRSA-3.0.8/pki/easy-rsa-6961.m7fBMu/tmp.dkqaZI'
-----
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) [my-pc]:

Keypair and certificate request completed. Your files are:
req: /opt/EasyRSA-3.0.8/pki/reqs/my-pc.req
key: /opt/EasyRSA-3.0.8/pki/private/my-pc.key

Now copy the client key to the client-configs directory:

$ cp pki/private/my-pc.key /opt/client-configs/keys/

Copy the client certificate request file to the CA server:

$ scp pki/reqs/my-pc.req  [email protected]:/tmp                                                        

On the CA server, import the CSR:

$ cd /opt/EasyRSA-3.0.8
$ ./easyrsa import-req /tmp/my-pc.req my-pc

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020

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

Now we should sign the request for client, type:

$ ./easyrsa sign-req client my-pc

Output:

Note: using Easy-RSA configuration from: /opt/EasyRSA-3.0.8/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020


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                = my-pc


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes 
Using configuration from /opt/EasyRSA-3.0.8/pki/easy-rsa-5511.IwDcbS/tmp.doUbCv
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'my-pc'
Certificate is to be certified until Jul  1 21:33:52 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /opt/EasyRSA-3.0.8/pki/issued/my-pc.crt

Copy the client certificate on the openvpn server:

$ scp pki/issued/my-pc.crt [email protected]:/tmp                          

Now on the openvpn server, we need to copy all the client files to the client directory that we have created before.

$ sudo cp /tmp/my-pc.crt /opt/client-configs/keys/
$ sudo cp /etc/openvpn/server/ca.crt /opt/client-configs/keys/
$ cp /opt/EasyRSA-3.0.8/ta.key /opt/client-configs/keys/

Make sure that the non-root user has the permissions on the files.

$ sudo chown franck:franck /opt/client-configs/keys/*

Configure VPN service

We should first make a copy of the template to use

$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/server/

Then uncompress the file

$ sudo gzip -d /etc/openvpn/server/server.conf.gz

And enter to the folder

$ cd /etc/openvpn/server

Some lines will be replaced to match our configuration::

  • The cryptographic ciphers will be set to AES-256-CBC
  • The HMAC message digest algorithm will be sha256
  • As we also use a Diffie-Hellman parameter, we will set it to dh.pem
  • We will use the user nobody and group nogroup to run openvpn with no privileges once it has started
  • We will push the dns changes to redirect all traffic through the vpn with the values push redirect-gateway def1 bypass-dhcp, push dhcp-option DNS 208.67.222.222, push dhcp-option DNS 208.67.220.220
  • We will keep the default port 1194
  • We will use the udp protocol
  • we should indicate the key openvpn-server.key and certificate openvpn-server.crt to use as the credential

So the file should look as below:

$ sudo vim /etc/openvpn/server/server.conf
    tls-crypt ta.key
    cipher AES-256-CBC
    auth SHA256
    dh dh.pem
    user nobody
    group nogroup
    push "redirect-gateway def1 bypass-dhcp"
    push "dhcp-option DNS 208.67.222.222"
    push "dhcp-option DNS 208.67.220.220"
    port 1194
    proto udp
    explicit-exit-notify 1
    cert openvpn-server.crt
    key openvpn-server.key

You should activate the ip forwarding by editing net.ipv4.ip_forward value in /etc/sysctl.conf.

$ sudo vim /etc/sysctl.conf
    net.ipv4.ip_forward=1

To make the changes we made in /etc/sysctl.conf effective, run:

$ sudo sysctl -p
net.ipv4.ip_forward = 1

Now you need to allow OpenVPN through your firewall by enabling the masquerading. To do that, you need to identify the name of your public network interface:

$ ip route | grep default
default via X.X.X.X dev eth0 proto static 

In our case it’s eth0. Now we should add the masquerades rules in the firewall configuration, so we will add the line below at the top of the rules’ files:

$ sudo vim /etc/ufw/before.rules
    # START OPENVPN RULES
    # NAT table rules
    *nat
    :POSTROUTING ACCEPT [0:0]
    # Allow traffic from OpenVPN client to the public server interface eth0
    -A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
    COMMIT
    # END OPENVPN RULES

Now let’s edit ufw to allow forwarded packets by default.

$ sudo vim /etc/default/ufw
    DEFAULT_FORWARD_POLICY="ACCEPT"

Open the openvpn port on the firewall:

$ sudo ufw allow '1194/udp'

To restart ufw service, type:

$ sudo ufw disable && sudo ufw enable

To enable the openvpn service to start as the system startup, type:

$ sudo systemctl enable [email protected]

To start openvpn, type:

$ sudo systemctl start [email protected]

You can check openvpn status by:

$ sudo systemctl status [email protected]

Output:

[email protected] - OpenVPN service for server
     Loaded: loaded (/lib/systemd/system/[email protected]; disabled; vendor preset: enabled)
     Active: active (running) since Sun 2021-03-28 23:30:57 UTC; 8s ago
       Docs: man:openvpn(8)
             https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
             https://community.openvpn.net/openvpn/wiki/HOWTO
   Main PID: 78132 (openvpn)
     Status: "Initialization Sequence Completed"
      Tasks: 1 (limit: 1073)
     Memory: 1.0M
     CGroup: /system.slice/system-openvpnx2dserver.slice/[email protected]
             └─78132 /usr/sbin/openvpn --status /run/openvpn-server/status-server.log --status-version 2 --suppress-timestamps --config server.conf

Mar 28 23:30:57 localhost systemd[1]: Starting OpenVPN service for server...
Mar 28 23:30:57 localhost systemd[1]: Started OpenVPN service for server.

To check the tunnel interface, type:

$ ip addr show tun0

Output:

3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
    link/none 
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::c3d9:85d1:e2a9:6b2c/64 scope link stable-privacy 
       valid_lft forever preferred_lft forever

Configure vpn files for clients

$ sudo mkdir -p /opt/client-configs/files

Now we should copy the sample configuration file

$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /opt/client-configs/base.conf

Give the permission to the non root user

$ sudo chown franck:franck -R /opt/client-configs/

Edit the base.conf file

$ vim /opt/client-configs/base.conf
    remote your_server_ip 1194               
    proto udp
    # Downgrade privileges after initialization (non-Windows only)
    user nobody
    group nogroup
    #ca ca.crt
    #cert client.crt
    #key client.key
    #tls-auth ta.key 1
    cipher AES-256-CBC
    auth SHA256
    key-direction 1
    # For the clients using resolvconf for DNS resolution, uncomment the lines below on the client computer
    ; script-security 2
    ; up /etc/openvpn/update-resolv-conf
    ; down /etc/openvpn/update-resolv-conf
    # Instead for the clients using systemd-resolved for DNS resolution, uncomment the lines below on the client computer
    ; script-security 2
    ; up /etc/openvpn/update-systemd-resolved
    ; down /etc/openvpn/update-systemd-resolved
    ; down-pre
    ; dhcp-option DOMAIN-ROUTE .

Now we will create a script to generate the certificates and encrypted files on the client. The script will also make a copy of the base.conf file and collect all the keys and certificates created for the clients. For each client, we would need to generate a certificate and key before running the script

$ vim /opt/client-configs/make_config.sh
    #!/bin/bash

    # First argument: Client identifier

    KEY_DIR=/opt/client-configs/keys
    OUTPUT_DIR=/opt/client-configs/files
    BASE_CONFIG=/opt/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

Make sure that only the non-root user can run the script.

$ chmod 700 /opt/client-configs/make_config.sh

Now you can generate the client connection file based on the client key and certificate configuration (my-pc.crt and my-pc.key)

$ cd /opt/client-configs

Now run the script followed by the common name used for the client which will create the client vpn file to use.

$ ./make_config.sh my-pc

You can check the result:

$ ls -l files/
total 12
-rw-rw-r-- 1 franck franck 8598 Mar 30 11:12 my-pc.ovpn

Connect client to the OpenVPN connection

Install openvpn on the client. This will be use to establish the vpn connection with the server

$ sudo apt update && sudo apt install openvpn -y

Now copy the OpenVPN client file which is on the server to your client computer. So, on your client computer do the following command:

$ rsync -av [email protected]:/opt/client-configs/files/my-pc.ovpn .

Before editing the client OpenVPN configuration file, we must check if we use resolvconf or systemd-resolved for DNS resolution

$ cat /etc/resolv.conf
        OUTPUT:
        # This file is managed by man:systemd-resolved(8). Do not edit.
        . . .

        nameserver 127.0.0.53
        options edns0

With the value nameserver 127.0.0.53, it shows that you use systemd-resolved. So, install a package which will help systemd-resolved to use the VPN for the DNS resolution when connected.

$ sudo apt install openvpn-systemd-resolved

Now we can edit the vpn client file by uncommenting the lines needed for systemd-resolved

$ vim my-pc.ovpn
    script-security 2
    up /etc/openvpn/update-systemd-resolved
    down /etc/openvpn/update-systemd-resolved
    down-pre
    dhcp-option DOMAIN-ROUTE .

For the system using update-resolv-conf, you will uncomment the lines

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

Now let’s try connecting to the VPN using openvpn command to the client configuration file:

$ sudo openvpn --config my-pc.ovpn

You can check the ip information for the tunnel interface

$ ip a

This will show a tunnel ip address and we can make a ping to the OpenVPN server. With this, you can confirm that you are able to reach your server as if you were in the same private network.

Conclusion

It’s easy to set up a VPN connection when using OpenVPN. This is a good solution when you want to set up a VPN solution on your cloud server without using any specialized solution such as a virtual firewall or anything else. It’s a fast and secure solution.

Source link

- Advertisement -

More articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisement -

Latest article