How to setup a VPN Connection with OpenVPN

Introduction

Why VPN to Home ?

I admit, at the beginning, The thought of building a VPN for Home sounds about obscure.

Why would anybody need a VPN to their home and to what end ?

Well , there are quite a few answers to those questions which I will try to address several key advantages for building a home VPN and hopefully one of those reasons will convince you that a home VPN is actually pretty cool.

  1. Home Equipment — every now and then I found myself with the need of printing an invoice or an E-ticket which I need to use for my personal use … for that and other the prefered choice is printing at home.

Those are just a few of the reasons why I think a VPN to your home is a good Idea.

Why OpenVPN ?

OpenVPN is one of if not the Most used VPN Server out in the Market , there are dozens of tutorials and support pages about it and may companies choose it as their gateway to their organization.

Ohhh , and yes it’s Free (there is a commercial version for large/medium companies).

It is very easy to set up.

Why this tutorial ?

Well… for several reasons. I think that the first, is none of the tutorials I have seen do not address the client side example of the connection (through the NetworkManager GUI). Second there are a few tips and tricks to make it easier to maintain and produce a more advanced configuration (like PAM).

I assume that your Raspberry Pi is already installed with CentOS and EPEL.

IT Configuration

In this tutorial we are working with the assumption that your internet connection does not consist a static IP and that you do own a public domain.

For this scenario the following document will provide several alternatives that will help you get the job done.

Static / Dynamic IP

In case your ISP has provided a static IP address to your account then you are in a good position. You can go to one of the known domain provides such as :

  • Your ISP

And buy a nice domain for about 3–12 dollars a year.

If you are using a Dynamic IP address then you can use one of the following dynamic DNS provides :

  • duckdns.org

Once you create an account you need to setup a client/cron to keep your DNS record update 2 date.

(I advise you (if you can) to look at your router settings. Most routers today come with a variety of clients for well known dynamic DNS provides in order to skip the client installation).

For This tutorial I will use example.duckdns.org as the domain for the certificate this is how I did it :

  1. register here

Server Side

Installing the Server

Installing the Server is very easy to do , it’s a one single yum command:

# yum install -y openvpn easy-rsa openssl

We are now installing OpenVPN 2.4 with easy-rsa 3

When the installation is complete, check the openvpn and easy-rsa version.

# openvpn --version# ls -lah /usr/share/easy-rsa/

Certificates

The certificates in OpenVPN are not complicated to setup but they do require some attention.

There are 2 types of certificates we can generate, each has its own advantages and disadvantages so we will go through both options (you can choose whichever you like.

Private Certificate (easy-rsa)

Advantages:

Key Master — you are the key master the OpenVPN Server , you can generate both Client and Server certificate and use those for authentication (as I am going to show you how)

Disadvantages:

You will have to know and get yourself familier with SSL/TLS which in most cases a necessity and not a requirement by the Server Admin (you)

Configure Easy-RSA 3

In this step, we will configure easy-rsa 3 by creating new ‘vars’ file. The ‘vars’ file contains the Easy-RSA 3 settings.

Go to the ‘/etc/openvpn/’ directory and copy the ‘easy-rsa’ script.

# cd /etc/openvpn/# cp -r /usr/share/easy-rsa /etc/openvpn/

Now go to the ‘easy-rsa/3/’ directory and create new vars file using your favorite EDITOR (I prefer VIM)

# cd /etc/openvpn/easy-rsa/3/# touch vars

Paste the vars easy-rsa 3 configuration below.

Build OpenVPN Certificates and Keys

In this step, we will build the OpenVPN keys based on the easy-rsa 3 ‘vars’ file that we’ve created. We will build the

  • CA certificate and key
# cat > vars << EOF
set_var EASYRSA "$PWD"
set_var EASYRSA_PKI "$EASYRSA/pki"
set_var EASYRSA_DN "cn_only" # CHANGEABLE
set_var EASYRSA_REQ_COUNTRY "COUNTRY" # CHANGEABLE
set_var EASYRSA_REQ_PROVINCE "PROVINCE" # CHANGEABLE
set_var EASYRSA_REQ_CITY "CITY" # CHANGEABLE
set_var EASYRSA_REQ_ORG "ORG" # CHANGEABLE
set_var EASYRSA_REQ_EMAIL "EMAIL" # CHANGEABLE
set_var EASYRSA_REQ_OU "OU" # CHANGEABLE
set_var EASYRSA_KEY_SIZE 2048
set_var EASYRSA_ALGO rsa
set_var EASYRSA_CA_EXPIRE 7500
set_var EASYRSA_CERT_EXPIRE 365
set_var EASYRSA_NS_SUPPORT "no"
set_var EASYRSA_NS_COMMENT "YOUR_OWN_CA" # CHANGEABLE
set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types"
set_var EASYRSA_SSL_CONF "$EASYRSA/openssl-1.0.cnf"
set_var EASYRSA_DIGEST "sha256"
EOF

Change the values so they will match your certificate request (just go through the list , you will notice it) save & exit.

Now make the ‘vars’ file executable by changing the permission of the file.

# chmod +x vars

The vars file for Easy-RSA 3 setting has been created.

Before building any keys, we need to initialize the PKI directory and build the CA key.

Initiate the PKI directory and build the CA key using the command below.

# ./easyrsa init-pki# ./easyrsa build-ca

Now type the password for your CA key and you will get your ‘ca.crt’ and ‘ca.key’ files under the ‘pki’ directory.

Build Server Key

Now we want to build the server key, and we will build the server key named ‘my-server’.

Build the server key ‘my-server’ using the command below.

# ./easyrsa gen-req my-server nopass
  • nopass = option for disable password for the ‘hakase-server’ key.

When you are prompted for a common name (CN) then input your public fully qualified domain name (FQDN) : example.duckdns.org (from the duckdns.org record in our example)

Sign the ‘my-server’ key using our CA certificate.

# ./easyrsa sign-req server my-server

You will be asked for the ‘CA’ password, type the password and press Enter. And you will get the ‘hakase-server.crt’ certificate file under the ‘pki/issued/’ directory.

Verify the certificate file using the OpenSSL command and make sure there is no error.

# openssl verify -CAfile pki/ca.crt pki/issued/my-server.crt

All server certificate keys have been created. The server private key is located at the ‘pki/private/my-server.key’, and the server certificate on the ‘pki/issued/my-server.crt’.

Build Diffie-Hellman Key

This action will take a lot of time, depending on the key length that we chose and the available entropy on the server. We will be using the length key that we define on the ‘vars’ file.

Generate the Diffie-Hellman key using command below.

# ./easyrsa gen-dh

The DH key has been generated, located at the ‘pki’ directory.

Generate the CRL Key

The CRL (Certificate Revoking List) key will be used for revoking the client key. If you have multiple client certificates on your vpn server, and you want to revoke some key, you just need to revoke using the easy-rsa command.

# ./easyrsa gen-crl

Copy Certificates Files

All certificates have been generated, now copy the certificate files and PEM files.

Copy Server Key and Certificate.

# cp pki/ca.crt /etc/openvpn/server/# cp pki/issued/my-server.crt /etc/openvpn/server/# cp pki/private/my-server.key /etc/openvpn/server/

Copy DH and CRL Key.

# cp pki/dh.pem /etc/openvpn/server/# cp pki/crl.pem /etc/openvpn/server/

Configure the OpenVPN Server

In this step, we will create new configuration ‘server.conf’ for the openvpn server.

Go to the ‘/etc/openvpn/’ directory and create new configuration file ‘server.conf’ using your favorite EDITOR (vim).

# cd /etc/openvpn/
(/etc/openvpn/server for RHEL/CENTOS8)
# touch server.conf

Paste the following OpenVPN server configuration there.

# cat > server.conf << EOF
# OpenVPN Port, Protocol and the Tun
port 1194
proto udp
dev tun
# OpenVPN Server Certificate — CA, server key and certificate
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/my-server.crt
key /etc/openvpn/server/my-server.key
#DH and CRL key
dh /etc/openvpn/server/dh.pem
crl-verify /etc/openvpn/server/crl.pem
# Network Configuration — Internal network
# Redirect all Connection through OpenVPN Server
server 172.26.15.0 255.255.255.0
push “redirect-gateway def1”
# Using the DNS from https://dns.watchpush “dhcp-option DNS 192.168.0.2”
push “dhcp-option DNS 192.168.0.3”
push “route 192.168.0.0 255.255.255.0”
#Enable multiple clients to connect with same Certificate keyduplicate-cn
# TLS Security
cipher AES-256-CBC
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
auth SHA512
auth-nocache
# Other Configuration
keepalive 20 60
persist-key
persist-tun
comp-lzo yes
daemon
user nobody
group nobody
# OpenVPN Log
log-append /var/log/openvpn.log
verb 3
EOF

Save and exit.

The configuration for OpenVPN has been created.

Firewall And NAT Configuration

In this step, we will enable Port-forwarding kernel module and configure routing ‘Firewalld’ for OpenVPN.

Enable the port-forwarding kernel module by running following commands:

# echo ‘net.ipv4.ip_forward = 1’ >> /etc/sysctl.conf# echo ‘net.ipv4.conf.all.accept_redirects = 0’ >> /etc/sysctl.conf# echo ‘net.ipv4.conf.all.send_redirects = 0’ >> /etc/sysctl.conf# sysctl -p

Next, configure routing using the Firewalld for OpenVPN.

To see your zone you can run the following command :

# firewall-cmd --get-default-zone# export FWZONE=$(firewall-cmd --get-default-zone)

This will give us the zone we need for our services configuration.

Add the ‘openvpn’ service to the firewalld list service and add the ‘tun0’ interface to the firewalld trusted zone.

# firewall-cmd --permanent --add-service=openvpn# firewall-cmd --permanent --zone=${FWZONE} — add-interface=tun0

Enable ‘MASQUERADE’ on the ‘trusted’ zone firewalld.

# firewall-cmd --permanent --zone=${FWZONE} --add-masquerade

Enable NAT for OpenVPN internal IP address ‘10.10.1.0/24’ to the external IP address ‘SERVERIP’.

# SERVERIP=$(ip route get 84.200.69.80 | awk 'NR==1 {print $(NF-2)}')# echo $SERVERIP# firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 172.26.15.0/24 -o $SERVERIP -j MASQUERADE

If you need to make changes the configuration are been kept at the file “direct.xml”

# cat /etc/firewalld/direct.xml<?xml version=”1.0" encoding=”utf-8"?><direct><passthrough ipv=”ipv4">-t nat -A POSTROUTING -s 172.26.15.0/24 -o $SERVERIP -j MASQUERADE</passthrough></direct>

NOTE:

The “172.26.15.0/24 are taking from the server configuration and is the VPN network the Server will use for Client / Server communication.

And reload firewall.

# firewall-cmd --reload

Test the setting with the following command:

# netstat -plntu | grep 1194

The output should look like :

udp 0 0 0.0.0.0:1194 0.0.0.0:* 22500/openvpn

And make sure the service is running without errors:

# systemctl status openvpn@server● openvpn@server.service — OpenVPN Robust And Highly Flexible Tunneling Application On serverLoaded: loaded (/usr/lib/systemd/system/openvpn@.service; enabled; vendor preset: disabled)Active: active (running) since Fri 2019–10–11 21:58:57 IDT; 1 weeks 2 days agoMain PID: 22500 (openvpn)Status: “Initialization Sequence Completed”CGroup: /system.slice/system-openvpn.slice/openvpn@server.service└─22500 /usr/sbin/openvpn — cd /etc/openvpn/ — config server.conf

The Port-forwarding and the Firewalld routing has been completed, now start the openvpn service and enable it to launch automatically every time at system boot.

# systemctl start openvpn@server# systemctl enable openvpn@server

For RHEL/CENTOS 8

# systemctl start openvpn-server@server.service# systemctl enable openvpn-server@server.service

Now that your Server is setup we can continue with the client configuration

Client Side

In this Client Section I will go through 3 types of configuration

  1. Private CA — CLI

NOTE

Everything we do in the GUI can be easily exported to a simple *.ovpn file which can be used in the CLI.

OVPN File

I want to talk about this file type for several reasons.

  • Simple — this is the easiest configuration OpenVPN can offer because this is a Copy/Past scarion where all you have to do is copy the context I am going to provide and just change several section

Private CA.

First we will want to generate a private Key + Certificate using our Private CA and for that both easy-rsa and openssl have a very easy way of doing that.(I will focus on easy-rsa for this example)

# ./easyrsa gen-req client01 nopass

Now sign the ‘client01’ key using our CA certificate as below.

# ./easyrsa sign-req client client01

Type ‘yes’ to confirm the client certificate request, then type the CA password.

The client certificate named ‘client01’ has been generated, verify the client certificate using the openssl command.

# openssl verify -CAfile pki/ca.crt pki/issued/client01.crt

Copy client01 Key and Certificate.

# cp pki/ca.crt /etc/openvpn/client/# cp pki/issued/client01.crt /etc/openvpn/client/# cp pki/private/client01.key /etc/openvpn/client/

Client Machine

On the Client Machine we have 2 options we can use in regards to the OpenVPN client but as stated before the first action item is to create the ovpn file.

Here is an example of the ovpn file :

# cat > client.ovpn << EOF
client
remote 'vpn.<your-domain>.duckdns.org' 1194
ca [inline]
cert [inline]
key [inline]
cipher AES-256-CBC
comp-lzo yes
dev tun
dev-type tun
proto udp
port 1194
route '192.168.0.0' '255.255.255.0' '172.26.15.1'
nobind
auth-nocache
script-security 2
persist-key
persist-tun
user nm-openvpn
group nm-openvpn
<ca>
--------BEGIN CERTIFICATE----------
--------END CERTIFICATE------------
</ca>
<cert>
--------BEGIN CERTIFICATE----------
--------END CERTIFICATE------------
</cert>
<key>
--------BEGIN PRIVATE KEY----------
--------END PRIVATE KEY------------
</key>
EOF

You can extend the verb option to a bigger number (up to 7) in order to receive a better verbosity in case the connection is not working.

Client CLI

This option is very simple and easy to apply and we can set it up to connect to the VPN at boot.

Copy the Client01.ovpn file to /etc/openvpn/client

# cp Client01.ovpn /etc/openvpn/client/

Now change the directory to the /etc/openvpn/client

# cd /etc/openvpn/client/

Now run the openvpn command and start the vpn

# openvpn --config Client01.ovpn

Now we can test the VPN connection by pinging the default gateway of the VPN network:

# ping 172.26.15.1

You should receive a reply and everything is setup correctly

Now if we want to make sure the vpn client is running at startup we need to enable it using the systemctl tool:

Systemctl enable openvpn@client

Client GUI

The GUI configuration are very simples

  1. Edit NetworkManager connection
  1. Selection Import from file option:
  1. Select the import
  1. Now click on “Create”

We are all done

Client Pubilc Certificate

Sense we configured the VPN Server which uses the public certificates with a username/password challenge response then we need to make we select it when we configure the GUI VPN connection:

Select the challenge response and pub the public CA (you can download it from letsencrypt site or take it from the VPN server :

click “Save” and you are do

try to connect to the VPN using the VPN option in your networkManagere GUI

that is all , if you have any question fill free to pust a commet.

Open Source contributer for the past 15 years