OpenVPN – Introduction and Installation on CentOS

What is OpenVPN

Just from the name “VPN” means “Virtual Private Network” and “Open” refers to the Open Source Software status of the OpenVPN application.  This is the first of a series of articles about OpenVPN.  We will look at a number of potential use scenarios in the rest of this series.

For starters we will use OpenVPN on a CentOS Linux server. As the series unfolds, it will hopefully become clearer what the OpenVPN can be used for.  This document assumes that you are logged on as the “root” super-user.

Installation on CentOS

OpenVPN is available as an RPM package.  So we can first check if it has been installed

# rpm -q openvpn
package openVPN is not installed

OK, so we try

# yum install openvpn
no package openvpn available

Oops .. now what.  OpenVPN does not come as a pre-compiled binary for CentOS.  However the DAG repository at RPMForge hosts several pre-compiled versions.

Preparing things ..

I have tried the following on a number of CentOS installations.  Credit to to point the way on some of those steps.

  • Get the required development packages ..
# yum install gcc make rpm-build autoconf.noarch zlib-devel pam-devel openssl-devel -y
  • Install LZO RPM and configure the RPMForge Repo​
# wget
# rpmbuild --rebuild lzo-1.08-4.rf.src.rpm
# rpm -Uvh lzo-*.rpm
  • Get and install the module for the correct OS

CentOS 5 – 32 bit

# wget

CentOS 6 – 32 bit

# wget

CentOS 5 – 64 bit

# wget

CentOS 6 – 64 bit

# wget
  • Install the OS Specific module
# rpm -Uvh rpmforge-release*

Go for it ..

# yum install -y openvpn

This should complete successfully.

You check by executing

# service openvpn status
openvpn: service not started
# service openvpn start
Starting openvpn:                                          [  OK  ]
# service openvpn stop
Shutting down openvpn:                                     [  OK  ]

After everything checks out, remove the RPMForge repository to protect the integrity of updates.

# yum remove rpmforge-release

Creating a Simple Tunnel

There are many reasons we may want to establish a private tunnel between two machines.  Let’s say for example that, although both boxes have a public IP address, we restrict access on those addresses to a limited number of ports.  An example might clarify things.

Configuration files

When we start the openvpn service,  the system looks in the /etc/openvpn directory for files with a .conf extension.  We can place directives in these files to create VPN tunnels.  The creation of a VPN tunnel implies the creation of a tunnel interface at each box.  We will give these tunnel interface (virtual) adapters a private IP address.

VPN Simple Tunnel

Computer A 

Public IP: aaa.bbb.78.150
Tunnel IP:

Computer B
Public IP: xxx.yyy.174.240
Tunnel IP:

In this example, the configuration files on both boxes look similar.

Computer A (at aaa.bbb.78.150)

 ## server13.conf
 remote xxx.yyy.174.240
 dev tun13
 proto udp
 port 61002
 keepalive 10 60

Computer B (at xxx.yyy.174.240)

 ## server31.conf
 remote aaa.bbb.78.150
 dev tun31
 proto udp
 port 61002
 keepalive 10 60

OpenVPN Configuration Files Explained ..

## server13.conf | Comment line .. this is computer A
remote xxx.yyy.174.240  | the endpoint for this tunnel will be at public IP xxx.yyy.174.240
dev tun13 | the device type/name (tunnel name) will be “tun13”
proto udp | and the actual tunneled traffic will be sent using UDP protocol
port 61002 | on port 61002
ifconfig | tunnel endpoints: (local) (remote)
keepalive 10 60 | pings every 10 sec .. if no reply after 60 sec .. assumes connection down
daemon | keep running as a background daemon (service)

As can be seen the two files (computer A/B) are very similar.  After executing # service openvpn start on Computer A, # ifconfig reports the tunnel interface.

# ifconfig
tun13 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:80671 errors:0 dropped:0 overruns:0 frame:0
 TX packets:79927 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:100
 RX bytes:14782745 (14.0 MiB) TX bytes:15154750 (14.4 MiB)

But when we try to ping (the other end) .. we get the expected result ..

[root@computerA ~]# ping
PING ( 56(84) bytes of data.

In other words .. nothing :(.

Now we log in to computer B and start the OpenVPN service .. and ping again ..

[root@computerA ~]# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=109 ttl=64 time=0.609 ms
64 bytes from icmp_seq=110 ttl=64 time=0.466 ms
64 bytes from icmp_seq=111 ttl=64 time=0.442 ms

And success :).

Final Comments

The OpenVPN application is very powerful, and in this article we barely scratched the surface.  It is worth noting that the tunnel IP addresses do get treated as incoming, and the adapter as a “real” adapter. In the illustration about tunneling, this is something we have implemented in our practice.  Typically, there are very limiting firewall rules in place on the public interfaces (using iptables).  So, in our case we added a firewall rule to allow ALL traffic from the subnet, and we did this on both boxes (linux servers).

Also, the hardest part .. as an OpenVPN novice .. is to get the OpenVPN package installed.  It *is* a bit tricky, and the recipe we illustrated above is somewhat simpler than what it used to be (don’t ask 🙁 ).

In our sample illustration, the traffic that gets sent over the tunnel is in clear-text, but it does not have to be like that.  We will talk about securing the data stream, and illustrate some different use scenarios in future posts.

Finally, here are some good Internet resources if this article inspires you to dig deeper.

OpenVPN Official Website

OpenVPN Man Pages

Enjoy ..