Having a virtual private network affords a lot of convenience, particularly for those who want or need to access a remote network from a different location, such as connecting to a work network from home, or vice versa. With the availability of 3G on the road, or wireless hotspots everywhere, being able to connect, securely, to a remote private network from anywhere is ideal.

OpenVPN is one of the most reliable VPN setups around. It’s fully open source, it’s supported on Linux, Windows, and OS X, it’s robust, and it’s secure. Unfortunately, configuration can be a bit of a pain, so in a series of upcoming tips, I aim to get you up and running quickly.

To begin, you will need to have OpenVPN installed on the server or system you wish to use as a VPN end-point. Most distributions include OpenVPN; for the server setup, I am using OpenVPN 2.0.9 as provided by the RPMForge repository for CentOS 5.

The first part of this series concentrates on the server, while the second and third parts will concentrate on the configuration of Linux and OS X clients, respectively. So without further ado, let’s get our hands dirty.

To begin with, you need to copy some files from the OpenVPN docs directory (typically provided in /usr/share/doc/openvpn-[version]) to create certificates:

# cd /usr/share/doc/openvpn-2.0.9
# cp -av easy-rsa /etc/openvpn/
# cd /etc/openvpn/easy-rsa/
# vim vars

In the vars file, edit the KEY_* entries at the bottom of the file, such as KEY_COUNTRY, KEY_ORG, KEY_EMAIL, etc. These will be used to build the OpenSSL certificates. Next, it’s time to initialize the PKI:

# . ./vars
# sh clean-all
# sh build-ca
# sh build-key-server server

For the above, and the below client certificates, you can enter pretty much anything for the “Common Name” field, however there is a certain logic to use: “OpenVPN-CA” when generating the Certificate Authority, “server” when generating the server certificate, and “client” or the name of the specific client system for the client certificates. Those certificates are generated with:

# sh build-key client1
# sh build-key client2

The next step is to generate the Diffie Hellman parameters for the server:

# sh build-dh

When this is done, you will have a number of files in the keys/ subdirectory. At this point, for the clients, you want to copy the appropriate files to them securely (i.e., via SSH or on a USB stick); the files the clients need are ca.crt, client1.crt, and client1.key (or whatever you named the files when you generated them with the build-key script).

Next, create the OpenVPN server configuration file. To get up and running quickly, copy one of the example config files:

# cd /etc/openvpn/
# cp /usr/share/doc/openvpn-2.0.9/sample-config-files/server.conf .
# vim server.conf

The aim here is to get this going right away, so we won’t examine each of the options in detail. The primary things you want to do are to uncomment the “user” and “group” directives, to make the openvpn process run as the unprivileged “nobody” user. You may also want to change the “local” directive to make it listen to one specific IP address. This would be the IP to which your firewall is forwarding UDP port 1194. As well, you will want to set the “client-to-client” directive to enable it, and also set the “push” directives for route and DNS options. What follows is a comment-stripped server.conf, as an example:

port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key  # This file should be kept secret
dh dh1024.pem
ifconfig-pool-persist ipp.txt
push "route"
push "dhcp-option DNS"
push "dhcp-option DOMAIN domain.com"
keepalive 10 120
user nobody
group nobody
status openvpn-status.log
verb 3

Finally, copy the required keys and certificates that you previously generated:

# cd  /etc/openvpn/
# cp easy-rsa/keys/ca.crt .
# cp easy-rsa/keys/server.{key,crt} .
# cp easy-rsa/keys/dh1024.pem  .

And, finally, start the OpenVPN server:

# /etc/init.d/openvpn start

To get routing set up properly on the server so that remote clients, when they connect, can reach more than just the server itself, you will need to enable IP forwarding. This can be done by the following:

# echo 1 > /proc/sys/net/ipv4/ip_forward

You can also do it by editing /etc/sysctl.conf and adding the following (this is a good thing to do as it will ensure that packet-forwarding persists across reboots):

net.ipv4.ip_forward = 1

You also want to ensure that packets going back to the client system are routed properly. This can be done by changing the route on the gateway of the server’s network to route packets to the client network ( through the OpenVPN server (if the server happens to be the gateway as well, you don’t have to do anything additional to accomplish this). How this is done largely depends on the operating system of the gateway.

Once this is done, you should be able to ping any machine on the server’s LAN from the client, and be able to ping the client from any machine on the server’s LAN. For instance, from a machine on the server LAN (not the server):

% traceroute
traceroute to (, 64 hops max, 52 byte packets
 1  fw (  0.848 ms  0.342 ms  0.249 ms
 2  server (  0.214 ms  0.231 ms  0.243 ms
 3  server (  0.199 ms !Z  0.443 ms !Z  0.396 ms !Z
% ping
PING ( 56 data bytes
64 bytes from icmp_seq=0 ttl=63 time=17.540 ms

And from the client:

# traceroute
traceroute to (, 30 hops max, 40 byte packets
 1 (  22.963 ms  27.311 ms  27.317 ms
 2 (  27.297 ms !X  27.294 ms !X  27.269 ms !X
# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=62 time=515 ms

The setting up of OpenVPN clients will be the subject of two tips in the next week. I’ve made the assumption that the client is correctly configured here, simply to illustrate how it should look when it all works together, but in the next parts of this series we will get into more depth with the client configuration.

Download the PDF, “How to set up OpenVPN server and create Linux and Mac OS X clients.