In this guide I will show and explain the steps required to get a VPN server running on a fresh install of CentOS7. This guide will start the server up in steps. There are a lot of steps and places where you can get tripped up in getting a OpenVPN set up and running. By bringing everything up in steps you will be better able to figure out what step failed if something goes wrong. This guide is based off of official documentation found here. Commands are in bold in the code blocks, and output is normal text. Enjoy!

 

Prerequisites:
  • CentOS 7 installed

 

Install the required packages

sudo yum -y install epel-release
sudo yum -y install firewalld vim ntp openvpn easy-rsa zip

Let me explain what these packages are. First, epel-release lets you install extra packages that aren’t in the default CentOS repository. firewalld is what we will use to configure the firewall. vim is a text editor we are going to use, you can skip this and use what ever text editor you’d prefer. ntp syncs the system clock to a very accurate source, it is important to have fairly accurate time when using certificates with OpenVPN. openvpn this is the VPN server we will be using. easy-rsa is what we will use to create certificates that will be used with OpenVPN.

 

Set up ntpd

timedatectl list-timezones

Use your arrow / page down keys to scroll through this list. Find the time zone that best describes where you are. Next we will tell the system to start the time sync service to start at boot.

sudo timedatectl set-timezone America/New_York
sudo systemctl start ntpd
sudo systemctl enable ntpd

 

Set up easy-rsa, build CA, create server certificate

The easy-rsa package is used to build a certificate authority(CA). You will then use this CA to sign other certificates that the server and client machines will use to communicate over a secure channel. The method OpenVPN uses to do this is very similar SSL, what web browsers use to do secure communication over the internet, like a banking website would. The version of easy-rsa provided by yum at the time of me writing this is 3. Most guides are using a 2.x version. Here is more info on using easy-rsa 3.

We are going to copy the easy-rsa files that yum installed to the openvpn configuration directory. We do this in case yum ever updates easy-rsa in its default directory and overwrites our changes.

sudo mkdir /etc/openvpn/easy-rsa
sudo cp -r /usr/share/easy-rsa/3/* /etc/openvpn/easy-rsa

Now we are going to start building our certificates. The files that easy-rsa will create for us will be written in the pki/ directory. In our case the full path will be /etc/openvpn/pki.

cd /etc/openvpn/easy-rsa
sudo ./easyrsa init-pki

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

 

Then we build the CA

sudo ./easyrsa build-ca

Generating a 2048 bit RSA private key
………………………………………………………………………………+++
……………………………………………………………………………………………………+++
writing new private key to ‘/etc/openvpn/easy-rsa/pki/private/ca.key.sUhZXYUixU’
Enter PEM pass phrase:

Enter a password for your CA. If you ever forget this password you will not be able to add or remove clients access to the server. This password can also not be left blank.

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]:

You can leave Common Name default or enter something that describes you or your origination better. This creates a certificate for the CA that we will need later on both the server and all clients. The file is located at /etc/openvpn/easy-rsa/pki/ca.crt. It will also create our private key which is located at /etc/openvpn/pki/private/ca.key. This ca.key file is the top of the trust chain and should never be shared.

Now we are going to create a request for a server certificate from our newly created CA. Replace SERVER_NAME with what you’d like to call your server. This name is not really important. we use the nopass flag here because if we didn’t we would have to enter a password every time we start the server.

sudo ./easyrsa gen-req SERVER_NAME nopass
Generating a 2048 bit RSA private key
…..+++
………………………………………..+++
writing new private key to ‘/etc/openvpn/test2/pki/private/SERVER_NAME.key.5wDxc6WQee’
—–
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_NAME]:

Press enter to complete the command. This will make a couple files that we will use to sign the file and make it valid. Next we sign the certificate with our CA. We will need the password you entered earlier.

sudo ./easyrsa sign-req server SERVER_NAME

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 3650 days:

subject=
commonName = SERVER_NAME

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

Type yes then enter to confirm. Enter the password you made for the CA earlier. The output should be similar to below

Using configuration from ./openssl-1.0.cnf
Enter pass phrase for /etc/openvpn/easy-rsa/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
commonName :ASN.1 12:’SERVER_NAME’
Certificate is to be certified until Jul 16 15:09:21 2028 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /etc/openvpn/easy-rsa/pki/issued/SERVER_NAME.crt

We will now make a Diffie–Hellman key. This key allows us forward secrecy. What that means is if someone was to capture our traffic and save it. Then later find our certificates, they won’t be able to decrypt the traffic that they saved. This will take 1 to 2 minutes.

sudo ./easyrsa gen-dh

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 /etc/openvpn/test2/pki/dh.pem

 

Next we make one last key for the server. We don’t use easy-rsa for this step but because it is a key file I am including it here. This key helps stop people from messing with your server. Note If you are copy and pasting this line you will need to make sure the double hyphen is pasted correctly; it should be two – with no space between them. wordpress is changing it.

sudo openvpn –genkey –secret /etc/openvpn/easy-rsa/pki/ta.key

This completes the files we need for the server. We will circle around to easy-rsa again when we create our client files.

 

Configure OpenVPN

We start this process by copying a sample file that is installed with the OpenVPN package. At the time of writing this guide yum on CentOS 7 was installing version 2.4.6 of OpenVPN. Keep this in mind as the version number could be different for you. adjust the path as necessary.

sudo cp /usr/share/doc/openvpn-2.4.6/sample/sample-config-files/server.conf /etc/openvpn
sudo vim /etc/openvpn/server.conf

I use vim to edit text files. You can use another tool if you’d like. If you don’t know how to use vim search google for a quick start guide. We are going to tell OpenVPN to use the files we created with easy-rsa. There are 10 lines we are going to change.

Change:

ca ca.crt

To:

ca /etc/openvpn/easy-rsa/pki/ca.crt


 

Change:

cert server.crt

To:

cert /etc/openvpn/easy-rsa/pki/issued/SERVER_NAME.crt


 

Change:

key server.key

To:

key /etc/openvpn/easy-rsa/pki/private/SERVER_NAME.key


 

Change:

dh dh2048.pem

To:

dh /etc/openvpn/easy-rsa/pki/dh.pem


 

Change:

tls-auth ta.key 0

To:

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

Change:

;push “redirect-gateway def1 bypass-dhcp”

To (we are just un-commenting the line):

push “redirect-gateway def1 bypass-dhcp”


Change:

;push “dhcp-option DNS 208.67.222.222”

To:

push “dhcp-option DNS 1.1.1.1”


Change:

;push “dhcp-option DNS 208.67.220.220”

To:

push “dhcp-option DNS 8.8.8.8”


Change:

;user nobody

To:

user nobody


 

Change:

;group nobody

To:

group nobody


 

Change:

;topology subnet

To:

topology subnet


 

Configure The Firewall

CentOS 7 is using firewalld now for its firewall. This guide will use it instead of the iptables command. First we need to find what zone our public facing network card is in. NOTE: please some commands use a double hyphen. If you copy and paste these commands you will need to erase the single and replace with a double hyphen.

sudo firewall-cmd –get-active-zones
public
interfaces: eth0

If the command above shows no ouput, run this command directly below. Replace eth0 with your public facing network card.

sudo firewall-cmd –zone=public –change-interface=eth0

Here the internet facing network card is named eth0 and is in the public zone. Now we will first open the port that OpenVPN uses and also enable NAT.

sudo firewall-cmd –zone=public –add-service openvpn
success
sudo firewall-cmd –zone=public –add-service openvpn –permanent
success
sudo firewall-cmd –add-masquerade
success
sudo firewall-cmd –add-masquerade –permanent
success
sudo firewall-cmd –direct –passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
success
sudo firewall-cmd –permanent –direct –passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
success
sudo firewall-cmd –reload

 

We also need to allow the kernel to forward IPV4 traffic.

sudo vim /etc/sysctl.conf

Add this line to /etc/sysctl.conf:

net.ipv4.ip_forward = 1


sudo systemctl restart network.service

 

Start The OpenVPN Server

sudo systemctl -f enable openvpn@server.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openvpn@server.service to /usr/lib/systemd/system/openvpn@.service.
sudo systemctl start openvpn@server.service

 

Configure Client Files

This section will be about setting up the configuration files needed as well as the keys or certs we will need to start a vpn tunnel. You will need to enter a password that will have to be entered every time you connect to the vpn. If you don’t want to use a password append nopass after CLIENT_NAME. When it asks about common name just press enter. CLIENT_NAME should be replaced with a name that identifies the person connecting. If that person is no longer allowed to connect to the vpn, you can revoke their access by this name.

cd /etc/openvpn/easy-rsa
sudo ./easyrsa gen-req CLIENT_NAME
Generating a 2048 bit RSA private key
…………………………………+++
…+++
writing new private key to ‘/etc/openvpn/easy-rsa/pki/private/CLIENT_NAME.key.bKBo7Y6MNQ’
Enter PEM pass phrase:

Verifying – Enter PEM pass phrase:
—–
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) [CLIENT_NAME]:

Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/pki/reqs/CLIENT_NAME.req
key: /etc/openvpn/easy-rsa/pki/private/CLIENT_NAME.key

We will now sign the certificate with our CA. You will need to type yes when it asks you, and you will also need the CA password we entered earlier when we created the CA.

sudo ./easyrsa sign-req client CLIENT_NAME

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 3650 days:

subject=
commonName = CLIENT_NAME

Type the word ‘yes’ to continue, or any other input to abort.
Confirm request details: yes
Using configuration from ./openssl-1.0.cnf
Enter pass phrase for /etc/openvpn/easy-rsa/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
commonName :ASN.1 12:’CLIENT_NAME’
Certificate is to be certified until Aug 26 19:10:42 2028 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /etc/openvpn/easy-rsa/pki/issued/CLIENT_NAME.crt

 

Next edit the sample configuration file for OpenVPN clients. We should only need to change 3 lines here. Replace YOUR_PUBLIC_IP_ADDRESS with a FQDN or your public IP address.

sudo cp /usr/share/doc/openvpn-2.4.6/sample/sample-config-files/client.conf /etc/openvpn/client.conf
sudo vim /etc/openvpn/client.conf

Change:

remote my-server-1 1194

To:

remote YOUR_PUBLIC_IP_ADDRESS 1194


Change:

cert client.crt

To:

cert CLIENT_NAME.crt


Change:

key client.key

To:

key CLIENT_NAME.key


 

Now for the client configuration. We will need a few files for this. They are listed below:
/etc/openvpn/easy-rsa/pki/private/CLIENT_NAME.key
/etc/openvpn/easy-rsa/pki/issued/CLIENT_NAME.crt
/etc/openvpn/easy-rsa/pki/ca.crt
/etc/openvpn/easy-rsa/pki/ta.key
/etc/openvpn/client.conf
Lets copy these files to a directory and then zip them up so we can send them to our client machine.

sudo mkdir -p /etc/openvpn/client/CLIENT_NAME
sudo cp /etc/openvpn/easy-rsa/pki/private/CLIENT_NAME.key /etc/openvpn/client/CLIENT_NAME
sudo cp /etc/openvpn/easy-rsa/pki/issued/CLIENT_NAME.crt /etc/openvpn/client/CLIENT_NAME
sudo cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/client/CLIENT_NAME
sudo cp /etc/openvpn/easy-rsa/pki/ta.key /etc/openvpn/client/CLIENT_NAME
sudo cp /etc/openvpn/client.conf /etc/openvpn/client/CLIENT_NAME/CLIENT_NAME.ovpn
sudo su
cd /etc/openvpn/client/CLIENT_NAME
sudo zip CLIENT_NAME.zip *
exit

Transfer CLIENT_NAME.zip to your client machine. Unzip it and open it OpenVPN. On linux the command would be

cd /home/your_name/where_you_extracted_the_zip_file
sudo openvpn –config CLIENT_NAME.ovpn

Open your web browser, goto google.com. search for “what is my ip address”. This will check to see if your traffic is going through the VPN or not.

That’s it!