How to Install OpenVPN on CentOS 7

Installing and Configuring OpenVPN Server on CentOS with Client and Server Configuration Examples.
How To Install OpenVPN on CentOS.

Time flies, tools change a bit and new options are recognised, so I decided to update the step-by-step guide.

Relevance of the article: the current moment. Software: CentOS 7 minimal, SELinux enabled. All software updated with yum update.

[wpcd_coupon id=340]

⚠️Make an effort not to disable SELinux immediately after installing CentOS! This is briefly touched upon at the end of the article as well. Even the built-in Windows firewall can do a good job, let alone SELinux.

Step 1: Install OpenVPN

Additional utilities:

yum install wget

Installing OpenVPN:

yum install epel-release
yum install openvpn

Step 2: PKI Public Key Infrastructure

The directory for keys:

mkdir /etc/openvpn/keys
cd /etc/openvpn/keys

In general, all operations with OpenVPN keys can be done using OpenSSL. But there is Easy-RSA utility that used to come with OpenVPN, but now it is a separate project https://github.com/OpenVPN/easy-rsa. We will copy this utility to our server:

wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz
tar xvf EasyRSA-3.0.8.tgz
 cd /etc/openvpn/keys/EasyRSA-3.0.8

⚠️ The second option with yum install easy-rsa, but there is a disadvantage here in that you may get a newer version of easy-rsa than the one you are working with now, and you still copy those scripts and work with copies in the future. If via yum, remember to copy the files from /usr/share/easy-rsa/3.0.8.

Create a configuration file, with an understanding of what will happen. For example, the EASYRSA_PKI option (by default, “$PWD/pki”) specifies the path where the directory for the keys will be created. The command “init-pki” will perform “rm -rf” of the directory contents, be careful! You are still initialising the key infrastructure, it’s not there yet, but if anything is there it will be erased. Most options are default, edit country, OU, email etc. to your liking. Pay attention to validity periods (in days) of CA, CRL, CERT certificates.

⚠️ Attention! Different manuals have different sets of options, think about them all. For example, somewhere I saw: set_var EASYRSA_SSL_CONF “$EASYRSA/openssl-1.0.cnf”. Are you sure you need it? The description says: if you need to use a specific openssl config file, you can reference it here. Normally this file is auto-detected from a file named openssl-easyrsa.cnf from theEASYRSA_PKI or EASYRSA dir (in that order.) NOTE that this file is Easy-RSA specific and you cannot just use a standard config file, so this is an advanced feature.
⚠️ Attention! If you want any special OpenSSL options, specify the config file, understanding that you have at least one, and understanding why you want it.

In the “vars” configuration file, try to specify either the options that are important to you or the ones you override, but don’t copy the whole default config here.

nano vars
set_var EASYRSA                 "/etc/openvpn/keys/EasyRSA-3.0.8"
set_var EASYRSA_PKI             "$EASYRSA/pki"

set_var EASYRSA_REQ_COUNTRY    "US"
set_var EASYRSA_REQ_PROVINCE   "California"
set_var EASYRSA_REQ_CITY       "San Francisco"
set_var EASYRSA_REQ_ORG        "Copyleft Certificate Co"
set_var EASYRSA_REQ_EMAIL      "me@example.net"
set_var EASYRSA_REQ_OU         "My Organizational Unit"

set_var EASYRSA_KEY_SIZE        4096
set_var EASYRSA_ALGO            rsa
set_var EASYRSA_CA_EXPIRE       3650
set_var EASYRSA_CERT_EXPIRE     3650
set_var EASYRSA_CRL_DAYS        3650
set_var EASYRSA_DIGEST          "sha512"

There is nothing complicated there, see for yourself.

Step 3: Create a PKI (Public Key Infrastructure)

./easyrsa init-pki

This will create the directory /etc/openvpn/keys/EasyRSA-3.0.8/pki/.

⚠️ Warning! Once the infrastructure has been created, never run the init-pki command again! This command will, among other things, execute “rm -rf” of the directory contents, be careful!

Step 4: Create your own CA

When connecting clients to the OpenVPN server, to ensure that the server and client certificates are not forged, a CA (Certificate Authority) must be created. CAs can be own (mostly self-signed) and public, like Thawte, StartSSL, etc. In this example we will consider the situation when own CA is used – at least it is much cheaper. Even your CA does not have to be on the same server as the OpenVPN server, but more often the location of the CA for OpenVPN is on the same server as OpenVPN itself.

Creating your own CA:

./easyrsa build-ca

You could avoid entering a password (./easyrsa build-ca nopass), but if someone copies your CA’s private key, they will be able to sign “dummy” keys. You must guard your CA private key as the apple of your eye, as everything else is verified with it. Therefore the password must be brute force. After all, you won’t be using it every day.

We now have a ca.key and a ca.crt certificate:

  • /etc/openvpn/keys/EasyRSA-3.0.8/pki/private/ca.key
  • /etc/openvpn/keys/EasyRSA-3.0.8/pki/ca.crt

The secret key must be left on the server and not given to anyone else. Every time a new server or user certificate is issued we will need the secret key password! The CA certificate (ca.crt) is public and we will share it with the user certificates with clients.

Step 5: OpenVPN server certificates

Create a certificate request for the server without a password using the nopass option, otherwise you will have to enter the password from the console every time the server starts up:

./easyrsa gen-req server nopass

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

Sign the certificate request with our CA:

./easyrsa sign-req server server

As the script runs, we enter the password from the CA we specified earlier and answer yes. We got a certificate signed by our certificate authority for the server – /etc/openvpn/keys/easy-rsa-master/easyrsa3/pki/issued/server.crt

Step 6: Generate a Diffie-Helman key

./easyrsa gen-dh

In the case of OpenVPN, the Diffie-Helman file is needed to provide protection against decryption if the keys have been stolen. This refers to traffic that was recorded and stored before the keys were stolen. It’s a wide topic and I didn’t dare to overload the article with lyric digressions.

The generation takes a decent amount of time (in relation to other keys). In the end we get the key /etc/openvpn/keys/EasyRSA-3.0.8/pki/dh.pem

Step 7: List of withdrawn CRL certificates

Employees quit, lose their mobile phones and therefore need to be denied access to a VPN. You must revoke their certificate. To be able to revoke a client certificate you must create a list of revoked CRL certificates:

./easyrsa gen-crl

The file /etc/openvpn/keys/EasyRSA-3.0.8/pki/crl.pem will be created, which will contain a list of revoked certificates. This file must be copied to /etc/openvpn/ directory, specified in the OpenVPN server config and the OpenVPN server restarted.

Copy to /etc/openvpn folder all keys required for openvpn server (remember, we are in /etc/openvpn/keys/EasyRSA-3.0.8):

cp pki/{ca.crt,dh.pem,crl.pem} /etc/openvpn/
cp pki/issued/server.crt /etc/openvpn/
cp pki/private/server.key /etc/openvpn/

Create an HMAC file, for additional client and server verification (to protect against DDoS):

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

The file ta.key must be copied and transferred to the client.

In a normal server configuration, after startup (from root) permissions are changed to an unprivileged user (nobody or specially created). This user must have read permissions to the certificates for client authentication:

chmod 644 /etc/openvpn/ca.crt
chmod 644 /etc/openvpn/crl.pem
chmod 644 /etc/openvpn/dh.pem
chmod 644 /etc/openvpn/server.crt

The server.key, ta.key should only be available to root (chmod 600)!

Step 8: Client keys

Create a key for the openvpn client:

cd /etc/openvpn/keys/EasyRSA-3.0.8
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1

There may be situations where it is better to protect the client key with a password, at least a simple one. Then whenever you connect to the VPN you will need to enter the password. This can be handy if, for example, you don’t want your child to accidentally connect to your work network and cause trouble. You just don’t need to specify “nopass” at the end of the command above.

We will end up with two files:

Public client certificate: /etc/openvpn/keys/EasyRSA-3.0.8/pki/issued/client1.crt
Client private key: /etc/openvpn/keys/EasyRSA-3.0.8/pki/private/client1.key

The client will need to pass copies of the following files along with the config (see below):
client1.crt;
client1.key;
ca.crt;
ta.key
which are all used in the client config. No files other than those specified in the client config need to be transferred to the client!

Step 9: Configure OpenVPN

The default server configuration file is /etc/openvpn/server.conf. You will probably not need to change its location.

[wpcd_coupon id=340]

Note the common options for client and server. These are encryption type, traffic compression, etc. Some options are mirrored. For example, on the server ta.key 0, on the client ta.key 1, etc.

Example 1 (OpenVPN server config):

port 1194
proto udp
dev tun

ca ca.crt
cert server.crt
key server.key
dh dh.pem

# Checking whether the client certificate has been withdrawn
crl-verify crl.pem

server 10.8.12.0 255.255.255.0
ifconfig-pool-persist ipp.txt

# Let all client traffic go through the VPN
push "redirect-gateway def1"

# DNS hosting server (or others as you see fit):
push "dhcp-option DNS 8.8.8.8"

keepalive 10 120
tls-server
tls-auth ta.key 0
tls-timeout 120
auth MD5
cipher BF-CBC
comp-lzo
max-clients 10
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log /var/log/openvpn.log

# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 4

Example 2 (OpenVPN server configuration):

port 3725
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
crl-verify crl.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1"
push "dhcp-option DNS 8.8.8.8"
remote-cert-eku "TLS Web Client Authentication"
keepalive 10 120
tls-server
tls-auth ta.key 0
tls-timeout 120
auth SHA512
cipher AES-256-CBC
comp-lzo
max-clients 10
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
#log-append  openvpn.log
#log /dev/null
#log /var/log/openvpn.log
log openvpn.log
verb 6

Step 10: Configure a OpenVPN Client

Some options must be symmetrical to the server options, in particular encryption type (here BF-CBC), traffic compression, etc. All of the configs below work.

These are examples of OpenVPN client configs for Windows. For Linux all the same, only paths to the key files have to be specified as in the server config (see above).

Example 1 (OpenVPN client config):

client
dev tun
proto udp
remote 1.2.3.4 1194
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
tls-auth "C:Program FilesOpenVPNconfigta.key" 1
auth MD5
ca "C:\\Program Files\\OpenVPN\\config\\ca.crt"
cert "C:\\Program Files\\OpenVPNconfig\\client1.crt"
key "C:\\Program Files\\OpenVPN\\config\\client1.key"
cipher BF-CBC
comp-lzo
verb 3

Example 2 ( matches the example of the second server config):

client
dev tun
proto udp
remote 1.2.3.4 3725
resolv-retry infinite
nobind
block-outside-dns
persist-key
persist-tun
mute-replay-warnings
remote-cert-eku "TLS Web Server Authentication"
remote-cert-tls server
tls-client
tls-auth "C:\\Program Files\\OpenVPN\\config\\ta.key" 1
auth SHA512
ca "C:\\Program Files\\OpenVPN\\config\\ca.crt"
cert "C:\\Program Files\\OpenVPN\\config\\client1.crt"
key "C:\\Program Files\\OpenVPN\\config\\client1.key"
cipher AES-256-CBC
comp-lzo
verb 3

Step 11: Start OpenVPN

systemctl start openvpn@server

Check if it is running or not (assume that port 3876/udp is specified in the config):

netstat -tulnp | grep 3876

udp 0 0 0.0.0.0:3876 0.0.0.0:* 10431/openvpn

Great, it’s running on the specified port.

Well, or so we check:

systemctl status openvpn@server

If all is OK, enable autostart

systemctl enable openvpn@server

If something is wrong, look at the log. SELinux may not be allowing OpenVPN to run on the port you selected.

semanage port -a -t openvpn_port_t -p udp 3876

and try running OpenVPN again.

In any case, the log file will help you. After debugging, the log file can also be disabled (log /dev/null).

Step 12: Revoke client certificates

To revoke client1’s certificate:

cd /etc/openvpn/keys/EasyRSA-3.0.8/pki/
./vars
./easyrsa revoke client1

This will create a new file crl.pem which must be copied into /etc/openvpn directory, replacing the old one and restarting the OpenVPN server.

And in the index.txt file the corresponding certificate will be marked with R (working V and withdrawn – R).

The OpenVPN key infrastructure is essentially a normal OpenSSL CA, so much of what you know about OpenSSL will work for OpenVPN. For example, a list of certificates with serial numbers, whether they are revoked, and other information can be found in the index.txt file.

If you try to connect to a server with a revoked certificate, the server log may show the following events (verb level 4):

CRL CHECK FAILED: C=RU, ST=NW, L=City, O=Org, OU=OU, CN=client1, name=EasyRSA, emailAddress=client1@localhost.local (serial 04) is REVOKED

TLS_ERROR: BIO read tls_read_plaintext error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
TLS Error: TLS object -> incoming plaintext read error
TLS Error: TLS handshake failed

Note the line “CRL CHECK FAILED”: the certificate with serial number 04 is REVOKED!

Step 13: Firewall (iptables) and Routing Configuration

Allow access to the OpenVPN server from the external interface:

iptables -A INPUT -i eth0 -p udp --dport 3876 -j ACCEPT

After this, OpenVPN clients will be able to connect to the server but may not be able to go outside the server, depending on the current firewall settings.

To allow clients to access the Internet or LAN resources, first enable routing on the OpenVPN server (applies until reboot):

echo 1 > /proc/sys/net/ipv4/ip_forward

To save after reloading, save the line at the end of the file:

nano /etc/sysctl.conf
net.ipv4.ip_forward = 1

To allow OpenVPN clients to access the internet on behalf of the server (external interface eth0):

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

To allow OpenVPN clients to work with the local network (LAN interface eth1):

iptables -A FORWARD -i tun0 -o eth1 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -o tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Example of a working iptables script for an OpenVPN server:

#!/bin/sh

IF_EXT="eth0"
IF_OVPN="tun0"

OVPN_PORT="3876"

IPT="/sbin/iptables"
IPT6="/sbin/ip6tables"

# flush
$IPT --flush
$IPT -t nat --flush
$IPT -t mangle --flush
$IPT -X

$IPT6 --flush

# loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

# default
$IPT -P INPUT DROP
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT

$IPT6 -P INPUT DROP
$IPT6 -P OUTPUT ACCEPT
$IPT6 -P FORWARD ACCEPT

# allow forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# NAT
# #########################################
# SNAT - local users to out internet
$IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE

# INPUT chain
# #########################################
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# ssh
$IPT -A INPUT -i $IF_EXT -p tcp --dport 2685 -j ACCEPT
# icmp (vpn)
$IPT -A INPUT -i $IF_OVPN -p icmp -s 10.8.0.0/24 -j ACCEPT
# openvpn and dns (vpn)
$IPT -A INPUT -i $IF_OVPN -p udp --dport 53 -s 10.8.0.0/24 -j ACCEPT
# openvpn
$IPT -A INPUT -i $IF_EXT -p udp --dport $OVPN_PORT -j ACCEPT

Step 14: Creating a script to generate client configuration file .OVPN

Create a simple script to generate configuration files with relevant certificates, keys and encryption files.

Create and open make_config.sh.

#!/bin/bash
 
# First argument: Client identifier
 
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/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
  • base.conf – copy of the configuration file for the client
  • OUTPUT_DIR – directory in which the .ovpn file will be created
  • KEY_DIR – directory to which all previously generated keys should be copied

Make it an executable file by command:

chmod 700 make_config.sh

It is now easy and straightforward to generate client configuration files. Generate the .ovpn file for the client created in Step 8: Client keys.

./make_config.sh client1

If everything went well, we should get the client1.ovpn file in the OUTPUT_DIR directory. You must now copy or move the resulting configuration file to the client device: computer or smartphone.

Step 15: Connect a Client to OpenVPN

For Linux Users

To connect to OpenVPN, run the command:

openvpn --config /path/to/client1.ovpn

For Windows Users

  1. First, copy the client.ovpn configuration file in the c:\Program Files\OpenVPN\config\ directory.
  2. Download and install the OpenVPN application. You can find the latest build on the https://openvpn.net/community-downloads/. Once you have installed the application, launch OpenVPN.
  3. Right-click the OpenVPN system tray icon and select Connect. To perform this task, you need administrative privileges.
  4. To connect automatically, you need to change the shortcut on the desktop:
openvpn-gui.exe --connect client1.ovpn

For macOS Users
You can connect to OpenVPN from a macOS system using Tunnelblick (an open-source graphic user interface for OpenVPN on OS X and macOS).

Before launching Tunnelblick, make sure to store the client.ovpn configuration file in the ~/Library/Application Support/Tunnelblick/Configurations directory

Conclusion

After reading this article, you should have successfully installed and configured OpenVPN on a CentOS server. If you have any questions, feel free to write in the comments.

[paypal-donation]
Dmytro Yakovenko/ author of the article

Here and now! Founder of the Hosting Consultant service (dieg.info). DevOps with over 15 years of experience. Internet marketer with more than 6 years of experience.

Like this post? Please share to your friends:
VPN Report
Comments: 4
  1. Bear

    Thanks for ones marvelous posting! I seriously enjoyed reading it, you can be a great
    author.I will ensure that I bookmark your blog and will often come back in the
    foreseeable future. I want to encourage you to ultimately continue your great job,
    have a nice evening!

  2. digital wall

    Short but very accurate information… Thanks for sharing this one.
    A must read article!

  3. trisha beyers

    Keep this going please, great job!

  4. Dmytro Yakovenko (author)

    I get a lot of emails in private messages to create a simple guide for setting up an OpenVPN server. Please, an article for housewives :smile: How to set up a VPN in 5 minutes https://bestvpn.report/openvpn-for-housewives/

Leave a Reply

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: