Saturday, January 03, 2015

Linux - How to Set Up OpenVPN Server

So my friend is travelling in a country which has a great firewall :). Facebook, Youtube, Twitter and Gmail are all blocked. He asked me to help. So, I set up a openVPN server for him and what he needs to do is to install openVPN locally on his computer then connect to the openVPN server I set up for him, route all the traffic and he's super happy. I think it is benefical to write down what I did, for my own reference and also, in case someday you need to do the same thing.

So why openVPN can help? OpenVPN allows you to create a virtual private network and allow clients to connect to remote internet resources as if they were under the same LAN. By connecting to VPN server outside of the firewall, my friend can access internet resources through the VPN server, bypass the firewall blocking.

OS: CentOS 6.5
OpenVPN: openvpn-2.3.6
easy-rsa: easy-rsa-2.2.2


In order to install OpenVPN, you need EPEL (Extra Package for Enterprise Linux). EPEL is a Fedora special interest group that creates, maintains and manages a high quality set of addtional package for RedHat, CentOS and Scientific Linux. EPEL repository has more than 8000 packages and it was started by some Fedora contributors mainly for using Fedora packages they maintain on RHEL and it’s derivatives. To install EPEL repo:
1. Download the latest EPEL rpm from ""
2. Install rpm:
# rpm -ivh epel-release-6-8.noarch.rpm
or update:
# rpm -Uvh epel-release-6-8.noarch.rpm
3. Verify:
# yum repolist | grep epel
epel                                                   Extra Packages for Enterprise Linux 6 - x86_64

"easy-rsa" is a small RSA key management package, based on the openssl command line tool. It helps you to build and manage a PKI CA (create root certs, request and signed certs). You can find more information about "easy-rsa" here:

Install openVPN and easy-rsa packages.
# yum -y install openvpn easy-rsa

Configure OpenVPN server:
Now you should have a directory called "/etc/openvpn/" and it is most likely empty. Don't worry, we will add configuration files in a minutes.

Locate the sample server.conf file, you can use "find / -name "server.conf" command to locate, for me, this "server.conf" is located at "/usr/share/doc/openvpn-2.3.6/sample/sample-config-files/", once you located the file, copy it to "/etc/openvpn":
# cp /usr/share/doc/openvpn-2.3.6/sample/sample-config-files/server.conf /etc/openvpn/

Now update the server.conf file:
To enable all clients to redirect their default network gateway through the VPN, causing all IP traffic such as web browsing and DNS lookupds to go through the VPN, you should uncomment:
push "redirect-gateway def1 bypass-dhcp"

Set Google DNS as default DNS server:
push "dhcp-option DNS"
push "dhcp-option DNS"

To enhance security, reduce openVPN daemon's previleges:
user nobody
group nobody

The above are just basic configurations, you can also change log file location, log status, etc.

Generate CA certs and keys:
Prepare folder and files:
Now we need easy-rsa to help us generate and manage certificates and keys. Locate the "easy-rsa" folder. My "easy-rsa" folder is located at "/usr/share/easy-rsa"
Copy files over to "/etc/openvpn"
# mkdir -p /etc/openvpn/easy-rsa/keys
# cp -rf /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa/

Edit file "/etc/openvpn/easy-rsa/vars"
# vi /etc/openvpn/easy-rsa/vars
Go to "export KEY_" part, update the following:
export KEY_COUNTRY="xx"
export KEY_PROVINCE="xx"
export KEY_CITY="xxxx"
export KEY_ORG="xxxx"
export KEY_EMAIL="yoru_email"
export KEY_OU="server"

Then go to "/etc/openvpn/easy-rsa/", initialize the certificate authority:
# cd /etc/openvpn/easy-rsa/
# cp openssl-1.0.0.cnf openssl.cnf
# source ./vars
# ./clean-all

Generate CA certificate and key:
# cd /etc/openvpn/easy-rsa/
# ./build-ca

Sample output:
Generating a 2048 bit RSA private key
writing new private key to 'ca.key'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]: ----> Press Enter
State or Province Name (full name) [XX]: ----> Press Enter
Locality Name (eg, city) [XXXX]: ----> Press Enter
Organization Name (eg, company) [XXXXX]: ----> Press Enter
Organizational Unit Name (eg, section) [server]: ----> Press Enter
Common Name (eg, your name or your server's hostname) [XXXXX]: ----> Press Enter
Name [EasyRSA]: ----> Press Enter
Email Address [XXXXX]: ----> Press Enter

We have now generated the CA certificate and CA key. Then create certificate and key for server using the following command:
./build-key-server server

Copy files into /etc/openvpn/
The necessary keys and certificates will be generated in the /etc/openvpn/easy-rsa/keys/ directory. Copy the following certificate and key files to the /etc/openvpn/ directory.

Now You've created certificate for your server!

To verify your certificate:
# openssl x509 -text -in server.crt

Now move to the client side, we are going to generate certificate and key file for client (client1 is just a name, you can use a username instead):
# cd /etc/openvpn/easy-rsa/
# ./build-key client1

Great, now you have generated certificates and keys for both server and client!

Generate Diffie Hellman Parameter (DH):
DH is a specific method of securely exchanging cryptographic keys over a public channel. It allows two parties to jointly establish a shared secret key over an insecure communication channel. In openVPN, DH is subject to man-in-the-middle attackes, DH does not provide any identities and authentications. In openVPN , you just use DH to generate the session key. For example, DHE-RSA-AES128-SHA1 is a cipher spec that uses DH to generate the key, RSA for authentication, AES-128 for encryption and SHA1 fir digests.

Generate DH parameter:
# cd /etc/openvpn/easy-rsa/
# ./build-dh

Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time

Create OpenVPN configuration file for client:
Again, you can use the sample client file:
# cp /usr/share/doc/openvpn-2.3.6/sample/sample-config-files/client.conf /home/client1
# vim /home/client1/client.conf

You need at least set remote server:
remote VPN_server_IP 1194

and TLS files:
ca path_to_ca.crt
cert path_to_client1.crt
key path_to_client1.key

Copy the following files:

IP forwarding and routing Configuration:
Now we need to enable ip_forward kernel parameter and iptables:

Edit sysctl.conf file:
# vi /etc/sysctl.conf
Find the following line and set value “1” to enable IP forwarding.
# Controls IP packet forwarding
net.ipv4.ip_forward = 1
Then run the following command to apply the changes
# sysctl -p

Adjust iptables to forward traffic through VPN properly:
Enter the following commands:
iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE

Save the iptables changes using command:
# service iptables save
# service iptables restart

Start openVPN server:
# service openvpn start
You should see a tun0 interface in "ifconfig"
# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:  P-t-P:  Mask:
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

On openVPN client:

First of all, install openvpn package:
# yum -y install openvpn

Start openVPN client (Install openVPN if you haven't installed it already):
Make sure client.conf is at /etc/openvpn and certificate file and key are in place.

Now start openvpn client:
# service openvpn start

You should also see a tun0 interface.
# ifconfig
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
inet --> netmask 0xffffffff 

You should be able to ping the VPN server:
# ping -c 1
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=9.61 ms

Now you should be able to use internet resource through VPN server!

No comments: