Thursday September 29th, 2016


Set up and configure OpenVPN on CentOS 7

In this post, I will walk you through how to set up and configure an OpenVPN on CentOS 7 (Linux distribution). As a use case, I've setup and configure an OpenVPN between AWS and some service in-house. In a nutshell, a VPN connection is based on a Client/Server architecture from which the client can securely connect to the server through the VPN connection. OpenVPN is one of the most popular Open Source implementation of VPN solution and it uses SSL/TLS to create an encrypted secure connections.

Simple Scenario

In this scenario, I will use AWS VPC in which I will have two subnets one public and one private. I will install and configure the VPN server in the public subnet which in turn will allow me to access securely the private subnet, pretty simple setup. Same principles if you wanna set it up on your on-premise infrastructure.

aws vpn


Overview of public certificates and private keys

Let's walk through the public certificates and private keys.

  • Certificate authority (public certificate and private key) - ca.crt and ca.key
  • Diffie Hellman parameters file (required for the TLS) - dh.pem
  • Server key pair (public certificate and private key), for example - servername.crt and servername.key
  • Client key pair (public certificate and private key), for example - clientname.crt and clientname.key
  • Hash-based Message Authentication Code (HMAC) key ,extra security which adds "extra protection" to the TLS channel by requiring that incoming packets have a valid signature generated ta.key

On the server, you should have the following keys and certificates

/etc/openvpn/server.crt
/etc/openvpn/server.key 
/etc/openvpn/ca.crt 
/etc/openvpn/dh.pem
/etc/openvpn/ta.key

On the client, you should have the following keys and certificates

ca.crt 
clientname.key
clientname.crt 
ta.key

In case you get confused on how to get those keys and certificates, don't worry I will walk you through along the way on how to generate them using easy-rsa.


Server Setup

Now, we will setup up our VPN server. First we will install the epel-release repo since the OpenVPN RPMs are not available on the CentOS 7 default repositories.

$ sudo yum install -y epel-release

Install OpenVPN and Easy RSA (which will be used to keys and certificates generation)

$ sudo yum install -y openvpn easy-rsa

Now copy the server.conf sample to the /etc/openvpn/

$ sudo cp /usr/share/doc/openvpn-*/sample/sample-config-files/server.conf /etc/openvpn

Modify the server.conf with the following content

# Local IP address to listen on
# In case you have two VPNs you can run them 
# on different port 
local 0.0.0.0

# TCP Port number, do not forget to open this on your firewall
port 21194

# TCP protocol (You can also use the UDP protocol)                                             
proto tcp                                              

# Create a routed IP table 
dev tun                                                

# Certificate authority 
ca ca.crt   

# Server certificate                                            
cert server.crt 

# Server private key                                       
key server.key 

# Diffie Hellman                                         
dh dh2048.pem                                         

# Your VPN subnets which will be use 
# basically to choose the server IP e.g 10.92.0.1 
# And the rest of IP range will be used by VPN clients
# Make sure you don't use the same IP range (CIDR) as for your subnets 
# The Internet Assigned Numbers Authority (IANA) has reserved the following three blocks of the IP address space for private internets (codified # in RFC 1918):
# 10.0.0.0
# 172.16.0.0
# 192.168.0.0
server 10.92.0.0 255.255.255.0


# This will maintain the client virtual IP address 
# In case OpenVPN gets restarted, the clients will be 
# reconnected to the same virtual IP addresses
ifconfig-pool-persist ipp.txt


# This will allow other private subnets 
# to be reachable behind the OpenVPN server. 
# e.g these are my private subnets 
push "route 172.31.0.0 255.255.255.0"  # My subnet 1 with CIDR 172.31.0.0/24
push "route 172.31.1.0 255.255.255.0"  # My subnet 2 with CIDR 172.31.1.0/24 
push "route 172.31.2.0 255.255.255.0"  # My subnet 3 with CIDR 172.32.2.0/24
push "route 10.92.0.0 255.255.255.0"

# DNS servers e.g (Google)
# You can use your owns
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period
keepalive 10 120

# To generate run this: (openvpn --genkey --secret ta.key)
# For extra security beyond that provided
# by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and port flooding.
tls-auth ta.key 0 

# Blowfish (default)
cipher BF-CBC 

# Enable compression on the VPN link    
comp-lzo

user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log

Keys and certificates generation

Now, let's generate the following keys and certificates and for that we will use easy-rsa.

Copy the openssl.conf

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

First create these folders for storing the keys and certificates

$ sudo mkdir -p /etc/openvpn/easy-rsa/keys  # This is where all keys and certificates will be stored by easy-rsa

Now copy the sample of easy-rsa

$ sudo cp -rf /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa

For making these generations faster, we will modify the vars file.

$ sudo vi /etc/openvpn/easy-rsa/vars

And the following has been modified. These variables will be used by default in case you do not defined any while generating the certificates and the keys.

# These are the default values for fields
# which will be placed in the certificate.
# Do not leave any of these fields blank.
export KEY_COUNTRY="SE"
export KEY_PROVINCE="Stockholm"
export KEY_CITY="Stockholm"
export KEY_ORG="Tutorial"
export KEY_EMAIL="kalilou@tutorial.com"
export KEY_OU="DevOps"

# X509 Subject Field
export KEY_NAME="server"

Simple to generate the certificates and keys if we are in the easy-rsa directory

$ sudo su 
$ cd /etc/openvpn/easy-rsa

Source the vars

$ source ./vars

Clean all existing keys and certificates

$ ./clean-all

Generate the certificate authority (ca.key and ca.crt )

$ ./build-ca

Generate server certificate and key (server.crt, server.key and server.csr ), don't forget to sign by typing yes 'y' in the process.

$ ./build-key-server server

Generate a Diffie-Hellman key exchange file (dh2048.pem )

$ ./build-dh

Generate the tls-auth (ta.key )

$ openvpn --genkey --secret ta.key # This will be stored under /etc/openvpn/easy-rsa/

Let's check the generated keys and certificates

$ ls -l  server.* ca.* dh2048.pem
-rw-r--r--. 1 root root 1692 Sep 27 14:54 ca.crt
-rw-------. 1 root root 1708 Sep 27 14:54 ca.key
-rw-r--r--. 1 root root  424 Sep 27 14:55 dh2048.pem
-rw-r--r--. 1 root root 5428 Sep 27 14:55 server.crt
-rw-r--r--. 1 root root 1070 Sep 27 14:55 server.csr
-rw-------. 1 root root 1704 Sep 27 14:55 server.key

Now let's copy the keys and certificates to the /etc/openvpn directory

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

Now install iptables RPM

$ yum install -y iptables-services
$ iptables --flush</code>

Modify this file # vi /etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [3042:182520]
:OUTPUT ACCEPT [664:79706]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -j ACCEPT
-A INPUT -i tun0 -j ACCEPT
-A INPUT -i eth0 -p tcp -m state --state NEW -m tcp --dport 21194 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -m state --state INVALID -j DROP
-A FORWARD -s 127.0.0.0/8 -d 127.0.0.0/8 -i lo -m state --state NEW -j ACCEPT
-A FORWARD -s 127.0.0.0/8 -d 127.0.0.0/8 -o lo -m state --state NEW -j ACCEPT
-A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o tun0 -j ACCEPT
COMMIT

Start the iptables service

$ systemctl start iptables

Enable the IP forwarding in /etc/sysctl.conf by modifying or adding: net.ipv4.ip_forward = 1 and restart the network service # systemctl restart network

Now start the OpenVPN service

$ systemctl start openvpn@server  # In case you have some issues, try setting SELinux to be permissive (# setenforce 0)

Generate the client certificates and keys

Create your first VPN user certificates and keys, in my case the first user will be myself (kalilou). Do not forget to sign by typing yes 'y' in the process

$ cd /etc/openvpn/easy-rsa/
$ ./build-key kalilou

This will generate the following files: kalilou.crt, kalilou.key and kalilou.csr

Create the client OpenVPN config file

$ vi config.ovpn

Should contain the following (Replace openvpnserverIP with the real IP address)

client
dev tun
proto tcp
remote openvpn_server_IP 21194
ping-restart 30
remote-cert-tls server
nobind
persist-key
persist-tun
ca ca.crt
cert kalilou.crt
key kalilou.key
tls-auth ta.key 1
cipher BF-CBC
comp-lzo
verb 3
mute 20
daemon
mssfix 1000

You will need to copy safely these files to your client computer (kalilou.crt, kalilou.key, ta.key, ca.crt, config.ovpn )

Let's say I create a folder called kalilou on my client computer in which I have all those files mentioned above. In this directory, I will run sudo openvpn --config client.ovpn

Now I can connect securely to any of my servers behind the OpenVPN server


Tunnelblick for MacOX users (VPN client connections)

For Mac users, as for tips, I am using Tunnelblick for all my VPN client connection. I would then convert this to a Tunnelblick format.

First create this folder

$ mkdir -p kalilou.tblk/Contents/Resources
$ cp kalilou.* ta.key ca.crt config.ovpn 
$ chmod 0700 kalilou.tblk/Contents/Resources/*

Move this folder to Tunnelblick and it will automatically detect at startup

$ cp -r kalilou.tblk ~/Library/Application\ Support/Tunnelblick/Configurations/
$ cp -r kalilou.tblk  /Library/Application\ Support/Tunnelblick/Users/your_user/

You can write a script in which all these are done automatically each time you attempt to create a new VPN client user.

© 2020 Revolight AB