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.
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.
Let's walk through the public certificates and private keys.
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.
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
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)
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
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.