You want to run OpenVPN as securely as possible, so you're ready to set up a proper Public Key Infrastructure.
This isn't hard at all, and is many times more secure than using static keys. Follow these steps:
Create your own Certificate Authority (CA) certificate.
Create an OpenVPN server certificate.
Generate client certificates.
OpenVPN comes with a batch of scripts that make this easy. First, find the easy-rsa/2.0 directory, and copy it to /etc/openvpn:
# cp /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa/2.0
Change to the 2.0 directory:
# cd /etc/openvpn/easy-rsa/2.0
Open the vars file, and assign your own
values to these lines. Don't leave any blank. Use NA
if you don't want to assign your own
value:
export KEY_SIZE=2048 export KEY_COUNTRY=US export KEY_PROVINCE=NA export KEY_CITY=Linuxville export KEY_ORG="Alrac.net-test" export KEY_EMAIL="carla@alrac.net"
Then, run these commands just as they are shown, and follow
their prompts. After the leading dot in ../vars
there is a space.
# . ./vars
# ./clean-all
# ./build-ca
When it asks you for a Common Name, use something descriptive, like vpn-ca. Then, run this command to create the server certificate, naming it with your own server name:
# ./build-key-server xena
Use the fully qualified domain name, like xena.alrac.net, for the Common Name. Answer yes to "Sign the certificate? [y/n]" and "1 out of 1 certificate requests certified, commit? [y/n]."
Next, create unique keys for all of your clients. This example generates a passphraseless key pair for the laptop named Stinkpad:
# ./build-key stinkpad
Or, you may wish to password-protect the client key. Use this command instead:
# ./build-key-pass stinkpad
The user will be asked for the password every time they initiate a connection. Use the hostname for the Common Name. Now, generate the Diffie-Hellman parameters:
# ./build-dh
Finally, create a TLS-AUTH key. The server and all clients need a copy of this key:
# cd keys/
# openvpn --genkey --secret ta.key
You should now have something like this in your keys directory:
01.pem 02.pem ca.crt ca.key dh2048.pem index.txt index.txt.attr index.txt.attr.old index.txt.old serial serial.old stinkpad.crt stinkpad.csr stinkpad.key ta.key xena.crt xena.csr xena.key
For your own sanity, keep your certificate-creation directory separate. It can even be on a separate PC. Create a new keys directory, and move your new server keys and certificates into it. These commands are all run from /etc/openvpn/easy-rsa/2.0:
# mkdir -m 0700 /etc/openvpn/keys
# cp ca.crt ../../keys
# mv dh2048.pem ta.key xena.crt xena.key ../../keys
stinkpad.key, stinkpad.crt, and copies of ta.key and ca.crt must be moved to the appropriate directory on Stinkpad. You must create a unique key pair for each additional client.
See the next recipe to learn how to configure your server and clients to use your nice new PKI.
You can read your X509 certificates with this command:
$ openssl x509 -in [certificate name] -text
Anything ending in .key is a private key, which must be carefully protected and never shared. .crt is a public certificate, and can be shared. ca.key is your private root certificate authority key.
The most paranoid way is to do all this on a PC that is never connected to any network, and use USB flash devices or directly connected crossover cables to transfer them to their appropriate hosts. Secure copy over your LAN works, too, assuming you have SSH set up on your systems:
# scp stinkpad.crt stinkpad:/etc/openvpn/keys/
Generating a certificate/key pair for every client is a bit of work, but that's the magic bit that makes your OpenVPN tunnel secure. If you've ever created key pairs from scratch using OpenSSL instead of OpenVPN's excellent scripts, you will appreciate how much the OpenVPN developers have streamlined the process.
Consider requiring password-protected client certificates on all laptops. Any client PCs outside of the office are at risk for theft and misuse, especially laptops.
Use the Common Name to create a unique name for each key pair. I like to use the convention of vpnserver and vpnclient because they are different types of keys, which you can see by reading the build-key scripts. Using the hostname as the key name is a quick way to see what belongs where. It's easy to get confused when you're rolling out a batch of these; smart naming will keep you on track.
The Diffie-Hellman parameter is the encryption mechanism that allows two hosts to create and share a secret key. Once the OpenVPN client and server authenticate to each other, additional send and receive keys are generated to encrypt the session.
See Charlie Hosner's excellent paper, "OpenVPN and the SSL Revolution," for more details on how this works: http://www.sans.org/reading_room/whitepapers/vpns/1459.php?portal=c7da694586dcdad815fd41098461e495
man 8 openvpn
OpenVPN How-to: http://openvpn.net/howto.html