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:


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

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
verb 3
keepalive 10 120

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

plugin /usr/lib64/openvpn/plugins/ 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 and
so find line “push “dhcp-option DNS” and change it as below:

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

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

user nobody
group nobody

now find and uncomment the following lines:


this line tell openvpn to act as a subnet and assign ip to clients in range of
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:

  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 | awk 'NR==1 {print $(NF-2)}')
# firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s -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:

dev tun
proto tcp
remote 1194
comp-lzo yes
verb 3
cipher aes-256-cbc

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:
OpenVPN iOS client:
OpenVPN android client: