Setting Up OpenVPN on Linux

      No Comments on Setting Up OpenVPN on Linux

Initial Installation

So, let’s first install easy-rsa and OpenVPN.

sudo apt install openvpn easy-rsa

Configuring the Public Key Infrastructure

A properly configured public key infrastructure is key to successfully setting up OpenVPN. This provides the secure backbone which makes OpenVPN as effective as it is. An improper setup of the PKI will result in a VPN which does not work. This can be extremely hard to debug and a major time sink.

Simplifying Setup via Easy-RSA

To make this process easier, OpenVPN has a set of bash utilities known as easy-rsa. Easy-rsa allows you to easily generate everything you need to build a complete PKI. This utility generates everything from certificates and keys to the HMAC key and certificate revocation list can be generated through this utility.

Copy the OpenSSL Configuration File

cp /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.conf

Setting Defaults for Easy-RSA

Let’s configure some default settings for Easy-RSA. These settings make up the information included in the certificates we are generating. Open /usr/share/easy-rsa/vars and fill out the following:

set_var EASYRSA_REQ_COUNTRY     "<Your Country>"
set_var EASYRSA_REQ_PROVINCE    "<Your State>"
set_var EASYRSA_REQ_CITY        "<Your City>"
set_var EASYRSA_REQ_ORG         "<Your Organization>"
set_var EASYRSA_REQ_EMAIL       "<Your Email>"
set_var EASYRSA_REQ_OU          "<Your Organizational Unit>"

During generation of your certificate, the common name is interactively specified. Therefore it is unnecessary to fill it out now.

Initializing the Private Key Infrastructure

In setting up Easy-RSA, the first thing to do is to initialize the pki/ folder. Make absolutely sure that nothing of value is in this directory before running the following command:

/usr/share/easy-rsa/easyrsa init-pki

Now the /etc/openvpn/pki folder should exist. The infrastructure’s files go here when generated. We will copy them out of this folder and into /etc/openvpn when we need them.

First Step: Generating the Certificate Authority

The first piece of a public key infrastructure is a certificate authority. This is a trusted third party which vouches for both the client and server. It signs both of the two parties’ certificates so that they can be validated during a connection. In this case, we’re going to be our own certificate authority. This will give us the ability to sign the certificates on our own machine without having to take them to an outside source. Run the following command to do so:

/usr/share/easy-rsa/easyrsa build-ca nopass

Fill out the interactive fields and wait for the certificate generation to complete. This certificate can sign both the client and server’s certificates and keys.

Second Step: Generate the Server Certificate and Key

Now we need to generate a certificate and key for the server. We will use the certificate we generated in the last step to do so. This is a three step process. The first thing we have to do is to generate a signing request for the server. The following command will do so:

/usr/share/easy-rsa/easyrsa gen-req server nopass

The certificate authority will need to handle the certificate signing request. So to continue the process, let’s go ahead and sign the request.

/usr/share/easy-rsa/easyrsa sign-req server server

Note: If you receive a message saying “Unknown cert type ‘Server'”, copy the x509-types/ directory into the folder you created to hold the generated files

cp -r /etc/easy-rsa/x509-types/ ./

Easy-RSA’s sign-req server command will utilize our certificate authority ca.cert file to sign the server.crt file and configure it for use by an OpenVPN server.

Third Step: Generate the Client Certificate and Key

Now we will perform the same process for the client:

/usr/share/easy-rsa/easyrsa build-client-full client1 nopass

This will automatically run through the same steps for a client certificate and key. it will automatically sign them as well.

Fourth Step: Generate the Diffie-Hellman Parameters

Diffie-Hellman parameter establish perfect forward secrecy. Perfect forward secrecy creates a new session for each new connection. In this way, a compromised key will be unable to decrypt prior communications.

/usr/share/easy-rsa/easyrsa gen-dh

Configuring the OpenVPN Server

With that out of the way, we’re now going to perform the basic configuration needed to get OpenVPN off the ground. Go ahead and open up /etc/openvpn/server.conf and make the following changes:

# Specify the protocol and port the server will use.
# Routing TCP over TCP is very inefficient due to the packet checks it performs.
proto udp
port 1194

# Provide the server with the files it needs to perform X.509 handshaking.
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/server.crt
key /etc/openvpn/pki/server.key
dh /etc/openvpn/pki/dh.pem

# Certificate Revocation List
#crl-verify /etc/openvpn/pki/crl.pem

# Determine the type of virtual device used on the server.
# tun utilizes layer 3 routing.  It is the most compatible.
# tap utilizes layer 2 routing.  It is necessary when protocols not TCP/IP based
# need to be routed.
dev tun

auth SHA512
cipher AES-256-CBC

topology subnet

tls-auth /etc/openvpn/pki/ta.key 0

# Data compression with compatibility for older clients.

# Makes the OpenVPN server drop root privileges when no longer needed.
# This is a very good idea.
user nobody
group nobody

# Useful for debugging.  The higher the number, the more verbose the output.
verb 3
log-append /var/log/openvpn.log

#remote-cert-tls server

Forwarding Traffic Through the Server

The first setting we’re going to configure gives us the ability to route all of the clients’ traffic through our server. This allows it to work very similarly to anonymizing VPNs and is useful for providing Internet access through the network. Add the following to server.conf.

push "redirect-gateway def1 bypass-dhcp"

This option is not necessary if the VPN does not need to provide access to the Internet. Clients on the virtual private network will happily use the network by itself and continue to use their own default gateway.

Configuring DNS For Clients

Next, set the configuration to pass DNS server addresses to the clients. This is necessary to ensure that they maintain Internet access once connected.

push "dhcp-option DNS"
push "dhcp-option DNS"

Configuring Topology

Enable the correct topology for OpenVPN by adding:

topology subnet

The subnet topology represents a standard spoke and wheel type network configuration. This allows much more flexibility in configuration. Any number of clients can connect and communicate as if they were all hooked to the same switch. In contrast, legacy versions of OpenVPN only support a “net30” configuration. This configuration creates a /30 network. This greatly limits the maximum number of clients and makes routing between large groups of devices much more difficult. The one caveat in both of these schemes is that all data must flow through the VPN server, which could potentially become a bottleneck.

Security Hardening

Dropping Root

By default, OpenVPN will run as root. The following lines in server.conf will make it drop the privileges once no longer needed. This way, an exploited flaw in the OpenVPN software will provide a hacker with little additional access.

user nobody
group nobody

One of the steps we will take to secure our server is to instruct the server to validate the certificates of any client connecting. The following configuration option will do so:

remote-cert-eku "TLS Web Client Authentication"

Enable HMAC Authentication

The next step we will take is to enable an additional layer of HMAC verification for all encrypted handshake packets sent through the tunnel.

Make the following changes in /etc/openvpn/server.conf:

tls-auth ta.key 0

Now we need to actually generate this key.

sudo openvpn --genkey --secret /etc/openvpn/ta.key

Virtual Network Configuration

First, allow OpenVPN through your firewall.

sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=trusted --add-service openvpn --permanent
sudo firewall-cmd --list-services --zone=trusted
sudo firewall-cmd --add-masquerade
sudo firewall-cmd --permanent --add-masquerade

SHARK=$(ip route get | awk 'NR==1 {print $(NF-2)}')
sudo firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s \
sudo firewall-cmd --reload

Now edit /etc/sysctl.conf and add the following:

net.ipv4.ip_forward = 1

Now restart the networking service:

sudo systemctl restart network.service

Next, enable and start OpenVPN on the server:

sudo systemctl enable openvpn@server.service
sudo systemctl start openvpn@server.service

Client Configuration

Copy the following files from the server to the client:


Create a file on the client called client.ovpn containing the following:

ca /home/pdreyer/OpenVPN/keys/ca.crt
cert /home/pdreyer/OpenVPN/keys/client.crt
key /home/pdreyer/OpenVPN/keys/client.key
tls-crypt /home/pdreyer/OpenVPN/myvpn.tlsauth
remote-cert-eku "TLS Web Client Authentication"
proto udp
dev tun
topology subnet
user nobody
group nobody

Now start the OpenVPN client:

sudo openvpn --config ~/path/to/client.ovpn

Leave a Reply

Your email address will not be published. Required fields are marked *