How to install OpenVPN on CentOS 7 linux

In the series of tutorials about installing various tunneling technology, we reach to show how to install OpenVPN on CentOS 7 linux.

OpenVPN is an open-source Secure Socket Layer (SSL) VPN solution that accommodates a wide range of configurations.

In this tutorial, we plan to authenticate users by combination of username and password. also another way is to authenticate them by digital certificate.

Here is our environment:

OS: CentOS 7 linux on VMWare
Firewall: firewalld
Selinux: enforcing
IP Address: 192.168.1.128

1-Prerequisites

First we update OS package list and then install easyRSA and epel release package.
easyRSA is a public key infrastructure management tool which will help us set up an internal certificate authority (CA) for use with our VPN.
We’ll also use Easy RSA to generate our SSL key pairs later on to secure the VPN connections.

# yum update

because openvpn is not available in default centos 7 repositories, we will install epel repository:

# yum install epel-release

to install easyRSA, we need to have wget package and fetch easyRSA by it. so install wget:

# yum install wget

then fet easyRSA package:

wget -O /tmp/easyrsa https://github.com/OpenVPN/easy-rsa-old/archive/2.3.3.tar.gz

then exctract downloaded archive:

# tar xfz /tmp/easyrsa

this will create a directory called easy-rsa-old-2.3.3. now create required directories:

# mkdir -p /etc/openvpn/easy-rsa/

then copy extracted archive files to created directory:

# cp -rf easy-rsa-old-2.3.3/easy-rsa/2.0/* /etc/openvpn/easy-rsa

2- Install OpenVPN

Now that required packages and files have been installed, it’s time to install OpenVPN itself:

# yum install openvpn

OpenVPN has a sample configuration file. we copy this file to openvpn directory:

# cp /usr/share/doc/openvpn-2.4.8/sample/sample-config-files/server.conf /etc/openvpn

Note: remember to replace 2.4.8 with the version that is installed on your OS.

3- Configure OpenVPN

Now we dig in through openvpn configuration file and make some changes to fit our needs. so open server.conf file with your favorite editor. here we use vim:

# vim /etc/openvpn/server.conf

remember that in openvpn config file, comment lines start with a “;” character. find and uncomment this line:

push "redirect-gateway def1 bypass-dhcp"

Note: enabling this functionality can cause connectivity issues with other network services, like SSH.
openvpn normally listens on port 1194. if you want to change this port find this line and change it:

port 1194

in openvpn it’s possible to specify which protocol do you want to use. here we use tcp:

proto tcp

remember to comment this line:

;proto udp

leave the following lines unchanged and remember to uncomment them if they are commented:

dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
persist-key
persist-tun
verb 3
keepalive 10 120
comp-lzo

in this tutorial we decided to authenticate user by username/password combination. so add this line:

plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so login

because all of clients traffic will be routed through openvpn, we need to tell them which DNS servers they should use.
here we use google public dns 8.8.8.8 and 4.2.2.4.
so find line “push “dhcp-option DNS” and change it as below:

push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 4.2.2.4"

openvpn should be run with least privilege. so uncomment these lines:

user nobody
group nobody

now find and uncomment the following lines:

server 10.8.0.0 255.255.255.0

this line tell openvpn to act as a subnet and assign ip to clients in range of 10.8.0.0/24.
also we dont want to ask clients for their certificate. so add this line to the end of configuration:

verify-client-cert none

in addition add these lines to the end of configuration:

log /var/log/openvpn/openvpn.logfinally save changes and exit.

4- Generate keys and certificates

to encrypt openvpn traffic, we need to generate related public and private key and also CA certificate to send to clients.
first, create a directory for them:

# mkdir /etc/openvpn/easy-rsa/keys/

then to start generating keys and certificates, go to easy-rsa directory:

# cd /etc/openvpn/easy-rsa
# source ./vars

then run clean-all script to remove any keys and certificates already in folder:

# ./clean-all

now first of all, we create CA certificate private key:

# ./build-ca

if you don’t plan to change default suggested values during CA certificate generation, just press enter.
the output will be ca.key file. this file should be kept in a secure location.
now we create public and private key for server:

# ./build-key-server server

again if you don’t plan to plan to change default suggested values, just hit enter.
be aware if you enter a challenge password, you will be asked for it when connecting to the VPN from your client.
If you don’t want to set a challenge password, just leave this line blank and press ENTER.
the final part is to create Diffie-Helman key:

# ./build-dh

now copy generated keys and certificates to openvpn directory:

# cd /etc/openvpn/easy-rsa/keys/
# cp dh2048.pem ca.crt server.crt server.key /etc/openvpn/

Finally, copy the versioned OpenSSL configuration file, openssl-1.0.0.cnf, to a versionless name, openssl.cnf. Failing to do so could result in an error where OpenSSL is unable to load the configuration because it cannot detect its version:

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

5- Configure routing

Here we use firewalld as our firewall that has been installed during Centos installation.
so first we want to chech in which zone, openvpn virtual interface exists:

# firewall-cmd --get-active-zones

and the output will be:

Output
public
  interfaces: eno16777736

next, we add openvpn service to list of allowed services:

# firewall-cmd --zone=trusted --add-port=1194/tcp --permanent

then reload firewall:

# firewall-cmd --reload 

now we should configure nat to masquerade private ip to public ip:

# firewall-cmd --permanent --add-masquerade

Next, forward routing to your OpenVPN subnet. You can do this by first creating a variable (IFACEin our example) which will represent the primary network interface used by your server, and then using that variable to permanently add the routing rule:

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

finally reload firewall rules:

# firewall-cmd --reload

then we enable ip forwarding. so open /etc/sysctl.conf and put this line in it:

net.ipv4.ip_forward = 1

and then make this change permanent:

# sysctl -p

6- Start OpenVPN service

Now it’s time to start openvpn service. we want to make it started at system boot:

# systemctl -f enable [email protected]

finally start it:

# systemctl start [email protected]

and check if it has been started properly:

# systemctl status [email protected]

7- Define Users

To allow users authenticate themselves successfully, we should define username/passwords.
here we use pam plugin thant directly authenticate users against /etc/passwd and /etc/shadow.
so we add user to Centos but don’t allow them to have a shell and home directory:

# useradd -M -s /bin/false vpnuser1
# passwd vpnuser1

repeat these steps for every user you define.

8- Configure client

Server side configuration has been done completely. now we want to make client configuration file.
first copy content of /etc/openvpn/ca.crt.
then create a file named client.ovpn and put the following lines in it:

client
nobind
dev tun
proto tcp
remote 192.168.1.128 1194
comp-lzo yes
persist-key
persist-tun
auth-user-pass
auth-nocache
verb 3
cipher aes-256-cbc
<ca>
-----BEGIN CERTIFICATE-----
MIIG1jCCBL6gAwIBAgIJANEywsva8iRhMA0GCSqGSIb3DQEBCwUAMIGiMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEVMBMG
A1UEChMMRm9ydC1GdW5zdG9uMREwDwYDVQQLEwhjaGFuZ2VtZTERMA8GA1UEAxMI
Y2hhbmdlbWUxETAPBgNVBCkTCGNoYW5nZW1lMR8wHQYJKoZIhvcNAQkBFhBtYWls
QGhvc3QuZG9tYWluMB4XDTE5MTIwMjE0NDUwNVoXDTI5MTEyOTE0NDUwNVowgaIx
CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2Nv
MRUwEwYDVQQKEwxGb3J0LUZ1bnN0b24xETAPBgNVBAsTCGNoYW5nZW1lMREwDwYD
VQQDEwhjaGFuZ2VtZTERMA8GA1UEKRMIY2hhbmdlbWUxHzAdBgkqhkiG9w0BCQEW
EG1haWxAaG9zdC5kb21haW4wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDCWVN8EWz4HTNLzSI6UQx8aKTY5DbxydqwuhxLAv2TFEFDaRGsPfRJCzj0iRR5
3cghUnAr24HaYoSV/Foa2wwT+l/K4YEP4MjPwOWX9lPUNfYuPYnAWE+jy4fRHSuv
714WaEQbzPtUSHtevHVrn26CXniJzEDE5S31rAxRccz0uUsAQoLoKpvm1GfDmTIF
nprjImDXSPm6yXiEdUtomwW0lYRleJstgFpJrVQ9ZbfIoy/UBAuGNyyukg709ho4
wyd8Uq3HVodEy65i+cLBwuzy9JILUXPnFQ9mzJG13ENoEHIAzzlghjbjaUazfG0g
/dC8SkTd9+FjVGQMtqbo3dWmaMGHJ+SdFqAZgntv7J1U8y8Orf2LSErWOwRXuKbA
8XqRRj5Vv9Gx03FfaH4E5v8baqvq8QK7j1zVtQEo5vNy4JDDtEmdAfKdl8toKRa6
yekuzOVlL0mp1Fr6qdRt1bKtW0EOJid5F3zfCKkj0TVns4WuD3ZShTHGHqbzBguN
8xaUhD+2fyY2HpEMCMfM9PDMnQJRKNSI3G5V5S6R0b2Z9k+qzHT/iH117ohQ7NJi
265RBmOB8ltXAFzq5gXwDbVTZdB1/CzBc6gh6k9twzn4fQyAbHtAr9iicaU2edEl
P/Z2f6YnIj82rH9IsezetVnncqG+3GjjDHpLgsqzC8yiMQIDAQABo4IBCzCCAQcw
HQYDVR0OBBYEFMUdJfAPWShQf7fp7KVa9CcjESqPMIHXBgNVHSMEgc8wgcyAFMUd
JfAPWShQf7fp7KVa9CcjESqPoYGopIGlMIGiMQswCQYDVQQGEwJVUzELMAkGA1UE
CBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEVMBMGA1UEChMMRm9ydC1GdW5z
dG9uMREwDwYDVQQLEwhjaGFuZ2VtZTERMA8GA1UEAxMIY2hhbmdlbWUxETAPBgNV
BCkTCGNoYW5nZW1lMR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3QuZG9tYWluggkA
0TLCy9ryJGEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAaECmzLQO
CtT+hz9SKyeDNqVjukoEYydj7x8n2JupJCRVGI8NoovelKWO5D4/gn3vf76RZHcH
mK9/xEZI5tr2nRyYaCEgTiIK6QrCTVZmL6Uk8qW6CTbbhSSsk0zxFHXfbqbv/ZOu
sHo3tCdDaeA8DmgldNgaiDdauDkMiT+aDvl+SYty2Jri/hRyft6PcrPHSoB3tJOa
vWA+MOOs6SvnoHCSbODmBGmJYPSNVzV1bG/evLxlSY2YQwfpWoYY/PkWwr7uJ6jN
tOHiwVkrpXaJRrXdL540xDYZDGbb1We8no3wmu2qEExAMYF3aH8H2pXY/BPyINme
VY5vdsXePEHbvElQqBnXOWpTov8Laj/gJgyoHCQqGMxTQuoRGGpzhq1OvUKhMq/r
pN2MO/5Ltev6zBaK/g7XP8Lzgnd6P+wUKF8HqjqUcJMxEmv72mEQaL9Zen2R8avR
7WvZokJj2sPqB6atqfaBYoMmeHapln2kOXnrb+LNUjp6v50uEOVUGiGEdq4S+7P9
8461e3qkvtBQJMhFIT2+EnMwKEn1045kwu6z0ebRr6w0v7l31dFXx+IDYobv+LiN
UJj5HTB+cMKgN/lbBgXDU3QvCKc8HgURwhX2zwV0k+4LLrSyT6Kp8/rIzJhz3pAf
XIKcFrzsbB1jUcE1XOmwn6SHRqcse5uoLcw=
-----END CERTIFICATE-----
</ca>

Note: remember <ca> and </ca> with your own /etc/openvpn/ca.crt content.
finally give created client.ovpn file to your client. they import this file to their openvpn connections.

OpenVPN windows client: https://openvpn.net/client-connect-vpn-for-windows/
OpenVPN iOS client: https://apps.apple.com/us/app/openvpn-connect/id590379981
OpenVPN android client: https://play.google.com/store/apps/details?id=net.openvpn.openvpn