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 * [Windows-only Management Interface in .NET 2.0](http://www.mertech.com.au/default.aspx) * [TunTun, a GUI applet for Gnome](http://code.google.com/p/tuntun/) ### Presentations * [OpenVPN Presentation by Adrian Bridgett](http://www.archive.org/details/HantsLUG_openvpn) * [Presentation by James Yonan](http://openvpn.net/papers/BLUG-talk/2.html) ### Other * [OpenVPN Open Source information page](http://openvpn.net/index.php/open-source.html) * [OpenVPN MiniFAQ](http://workaround.org/openvpn-faq) ### Building the OpenVPN RPM yourself Download the tarball from [OpenVPN's Community Downloads page](http://openvpn.net/index.php/open-source/downloads.html). 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](http://blog.famillecollet.com/en). 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: ```bash 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. * [Very basic rules](http://serverfault.com/questions/39307/linux-ip-forwarding-for-openvpn-correct-firewall-setup) * [A more complicated setup](http://blogs.encodo.ch/news/view_article.php?id=196)