Tuesday, January 31, 2012

From Zero to OpenVPN in 30 Minutes

Workers today are more mobile than ever, so providing a secure link to your network for remote workers is crucial. Luckily, it’s also free and easy with OpenVPN. I’ll walk you through the process of setting up an OpenVPN server to authenticate and encrypt multiple client connections in just slightly more time than it takes to read this article.
In the olden days, OpenVPN was a typical nerdy free software project focused on good code rather than marketing, with a plain website devoid of glitz. Today it still has good code, but it has spun off several commercial options and boatloads of glitz. The free-of-cost community GPL edition is the beloved OpenVPN of old, but in addition you can install commercial options and add-ons such as the Access Server for Linux, Access Server Virtual Appliances for Linux, Mac, and Windows, Access Server Cloud Machines, and an Internet Private Tunnel service for Mac and Windows clients. Clients on all major platforms sport nice graphical interfaces, and there are several management GUIs, some standalone and some integrated into other products, such as DD-WRT, IPCop, and Zentyal.
We’ll set up the GPL community version on Linux. GUIs and extra services are nice conveniences, but admins should understand what’s happening under the hood, and OpenVPN has never been all that difficult to deploy, even without the glitzy helpers.
To get started, you will need at least two Linux PCs, with OpenVPN installed on each: one for the server and one (or more) for the client. OpenVPN is included in nearly all Linux distributions, so fire up your favorite package manager to install it. Source and binary downloads are also available.

Creating a Public Key Infrastructure

Your first step in setting up OpenVPN is to create a public key infrastructure (PKI). OpenVPN uses mutual authentication – the server and client authenticate to each other, which provides a strong level of security that protects both sides of the connection. Each client and server has a pair of keys – a public key for encrypting communications, and a private key for decrypting. Public keys are meant to be shared, while private keys must be protected and never shared. You’re probably familiar with key pairs from having used them to authenticate in SSH and SSL. To make things easier, we’ll use a certificate authority (CA) to sign clients’ key pairs. Without a CA, the server would need to store a copy of every client certificate. With one, the server holds the CA’s own key pair and a server key pair, and each client has its own key pair. The server doesn’t need to know anything about those client certificates; all it knows is whether the CA signed the client certificates.
In OpenVPN the public key is called a certificate and has a .crt extension. The private key is called a key, with a .key extension.
OpenVPN comes with nice helper scripts to set up this PKI. On my Debian Wheezy system the scripts are in /usr/share/doc/openvpn/examples/easy-rsa/2.0; on your Linux flavor they may be somewhere else. Once you hunt them down, copy the whole directory to /etc/openvpn so that the package manager will not overwrite your changes:
# cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/
On my system this creates /etc/openvpn/2.0. Change to your copied directory, then find a file named vars and edit the last section so that it contains your correct location, email address, and other identifying information. Feel free to examine the other options and change them if you wish, though everything should work fine with the defaults. Here’s how mine looks:
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_CITY="LittleBigtown"
export KEY_ORG="Tuxcomputing"
export KEY_EMAIL="carla@bratgrrl.com"
export KEY_EMAIL=carla@bratgrrl.com
export KEY_CN=test-system
export KEY_NAME=test-system-key
export KEY_OU=test-system
export PKCS11_MODULE_PATH=changeme
export PKCS11_PIN=1234
Now run the following commands:
#. ./vars
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) [OR]:
Locality Name (eg, city) [LittleBigtown]:
Organization Name (eg, company) [Tuxcomputing]:
Organizational Unit Name (eg, section) [test-system]:
Common Name (eg, your name or your server's hostname) [test-system]:
Name [test-system-key]:
Email Address [carla@bratgrrl.com]:
Look in the keys/ subdirectory to see your new root CA certificate and root CA key, ca.crt and ca.key. ca.crt is publicly readable, while ca.key must never be shared. Now build the server’s private key pair, specifying whatever name you want to use for your system. Every time you create a server key it must have a unique name to identify the system it is created for:
# ./build-key-server test-system
This process is similar to creating the CA. When it offers the option to create a challenge password, say no. Say yes to these questions:
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Now your server certificate is properly signed by your CA. Every client will get a copy of ca.crt, and thus be able to verify that they are connecting to the correct server.

Client Certificates

Next, you must create client certificates with the build-key or build-key-pass scripts. Use the first to create a password-less certificate, and the second to require your users to enter a password when they connect to the VPN. A password might be a wise precaution for mobile users. Use these commands just like the build-key-server script, with a unique name for each client:
# ./build-key lucy
# ./build-key ricky
# ./build-key-pass ethel
# ./build-key fred
One more chore is generating the Diffie-Hellman parameters. What, you and I and all normal humans ask, the heck are those? Diffie-Hellman is the protocol that allows two users to exchange a secret key over an insecure medium without any prior secrets, which is pretty cool, I think. Back at the OpenVPN server, run this command:
# ./build-dh
All you have to do is wait for it to finish; it creates a file called 01.pem.
All of your new keys and certificates are in plain text, so you can read them if you forget what they’re for. Now copy to each client the file ca.crt, plus the appropriate client certificates and keys.

Server Configuration

The next step is to create the server and client configuration files. Look in your installation’s openvpn/examples/ directory for configuration file examples. They are well-commented and easy to follow. Listed below is a complete example server configuration, /etc/openvpn/server.conf. The commented options take variables specific to your setup. Read the example file to learn about the other options:
port 1194
proto udp
dev tun

# the full paths to your server keys and certs
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/test-system.crt
key /etc/openvpn/keys/test-system.key
dh /etc/openvpn/keys/01.pem

cipher BF-CBC

# Set server mode, and define a virtual pool of IP
# addresses for clients to use. Use any subnet
# that does not collide with your existing subnets.
# In this example, the server can be pinged at

# Set up route(s) to subnet(s) behind
# OpenVPN server
push "route"
push "route"

ifconfig-pool-persist /etc/openvpn/ipp.txt
keepalive 10 120
status openvpn-status.log
verb 6

Client Configuration

Once you have the server set up, create a similar configuration file on your test client, /etc/openvpn/client.conf:
dev tun
proto udp

# enter the server's hostname
# or IP address here, and port number
remote test-system 1194

resolv-retry infinite

# Use the full filepaths to your
# certificates and keys
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/lucy.crt
key /etc/openvpn/keys/lucy.key

ns-cert-type server
verb 6

Connecting to the Server

Now everything should be properly configured. Start OpenVPN on both the server and client from the command line on each system by referencing the configuration file – for example, openvpn /etc/openvpn/server.conf. You’ll see all kinds of startup messages. When it’s finished, you should be able to ping the server’s virtual address from the client, which is in the example server configuration file. When your client and server can ping back and forth, you have a good stout encrypted OpenVPN tunnel.
Congratulations – you just got OpenVPN up and running. Now you get to figure out how to route your OpenVPN clients through your firewall to your server, how to set up your server to start automatically at boot time, and how to configure the clients to manage starting and stopping an OpenVPN session. To help with some of that, a good OpenVPN plugin for NetworkManager called network-manager-openvpn makes managing Linux OpenVPN clients as easy as any other network login. Visit OpenVPN.net for help, more graphical client and server administration tools, and to learn more about OpenVPN and what it can do.

No comments:

Post a Comment