Scalable Public Key Infrastructure for both OpenSWAN and OpenVPN
Posted by ElizabethBevilacqua on Thu 15 Nov 2007 at 14:26
User management and the related cryptographic authentication infrastructure is a major hurdle in deploying scalable, manageable VPNs (Virtual Private Networks). After introducing VPNs and Public Key Infrastructure (PKI) and discussing some of the benefits and challenges of two popular VPN implementations, we'll document how to build a scalable PKI to simplify VPN authentication management.
Two major pieces of FOSS (Free and Open Source Software) for VPNs are OpenSWAN and OpenVPN. Generally speaking, OpenSWAN is lighter weight, faster, and largely interoperable with other IPSec (IP Security) implementations. For example, if you need to connect to a Cisco or a Linksys, OpenSWAN is recommended. OpenVPN, on the other hand, provides free client software for Linux, Windows and Mac OS, better server-side management of the client-side network configuration (e.g., when they are non-technical users and need some networking tweaks), you can change the port to bypass non-standard firewall configurations, and even change the MTU (Maximum Transmission Unit) easily in case an intermediate gateway is acting funny.
Frequently it is necessary to support both implementations on a VPN server because of the advantages that each confers. But then one can quickly get an unscalable nightmare with a PKI per software and per client. This article will document a simple, single PKI infrastructure to manage all your users and their VPN connections with support for both OpenSWAN and OpenVPN.
An Introduction to VPNs and a Public Key Infrastructure
A VPN provides a cryptographically protected "private" network layered over IP (Internet Protocol). In a VPN, the server provides authentication and access to the VPN and a client is a system or network requesting access to the VPN. Both OpenSWAN and OpenVPN can use X.509 certificates to manage authentication. X.509 is a standard that defines cryptographic certificates which are "trusted" based on preconfiguration with a hierarchical chain of certificate authorities (CAs) known as a Public Key Infrastructure or PKI. Building an X.509 PKI is the only way we have found to manage an integrated, scalable client/user authentication database for both OpenSWAN and OpenVPN.
A PKI has a Certificate Authority (CA) at its root. This is a public/private cryptographic key pair whose signatures can be "trusted" (by configuring software to "trust" the CA's public key). Once the CA is "trusted", certificates (public/private key pairs) signed by it for each server and each client need to be generated. Server certificates are similar to the client's except they have the extra attribute 'Netscape Cert Type' set to 'SSL Server' to allow an additional sanity check. Once these certificates are signed, the clients and servers only need to exchange their public keys to establish their identity to each other (note: the signature of the CA can be checked by each side, enabling two way trust). If a certificate is ever compromised, it can be revoked and this information made available to the VPN servers and clients in the form of a Certificate Revocation List (CRL). In this way the CA controls authentication.
OpenSWAN is a VPN implementation based on the industry standard IPSec protocol (RFC 2401). In Debian Etch, it uses the in-kernel IPSec implementation, and the userspace tools are just frontends to the kernel. Due to kernel-level support, IPSec is very, very fast. For most workloads, you shouldn't notice a difference between IPSec protected traffic and normal unencrypted traffic. We have successfully set up VPNs between OpenSWAN and routers of various makes (Cisco, Linksys, Netgear) and with Windows and MacOS X clients using a variety of third party software. OpenSWAN implements most of the IPSec draft extensions such as NAT-T (detecting that a peer is behind a NAT (Network Address Translation) firewall and acting appropriately), X.509 based authentication, Dead Peer Detection (dropping disconnected clients) and many others.
OpenSWAN also implements several other nice features such as MTU control, changing the source address of the connection (so that a multihomed host can use the correct IP when sending traffic over a tunnel which is useful on a gateway), and many others. However, it is not always trivial to make IPSec interoperability actually work. Vendors are free to implement various subsets of the extensions, and there are many parts of the RFCs that are 'may's or 'might's that are not universally implemented. Not all clients support the IPSec extensions that OpenSWAN does. Moreover, OpenSWAN uses a highly baroque configuration syntax, some features are poorly documented, and it sports cryptic error and debug messages (in debugging something simple like client authentication, you typically have to wade through hundreds of lines of messages largely devoted to OpenSWAN internals).
OpenVPN is an SSL-based VPN, that, unlike OpenSWAN, is entirely userspace. If you want to connect to an OpenVPN server, you must be running an OpenVPN client (no interoperability here). Being in user space also means some additional workload over an in kernel implementation, but the decision to create a new VPN communication protocol has given the OpenVPN developers the freedom to add an extraordinarily rich feature set. For just about every internetworking need we have faced, there has been an OpenVPN option to address the problem.
OpenVPN is highly configurable and well-documented (including a 3300 line manpage). Obviously, that's a wider feature set than we can cover here. Some of the very nice things that openvpn can do trivially that would be difficult to configure for OpenSWAN are:
- Giving the client an address on the local subnet using a software bridge
- changing the client's default route to go through the VPN server
- Adding additional static routes to the client
- PAM (Pluggable Authentication Module) based password authentication.
The main disadvantage of OpenVPN is interoperability. You will not be able to connect an OpenVPN server and a Netgear client. However, OpenVPN provides binaries for most OS's that you would need on the client side (Windows of various ages, MacOS X), so if you can use OpenVPN as a server, most roaming users will be able to connect.
Another disadvantage is speed. OpenVPN works by creating a tun/tap device and listening on it. All VPN traffic traffic goes kernel -> application -> kernel, so it is much more expensive than an in kernel implementation. But, similar tun/tap applications are capable of 50MB/s which exceeds the capacity of most WAN (Wide Area Networking) links. An underpowered system may experience an excessively high load. Otherwise, performance is not likely to be much of an issue (modestly higher latency could affect some applications).
So, to begin, make sure you have both pieces of software installed (apt-get install openvpn openswan). openswan setup tries to be very helpful and gives you a default config file and a default rsa key. You can safely remove both ipsec.conf and ipsec.secrets now, as we'll be recreating them momentarily. The method we use is wrapped around the pkitool script that comes with openvpn, namely, /usr/share/doc/openvpn/examples/easy-rsa/2.0/pkitool.
$ mkdir -p /etc/pki/keys $ cp /usr/share/doc/openvpn/examples/easy-rsa/2.0/vars /etc/pki/
Create a file named /etc/pki/vars and fill in your information like this:
export EASY_RSA="/etc/pki/" export OPENSSL="openssl" export PKCS11TOOL="pkcs11-tool" export GREP="grep" export KEY_CONFIG="$EASY_RSA/openssl.cnf" export KEY_DIR="$EASY_RSA/keys" export KEY_SIZE=1024 export CA_EXPIRE=3650 export KEY_EXPIRE=3650 export KEY_COUNTRY="US" export KEY_PROVINCE="PA" export KEY_CITY="Philadelphia" export KEY_ORG="My company" export KEY_EMAIL="firstname.lastname@example.org"
$ . /etc/pki/vars $ /usr/share/doc/openvpn/examples/easy-rsa/2.0/clean-all $ /usr/share/doc/openvpn/examples/easy-rsa/2.0/build-dh $ /usr/share/doc/openvpn/examples/easy-rsa/2.0/pkitool --pass --initca
(put this password somewhere safe - you'll need it for future keys)
$ /usr/sbin/openvpn --genkey --secret ta.key $ /usr/share/doc/openvpn/examples/easy-rsa/2.0/pkitool --pass --server my.server
the password for this one is PASSWORD, more below.
$ cp /etc/pki/keys/ca.crt /etc/ipsec.d/cacerts $ cp /etc/pki/keys/my.server.key /etc/ipsec.d/private $ cp /etc/pki/keys/my.server.crt /etc/ipsec.d/certs $ echo 'PASSWORD' > /etc/openvpn/my.server.password $ chmod 0600 /etc/openvpn/my.server.password
Now that we've done this, both OpenSWAN and OpenVPN use a single PKI, and adding new clients is as easy as:
$ . /etc/pki/vars $ /usr/share/doc/openvpn/examples/easy-rsa/2.0/pkitool --pass user@domain
The openvpn client will need the files email@example.com, firstname.lastname@example.org, ca.crt, and ta.key. An openswan client will only need the first 3 of those files.
OpenSWAN Server Configuration details:
ipsec.conf: version 2.0 config setup nat_traversal=yes uniqueids=no conn %default compress=yes disablearrivalcheck=no authby=rsasig leftrsasigkey=%cert rightrsasigkey=%cert keyingtries=3 conn sslvpn type=tunnel left=%defaultroute leftsendcert=yes leftsubnet=192.168.1.0/24 leftid=my.server leftcert=my.server.crt dpdaction=clear pfs=yes right=%any rightsubnetwithin=0.0.0.0/0 rightca=%same auto=add
: RSA /etc/ipsec.d/private/my.server.key "PASSWORD"
OpenVPN Server Configuration details:
dev tap tls-server dh /etc/pki/keys/dh1024 ca /etc/ipsec.d/cacerts/ca.crt cert /etc/ipsec.d/certs/my.server.crt key /etc/ipsec.d/private/my.server.key askpass /etc/openvpn/my.server.password tls-auth /etc/pki/keys/ta.key 0 server-bridge 192.168.1.1 255.255.255.0 192.168.1.50 192.168.1.60 port 1194 comp-lzo up /etc/openvpn/up.sh down /etc/openvpn/down.sh keepalive 10 120
#!/bin/sh DEV=$1 MTU=$2 /sbin/ifconfig $DEV mtu $MTU up /usr/sbin/brctl addif br0 $DEV
#!/bin/sh # Intentionally empty script, the OS removes the interface # from the bridge when the connection terminates
OpenSWAN client configuration:
version 2.0 config setup nat_traversal=yes uniqueids=yes conn %default compress=yes disablearrivalcheck=no authby=rsasig leftrsasigkey=%cert rightrsasigkey=%cert keyingtries=3 conn vpn type=tunnel left=%defaultroute leftsendcert=yes email@example.com dpdaction=clear compress=yes right=my.server rightid=my.server rightca=%same rightsubnet=192.168.1.0/24 pfs=yes auto=start
: RSA /firstname.lastname@example.org "mypassword"
Put the certs in place:
$ cp ca.crt /etc/ipsec.d/cacerts $ cp email@example.com /etc/ipsec.d/private $ cp firstname.lastname@example.org /etc/ipsec.d/certs
OpenVPN client configuration:
$ echo "mypassword" > /etc/openvpn/password $ chmod 0600 /etc/openvpn/password
dev tap client remote my.server ca /etc/openvpn/ssl/ca.crt cert /email@example.com key /firstname.lastname@example.org tls-auth /etc/openvpn/ssl/ta.key 1 askpass /etc/openvpn/password port 1194 comp-lzo keepalive 10 120
Put the certs in place for this as well - the full paths are listed above.
To revoke a compromised or otherwise no longer valid certificate, you can use another script distributed with openvpn. We will for purposes of this demonstration say that we are revoking a certificate for baduser@domain, who has previously had a key pair generated for them. There will be 3 files in /etc/pki/keys associated with this certificate - the private key (email@example.com), the certificate signing request (firstname.lastname@example.org), and the signed certificate issued by our CA (email@example.com). It is important to remember that we are only revoking our signature on the public certificate - the private key is still a useable key, but it will no longer be part of our PKI.
So, the details:
$ . /etc/pki/vars
# Notice that we don't use the file extension - the script appends .crt
$ /usr/share/doc/openvpn/examples/easy-rsa/2.0/revoke-full baduser@domain $ cp /etc/pki/keys/ca.crl /etc/ipsec.d/crls/ $ cp /etc/pki/keys/ca.crl /etc/openvpn/ssl/
Add this to the server's openvpn configuration:
OpenSWAN will do the check automatically, but will need to be restarted.Acknowledgements:
Stephen Gran, System Administrator at LinuxForce; Primary Author
Elizabeth Bevilacqua, System Administrator at LinuxForce; Tester, Editor
CJ Fearnley, President of LinuxForce; Editor