OpenVPN Installation

[TOC]

Latest version of OpenVPN is v2.1.1. Installing this on an i386 CentOS
5.5 box (vpn.example.com)

Step 1: Install OpenVPN

yum info openvpn

This shows version 2.1.1, so we’ll go ahead an install it.

yum install openvpn

Step 2: Set up certificate params

Navigate to /etc/openvpn/easy-rsa/2.0. This folder contains a bunch of
scripts to make certificate and access management very easy. You will
edit the vars file. Here are the pertinent changes I’ve made:

# Why not keep all keys in one place?  
export KEY_DIR="/etc/pki/tls/openvpn"  
    
# Changed this to one year from ten years  
export KEY_EXPIRE=365  
  
# Organizational Unit Name will be asked during certificate generation  
export KEY_COUNTRY="US"  
export KEY_PROVINCE="IA"  
export KEY_CITY="Iowa City"  
export KEY_ORG="The University of Iowa"  
export KEY_EMAIL="support@vpn.example.com"

Step 3: Make yourself a Certificate Authority (CA)

You’ll need this step to sign server and client certificate signing
requests (CSR’s). Here’s a transcript of what I did (still at
/etc/openvpn/easy-rsa/2.0):

[root@bouncer 2.0]# source ./vars   
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/pki/tls/openvpn  
[root@bouncer 2.0]# ./clean-all   
[root@bouncer 2.0]# ./build-ca   
Generating a 1024 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) [US]:  
State or Province Name (full name) [IA]:  
Locality Name (eg, city) [Iowa City]:  
Organization Name (eg, company) [The University of Iowa]:  
Organizational Unit Name (eg, section) []:The Center for Bioinformatics and Computational Biology
Common Name (eg, your name or your server's hostname) [The University of Iowa CA]:vpn.example.com
Name []:            
Email Address [support@vpn.example.com]:

As you can see, I mostly hit return for most values since I pre-defined
them in vars

Step 4: Create a server certificate

For this, you’ll simply execute build-key-server. Here’s a transcript:

[root@bouncer 2.0]# ./build-key-server vpn.example.com  
Generating a 1024 bit RSA private key  
.............................++++++  
...++++++  
writing new private key to 'vpn.example.com.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) [US]:  
State or Province Name (full name) [IA]:  
Locality Name (eg, city) [Iowa City]:  
Organization Name (eg, company) [The University of Iowa]:  
Organizational Unit Name (eg, section) []:The Center for Bioinformatics and Computational Biology  
Common Name (eg, your name or your server's hostname) [vpn.example.com]:  
Name []:  
Email Address [support@vpn.example.com]:  
  
Please enter the following 'extra' attributes  
to be sent with your certificate request  
A challenge password []:  
An optional company name []:  
Using configuration from /etc/openvpn/easy-rsa/2.0/openssl.cnf  
Check that the request matches the signature  
Signature ok  
The Subject's Distinguished Name is as follows  
countryName           : 'US'  
stateOrProvinceName   : 'IA'  
localityName          : 'Iowa City'  
organizationName      : 'The University of Iowa'  
organizationalUnitName: 'The Center for Bioinformatics and Computational Biology'  
commonName            : 'vpn.example.com'  
emailAddress          : 'support@vpn.example.com'  
Certificate is to be certified until Jun 12 15:15:45 2020 GMT (3650 days)  
Sign the certificate? [y/n]:y  
  
1 out of 1 certificate requests certified, commit? [y/n]y  
Write out database with 1 new entries  
Data Base Updated

Step 5: Create one or more client certificates

Run build-key for each client. For instance, I’m going to generate a
certificate for myself (user ID nanand):

[root@bouncer 2.0]# source ./vars  
[root@bouncer 2.0]# ./build-key nanand  
Generating a 1024 bit RSA private key  
....++++++  
......++++++  
writing new private key to 'nanand.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) [US]:  
State or Province Name (full name) [IA]:  
Locality Name (eg, city) [Iowa City]:  
Organization Name (eg, company) [The University of Iowa]:  
Organizational Unit Name (eg, section) []:The Center for Bioinformatics and Computational Biology
Common Name (eg, your name or your server's hostname) [nanand]:  
Name []:Nikhil Anand**  
Email Address [support@vpn.example.com]:nanand@vpn.example.com**  
  
Please enter the following 'extra' attributes  
to be sent with your certificate request  
A challenge password []:  
An optional company name []:  
Using configuration from /etc/openvpn/easy-rsa/2.0/openssl.cnf  
Check that the request matches the signature  
Signature ok  
The Subject's Distinguished Name is as follows  
countryName           : 'US'  
stateOrProvinceName   : 'IA'  
localityName          : 'Iowa City'  
organizationName      : 'The University of Iowa'  
organizationalUnitName: 'The Center for Bioinformatics and Computational Biology'  
commonName            : 'vpn.example.com'  
name                  : 'Nikhil Anand'  
emailAddress          : 'nanand@vpn.example.com'  
Certificate is to be certified until Jun 12 15:22:26 2020 GMT (3650 days)  
Sign the certificate? [y/n]:y
  
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries  
Data Base Updated

It’s bloody important to just hit Enter when you’re asked the
Common Name (CN) for the client certificate! The OpenVPN server assigns
client IPs based on the CN in the client certificate. If you set the CN
of the clients the same as that of the server, each client will get
the same IP.

Step 6: Configure the server

Copy /etc/openvpn/sample-config-files/server.conf to its top-level
directory, /etc/openvpn

cp /etc/openvpn/sample-config-files/server.conf /etc/openvpn/

Edit the file to configure your server. Here are the pertinent lines I
changed:

ca /etc/pki/tls/openvpn/ca.crt  
cert /etc/pki/tls/openvpn/vpn.example.com.crt  
key /etc/pki/tls/openvpn/vpn.example.com.key  
dh /etc/pki/tls/openvpn/dh1024.pem  
  
server 10.34.2.0 255.255.255.0  
  
push "dhcp-option DNS 19.67.17.20"  
push "dhcp-option DNS 19.67.17.21"  
push "dhcp-option DOMAIN vpn.example.com"  
  
max-clients 50

Step 7: Enable the Management Interface

This provides you a realtime ‘view’ of connected users (in quotes since
it’s all textual.) You can also kill user sessions. To enable this, you
need a line in /etc/openvpn/server.conf.

#management (IP address) (port number) (text file for management password)
management 127.0.0.1 7896 management-password.txt

Make sure that the management password file is readable only by a
superuser!

Using the interface

Simple. Telnet. Here’s a transcript that shows me using the interface to
figure out who’s connected using the status command:

[root@example ~]# telnet 127.0.0.1 7896  
Trying 127.0.0.1...  
Connected to localhost.localdomain (127.0.0.1).  
Escape character is '^]'.  
ENTER PASSWORD:***********  
SUCCESS: password is correct  
>INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info  
status**  
OpenVPN CLIENT LIST  
Updated,Tue Nov 30 05:18:54 2010  
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since  
nikhil,173.27.1.155:58008,37145,35061,Tue Nov 30 05:17:54 2010  
ROUTING TABLE  
Virtual Address,Common Name,Real Address,Last Ref  
10.34.0.6,nikhil,173.27.1.155:58008,Tue Nov 30 05:18:54 2010  
GLOBAL STATS  
Max bcast/mcast queue length,0  
END  
quit  
Connection closed by foreign host.

Start the Server

service openvpn start

Resources

Differences between tun and tap

Now the mechanism by which OpenVPN connects /dev/tun on computer A with
/dev/tun on computer B is this: It simply creates an encrypted UDP
connection over the internet between A and B and forwards traffic
between /dev/tun on A with /dev/tun on B. Because of the clever way in
which the tun and tap drivers were designed, it is possible for a
program running entirely in user-space to effect this link, allowing
OpenVPN to be a portable cross-platform daemon (like SSH), rather than
an OS-specific kernel module (like IPSec).

The difference between a tun and tap device is this: a tun device is a
virtual IP point-to-point device and a tap device is a virtual ethernet
device. So getting back to the “long cable” analogy, using a tun device
would be like having a T1 cable connecting the computers and using a tap
device would be like having an ethernet network connecting the two
computers

Clients

Presentations

Other

Building the OpenVPN RPM yourself

Download the tarball from OpenVPN’s Community Downloads
page
.

wget http://openvpn.net/release/openvpn-2.1.1.tar.gz

You can now use rpmbuild to create a nice RPM for future deployment.
But it does have some dependencies:

yum install gcc glibc-devel openssl openssl-devel lzo-devel pam-devel pkcs11-helper-devel

Note: lzo-devel and pkcs11-helper-devel might not be available
on a stock system. I like EPEL and RPM’s by Remi.
The yum command will work flawlessly if you install these repos.

wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
wget http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
rpm -Uvh remi-release-5*.rpm epel-release-5*.rpm

You should now be ready to build the RPM.

rpmbuild -tb openvpn-2.1.1.tar.gz

The finished RPM will be located in:

/usr/src/redhat/RPMS/i386/openvpn-2.1.1-1.i386.rpm

You could store this someplace else if you wanted to install it on other
32-bit systems.

Firewall Stuff & Typical Problems

Make sure that this is set to 1 in /etc/sysctl.conf

net.ipv4.ip_forward = 1

For immediate effect,

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

Here are some basic, highly liberal rules:

iptables -A INPUT -i tun+ -m state --state NEW -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i tun+ -m state --state NEW -j ACCEPT iptables -A
POSTROUTING -s 192.168.0.0/16 -t nat -j MASQUERADE iptables -A
POSTROUTING -s 172.16.0.0/12 -t nat -j MASQUERADE iptables -A
POSTROUTING -s 10.0.0.0/8 -t nat -j MASQUERADE

If you use puppet to manage sysctl.conf (like I do), you can edit
/etc/init.d/openvpn and uncomment the line that enables IP forwarding
immediately.