OpenVPN

OpenVPN

Presented to CP-LUG 13 May 2008 by Matthew Rinehart

Description

OpenVPN is an open source (GPLv2) application for establishing secure connections over insecure networks.

Essential Terms

PKI

Public Key Infrastructure

Everyone who has ever connected via SSH or HTTPS has used part of PKI. A pair of keys (big numbers) is generated for each entity needing an identity (like a server). One of these keys is considered public; anyone can view this key in its entirety, and in fact, should. The other key is private; only the entity to whom the key pair belongs should have access to this key.

By using an asymmetric key pair, encryption can be established between two entities who have previously never communicated. Here's how it might work connecting to an SSL webserver.

  1. Client makes request for https://whatever/
  2. Server transmits its public key to the client.
  3. Client generates a session key (symmetric cryptography, a "shared secret")
  4. Client encrypts the session key with the server's public key
  5. Encrypted session key is transmitted to server
  6. Server decrypts session key with its private key
  7. Server establishes secure connection using session key as a shared secret

VPN

Virtual Private Network

On your home's private network, you can communicate between the hosts on the network without worrying about anyone on the Internet seeing that traffic because you're on a private subnet that doesn't get routed to the Internet.

A VPN provides that same security via encryption. Once a VPN connection is established, the traffic to the hosts on your home network is encrypted before being sent across the Internet, then decrypted at the VPN server and sent the rest of the way just as traffic on the local network would be. The response is then sent back to the VPN server, encrypted, and forwarded back across the Internet to your VPN client, which decrypts it and presents it to the application.

Once setup and running, a VPN can and should be completely transparent.

Installation

There are several installation options available.

The Easy Way

emerge openvpn

The Almost-As-Easy Way

Install it from your (other) distribution's software repository.

The Hard Way

Build it yourself. Sources can be obtained from http://openvpn.net/index.php/downloads.html

For building it from source manually, you will need to have installed OpenSSL, LZO, and PAM, if you want the same functionality that the binary packages provide. It is a standard ./configure; make; make install procedure; just pass in the proper options to the configure script to get it built the way you like it.

The Other Ways

OpenVPN will run on Mac and Windows. A Windows installer is provided at the OpenVPN download page: http://openvpn.net/index.php/downloads.html

Third parties have provided other versions, as well as GUIs. The general OpenVPN howto at http://openvpn.net/index.php/documentation/howto.html has some information on those.

Configuration

There are several choices to be made when configuring OpenVPN.

Routed or Bridged?
A routed VPN configuration means that clients will receive IP addresses on a different subnet than the one you're using for your network, and the VPN server will route requests between the subnets.
A bridged VPN configuration creates an Ethernet bridge between the clients and server. All clients will have IP addresses on the same subnet as the server and other hosts on the server's network.
Numbering private subnets
The private subnets used for your local network as well as (if using the routed method above) the VPN client IP pool need to be sufficiently unique to lower the probability that a remote site's private network is using an overlapping or coinciding address space. A popular subnet in use because of default router configurations is 192.168.1.0/24. Attempting to establish a connection to a site using that subnet from another site using that subnet will result in routing conflicts. A request to 192.168.1.100 is ambiguous under this configuration. For that reason, OpenVPN recommends you configure your local network (and VPN client subnet) to be address spaces somewhere within the large 10.0.0.0/8 range.

Setting up PKI

OpenVPN ships a set of tools called "easy-rsa" for establishing your site's PKI. It consists of a series of scripts which invoke OpenSSL with various parameters to generate keys, certificates, and other essential files.

PKI Setup Workflow

Step Host Action Affected/Generated Files
1 All Edit vars to reflect the settings for your site. (none)
2 All . ./vars (none)
3 All ./clean-all index.txt, serial
4 CA ./build-ca (take defaults) ca.key, ca.crt
5 Server ./build-req --server servername (take defaults) servername.key, servername.csr
6 Server -> CA Transfer servername.csr to keys directory servername.csr
7 CA ./sign-req server (answer 'y' to both prompts) servername.crt, 01.pem, index.txt, index.txt.attr, serial
8 CA -> Server Transfer servername.crt to keys directory servername.crt
9 Server ./build-dh dh1024.pem
10 Client ./build-req clientname (take defaults) clientname.key, clientname.csr
11 Client -> CA Transfer clientname.csr to keys directory clientname.csr
12 CA ./sign-req clientname (answer 'y' to both prompts) clientname.crt, 02.pem, index.txt, index.txt.attr, serial
13 CA -> Client Transfer clientname.crt to keys directory clientname.crt
14 CA -> All Transfer ca.crt to keys directory ca.crt

At completion, the following should represent the files present on each type of machine:

Host File Purpose
CA ca.key CA private key; signs certificate signing requests from server and clients
CA *.crt Public certificates; key revocation
Server ca.crt CA certificate; certificate validation
Server dh1024.pem Diffie-Hellman parameters
Server servername.crt Server certificate (public key)
Server servername.key Server private key
Client ca.crt CA certificate; certificate validation
Client clientname.crt Client certificate (public key)
Client clientname.key Client private key

Setting up server configuration

/etc/openvpn/openvpn.conf:

port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
key /etc/openvpn/easy-rsa/keys/server.key
dh dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /etc/openvpn/ipp.txt
;client-to-client
;duplicate-cn
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status /etc/openvpn/openvpn-status.log
verb 3
server subnet mask
Sets up server mode and defines a network range for client configuration. The VPN server will take the first available address in the subnet and assign the other addresses to clients as they connect. In this example, the VPN server will be on 10.8.0.1
ifconfig-pool-presist file
Stores information on client configuration in a file so that clients can be assigned the same IP the next time they connect.
client-to-client
Permit connected clients to see each other on the network.
duplicate-cn
Allow multiple clients identifying themselves the same way (i.e., using the same certificate) to be connected simultaneously.
comp-lzo
Employ compression to the network traffic.
user/group
After initalizing, drop privileges to the specified credentials.
persist-key/persist-tun
Do not try to reopen the server key/network tunnel device on restart/reload, as the reduced privileges make that impossible.
status file
Write status information to a log file. The file is periodically truncated to prevent it from growing out of control.
verb number
Set verbosity level of openvpn output.

Setting up client configuration

/etc/openvpn/openvpn.conf:

client
dev tun
proto udp
remote server 1194
resolv-retry infinite
nobind
user nobody
group nobody
persist-key
persist-tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/client.crt
key /etc/openvpn/keys/client.key
ns-cert-type server
comp-lzo
verb 3
client
Specify client mode.
remote server port
Specify the VPN server to connect to. Multiple remote entries can be provided for load-balancing.
resolv-retry infinite
Continue forever trying to resolve the server and connect.
nobind
Bind to any random client port instead of a specific one.
ns-cert-type server
Require the VPN server to have a certificate with the nsCertType set to "server".

Additional Tweaking

So far, OpenVPN installed and configured this way will allow a single client to connect to a single server and communicate only with it. Depending on your environment, you may want to implement one or more of the following additional configurations.

CRL Verification

It is a good idea to make use of a CRL (certificate revocation list) for your PKI. OpenVPN can be configured to look for a CRL and read it on each client connection to verify that the client's certificate is still valid. The crl-verify directive will enable this. The file specified as the argument to that directive is re-read on each new connection and can therefore be updated/replaced while the server is running.

NOTE: A valid CRL file must already be in place to use crl-verify. You cannot specify the name of a file that does not yet exist, or a 0-length file. The server will fail to start.

Revoking a certificate is done at the CA/key-signing server with the script revoke-full, e.g., ./revoke-full clientname. This creates or updates a crl.pem file, which can be copied to your OpenVPN server and referenced with the crl-verify directive.

Client Configuration Directory

The directive client-config-dir specifies a directory holding client-specific configuration files. They are named identical to the CN attribute of the client certificate. This file can be used to push specific settings to the client, such as a static IP, additional routes, etc.

A common use for this might be adding your site's DNS server to the client configuration so that local hostnames resolve as expected once connected. It can also be used to push a new default gateway to the client, such that ALL traffic originating from the host defaults to the VPN.

Expand Access on Server Side

It's likely you want to be able to use the VPN to connect to more than one machine on your local network. This is a fairly simple process. If you are using a tunneled connection, do the following:

  1. Configure the VPN server for IP forwarding/routing
  2. Add the configuration directive push "route VPN_subnet VPN_subnet_mask" to the server configuration file
  3. If the VPN server is not on also the local network gateway, add a static route to the gateway to instruct it to forward traffic intended for the VPN subnet to the VPN server

For TAP connections, do nothing. The server-side network is automatically fully accessible under this configuration, since the VPN clients receive addresses on the same network segment.

Expand Access on the Client Side

Although less likely than expanding the access on the server side, OpenVPN supports the scenario in which you would want a single machine on the client side to connect to the VPN and allow all other machines on its network to speak to the VPN as well.

In order to do this, the client's subnet must be unique; it cannot be used by the server's network, the virtual network, or any other connecting client's network. The client must also be identified by a specific certificate that is not allowed to be used by any other client.

To start, the client must be configured for IP forwarding. Next, the server must be setup with client-config-dir, such that a configuration file can be specified for this specific client alone. That configuration file must contain the following directive:

iroute <client's subnet ID> <client's subnet mask>

This informs the OpenVPN process to forward traffic received intended for that network to this client. Then, in the main server configuration file, the following directive should be specified:

route <client's subnet ID> <client's subnet mask>

This instructs the daemon to add that route to the kernel's routing table on startup, so that traffic intended for that subnet gets to OpenVPN.

If other clients should be able to see the subnet behind this particular client, add the following:

client-to-client
push "route <client's subnet ID> <client's subnet mask>

Note that this will allow clients to see all other clients as well, which may not be ideal.

Finally, if the VPN server is not the local network gateway, add a static route to the gateway to send traffic intended for the client's subnet to the VPN server.

If the client involved in this configuration isn't the gateway for its network, a similar setup will be required on its end to route traffic properly.

Management Interface

A management interface can be enabled with the directive management address port. A telnet client can connect to this address and port to issue commands, or a GUI can be configured to send the commands to that address and port in response to manipulation of its interface.

Some of the things you can do with the management interface is forcibly disconnect existing connections (e.g., if you've just revoked their certificate or if you want them to pull new commands from the client-config-dir) and adjust daemon verbosity on the fly.

Other Options

The possibilities are seemingly endless. Here are some advanced configurations that I haven't needed to implement yet and therefore have not looked into closely:

  • Pushing DHCP options to clients with dhcp-option
  • Restricting access based on connecting client
  • Username/password authentication
  • Smartcard login
  • Redirecting all traffic through the VPN
  • Connecting to the OpenVPN server via HTTP proxy
  • Load-balancing/failover
  • Additional hardening
    • HMAC signatures via tls-auth
    • Fully-unprivileged operation on Linux servers
    • chroot jail
    • Larger key sizes
    • Isolation of ca.key
    • Verifying server certificate type as "server"