Use OpenVPN to easily tie together your networks.
Creating a VPN can be quite difficult, especially when dealing with clients using multiple platforms. Quite often, a single VPN implementation isn’t available for all of them. As an administrator, you can be left trying to get different VPN implementations to operate on all the different platforms that you need to support, which can become a nightmare.
Luckily, someone has stepped in to fill the void in cross-platform VPN packages by writing OpenVPN (http://openvpn.sourceforge.net
). OpenVPN supports Linux, Solaris, OpenBSD, FreeBSD, NetBSD, Mac OS X, and Windows 2000/XP. It achieves this by implementing all of the encryption, key-management, and connection-setup functionality in a user-space daemon, leaving the actual tunneling portion of the job to the host operating system.
To accomplish the tunneling, OpenVPN makes use of the host operating system’s virtual TUN or TAP device. These devices export virtual network interfaces, which are then managed by the openvpn process to provide a point-to-point interface between the hosts participating in the VPN.
Instead of being sent and received by the virtual device, traffic is sent and received from a user-space program. Thus, when data is sent across the virtual device, it is relayed to the openvpn program, which then encrypts it and sends it to the openvpn process running on the remote end of the VPN link. When the data is received on the other end, the openvpn process decrypts it and relays it to the virtual device on that machine. It is then processed just like a packet being received on any other physical interface.
OpenVPN uses SSL and relies on the OpenSSL
library (http://www.openssl.org
) for encryption, authentication, and certificate verification functionality. Tunnels created with OpenVPN can either use preshared static keys or take advantage of TLS dynamic keying and digital certificates. Since OpenVPN makes use of OpenSSL, it can support any cipher that OpenSSL supports. The main advantage of this is that OpenVPN will be able to transparently support any new ciphers as they are added to the OpenSSL distribution.
If you’re using a Windows-based operating system or Mac OS X, all you need to do is download the installer, run it, and configure OpenVPN. On all other platforms, you’ll need to compile OpenVPN yourself. Before you compile and install OpenVPN, make sure that you have OpenSSL installed.
Installing the
LZO compression library (http://www.oberhumer.com/opensource/lzo/
) is also generally a good idea. Using LZO compression can make much more efficient use of your bandwidth, and it may even greatly improve performance in some circumstances.
To compile and install OpenVPN, download the tarball and type something similar to this:
$tar xfz openvpn-2.0.7.tar.gz
$cd openvpn-2.0.7
$./configure && make
If you installed the LZO libraries and header files somewhere other than /usr/lib and /usr/include, you will probably need to use the --with-lzo-headers
and --with-lzo-lib
configure script options.
For example, if you have installed LZO under the /usr/local hierarchy, you’ll want to run the configure script like this:
$ ./configure --with-lzo-headers=/usr/local/include \
--with-lzo-lib=/usr/local/lib
If the configure script cannot find the LZO libraries and headers, it will print out a warning that looks like this:
LZO library and headers not found. LZO library available from http://www.oberhumer.com/opensource/lzo/ configure: error: Or try ./configure --disable-lzo
If the script does find the LZO libraries, you should see output on your terminal that is similar to this:
configure: checking for LZO Library and Header files... checking lzo1x.h usability... yes checking lzo1x.h presence... yes checking for lzo1x.h... yes checking for lzo1x_1_15_compress in -llzo... yes
Now that that’s out of the way, you can install OpenVPN by running the usual make install
. If you are running
Solaris, you’ll also need to install a TUN/TAP driver. The other Unix-based operating systems already include one, and the Windows and Mac OS installers will install the driver for you. You can get the source code to the Solaris driver from the SourceForge project page (http://vtun.sourceforge.net/tun/
).
Once you have LZO, OpenSSL, the TUN/TAP driver, and OpenVPN installed, you can test everything by setting up a rudimentary VPN (that isn’t so private) from the command line.
On machine A (kryten in this example), run a command similar to this one:
# openvpn --remote zul --dev tun0 --ifconfig 10.0.0.19 10.0.0.5
The command that you’ll need to run on machine B (zul) is a lot like the previous command, except the arguments to --ifconfig
are swapped:
# openvpn --remote kryten --dev tun0 --ifconfig 10.0.0.5 10.0.0.19
The first IP address is the local end of the tunnel, and the second is the remote end; this is why you need to swap the IP addresses on the other end. When running these commands, you should see a warning about not using encryption, as well as some status messages. Once OpenVPN starts, run ifconfig
to verify that the point-to-point tunnel device has been set up:
[andrew@kryten andrew]$ /sbin/ifconfig tun0 tun0: flags=51<UP,POINTOPOINT,RUNNING> mtu 1300 inet 10.0.0.19 --> 10.0.0.5 netmask 0xffffffff
Now, try pinging the remote machine, using its tunneled IP address:
[andrew@kryten andrew]$ ping -c 4 10.0.0.5 PING 10.0.0.5 (10.0.0.5): 56 data bytes 64 bytes from 10.0.0.5: icmp_seq=0 ttl=255 time=0.864 ms 64 bytes from 10.0.0.5: icmp_seq=1 ttl=255 time=1.012 ms 64 bytes from 10.0.0.5: icmp_seq=2 ttl=255 time=0.776 ms 64 bytes from 10.0.0.5: icmp_seq=3 ttl=255 time=0.825 ms --- 10.0.0.5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.776/0.869/1.012 ms
Now that you have verified that OpenVPN is working properly, it’s time to create a configuration that’s a little more useful in the real world. First, you will need to create SSL certificates [Hack #69] for each end of the connection. After you’ve done this, you’ll need to create configuration files on your server and clients. For these examples, zul will be the gateway into the private network and kryten will be the external client.
The configuration file for zul will be stored in /etc/openvpn/openvpn.conf. Here are the contents:
port 5000 dev tun0 tls-server dh /etc/ssl/dh1024.pem ca /etc/ssl/CA.crt cert /etc/ssl/zul.crt key /etc/ssl/private/zul.key mode server ifconfig 192.168.1.1 192.168.1.2 ifconfig-pool 192.168.1.4 192.168.1.255 push "route 192.168.0.0 255.255.255.0" route 192.168.1.0 255.255.255.0 ping 10 ping-restart 120 push "ping 10" push "ping-restart 60" daemon user _openvpn group _openvpn chroot /var/empty writepid /var/run/openvpn.pid verb 1
The port
and dev
options are used to specify what port to listen on and what TUN device to use. The tls-server
option enables TLS mode and specifies that you want to designate this side of the connection as the server during the TLS handshaking process. The dh
option specifies the Diffie-Hellman parameters to use during key exchange. These are encoded in a .pem file and can be generated with the following openssl
command:
# openssl dhparam -out dh1024.pem 1024
The next few configuration options deal with the SSL certificates. The ca
option specifies the Certificate Authority’s public certificate, and the cert
option specifies the public certificate to use for this side of the connection. Similarly, the key
option specifies the private key that corresponds to the public certificate.
The next option, server
, tells OpenVPN to act as a multi-client UDP server. This means that the server will dynamically allocate an IP address for any VPN client that connects to it. The range that the server uses to allocate these addresses is set with the ifconfig-pool
option. However, as you’re still really using a TUN interface to send and receive traffic, you’ll need to specify the addresses for each end of your TUN interface by using the ifconfig
option.
Next, set up routing between the VPN subnet and the rest of the network. Set the route on the server with the route
option, which takes a network address and netmask as its arguments. Set the route on the client via the push
command, which lets you send configuration information to authenticated clients.
To help ensure that the VPN tunnel doesn’t get dropped from any intervening firewalls that are doing stateful filtering, use the ping
option. This causes OpenVPN to ping the remote host every n seconds so that the tunnel’s entry in the firewall’s state table does not time out. If the client or server doesn’t receive a ping within 60 or 120 seconds, respectively, the ping-restart
option will cause them to attempt to reconnect to each other.
Finishing up, tell OpenVPN to fork into the background by using the daemon
option, drop its privileges to the _openvpn user and group with the user
and group
options, and tell it to chroot()
to /var/empty by using the chroot
option.
On kryten, the following configuration file is used:
port 5000 dev tun0 remote zul tls-client ca /etc/ssl/CA.crt cert /etc/ssl/kryten.crt key /etc/ssl/private/kryten.key pull verb 1
The main differences in this configuration file are that the remote
and tls-client
options have been used. Other than that, kryten’s public and private keys are used instead of zul’s, and the pull
option is used to request that the server push additional configuration information to the client. To turn on compression, add the comp-lzo
option to the configuration files on both ends of the VPN.
Now, the only thing to worry about is firewalling. You’ll want to allow traffic coming through your tun0
device, as well as UDP port 5000.
Finally, you are ready to run openvpn on both sides, using a command like this:
# openvpn --config /etc/openvpn.conf
Setting up OpenVPN under Windows is even easier. Simply run the OpenVPN GUI installer (http://openvpn.se/download.html
), and everything you need will be installed onto your system. This includes OpenSSL, LZO, the TUN/TAP driver, and OpenVPN itself. During the install process, you’ll be prompted about what to install and about whether or not to hide the TUN/TAP interface so that it won’t appear in your Network Connections folder, as shown in Figure 10-3.
Accepting the defaults should be okay in most situations. The Certificate Wizard is provided so that users can generate certificate requests to have their network administrators create certificates for them.
As part of the install process, files with the .ovpn extension are associated with OpenVPN. After the installation has completed, go into the config directory where you installed OpenVPN (e.g., C:\Program Files\OpenVPN\config if you accepted the defaults).
Now, create a file with an .ovpn extension and put your configuration settings in it. You’ll need to put your certificate and key files into the config directory as well. You should now be able to connect to your VPN by clicking on the OpenVPN GUI System Tray icon.
With the aid of Tunnelblick (http://www.tunnelblick.net
), installing OpenVPN under Mac OS X is just as easy as it is under Windows. Simply go to the Tunnelblick site and download the disk image appropriate for your version of Mac OS (Panther or Tiger). After you’ve opened the disk image, double-click on the Tunnelblick-Complete.mpkg package file. Once installation has completed, go to your Applications folder, find Tunnelblick, and launch it.
Tunnelblick will then prompt you to create a configuration file and open a window in which you can paste your settings. The file that you create here will be stored in ~/Library/openvpn. After you’ve done this, copy your key and certificates to ~/Library/openvpn.
You’re almost done now. Locate the icon that looks like a tunnel in the right-most position of the menu bar, click it, and then click Connect. With luck, you should be connected to your VPN in moments.
This hack should get you started using OpenVPN, but it has far too many configuration options to discuss here. Be sure to look at the OpenVPN web site for more information.