OpenVPN

OpenVPN is a secure tunnel. I use it to connect to my home network.

OpenVPN uses certificates to both authenticate the client with the server, and the server with the client. The only hard part about OpenVPN is setting up the certificate infrastructure. You need a root certificate (the certificate authority, CA), and certificates for each server and each client, signed by this root certificate.

Setting up a public key infrastructure
The use of client certificates enhances the security, but makes it harder to deploy, as you need to distribute client certificates to each host. You can not use an existing public key infrastructure (PKI); you would allow anyone with a certificate of that PKI to connect to your server (the  and   options can limits the allowed clients). You either need to to set up your own certificate infrastructure, or limit OpenVPN to use password-based authentication (see the options,   and  ).

The easiest method it to use easy-rsa, as described in the OpenVPN How-to.

The article Create a OpenVPN Certificate Authority describes the steps in more detail, but basically gives the same result.

Certificates, when deployed correctly, are much more secure than passwords, since the secret (key) does not need to be exchanged or shared between the different hosts. However, doing so requires a security hygiene which may not be required for a small-scale deployment.

Running IPv6 through the Tunnel
OpenVPN can both use a tap or a tun interface. A tap interface tunnels Ethernet traffic, so that includes both IPv4, IPv6 and NetBIOS. A tun interface tunnels IP traffic. Version 2.3 of OpenVPN supports tunnelling bot IPv4 and IPv6 traffic through the tunnel. OpenVPN 2.2 can also tunnel IPv6 traffic, but requires a custom scripts to configure the IPv6 addresses and routing tables. At the time of writing, OpenVPN 2.3 is not yet released, so the following three options are available:
 * Use a tap interface to bridge all Ethernet traffic, including IPv4 and IPv6 traffic. The disadvantage is that is less efficient since the tunnel contains broadcast traffic not targeted to the client;
 * Wait for OpenVPN 2.3 or compile a development version;
 * Use OpenVPN 2.2 with a custom connect- and disconnect script to set the IPv6 address of the tunnel.

I choose to compile a development version.

Install Development Version
On FreeBSD: cd /usr/ports/security/openvpn-devel sudo make install

On Mac OS X: sudo port install lzo2 git clone git://openvpn.git.sourceforge.net/gitroot/openvpn/openvpn.git cd openvpn git checkout 32ab329bc69c6292c205d4f33a4b8069341798d3 autoreconf -i -v ./configure --with-lzo-headers=/opt/local/include --with-lzo-lib=/opt/local/lib make make check sudo make install

Configure IPv6 Tunnel
Imagine the following setup:

A sample server and client configuration follow. These examples could probably be reduced in size; some parameters are default or some can be combined (e.g. " " can replace " ", " " " " and " ").

See the OpenVPN man page and Gert Döring's IPv6 Payload Patch for information on the different configuration options.

OpenVPN server configuration
local 192.0.2.206 proto udp  # or tcp-server is UDP is blocked dev tun1 ca         ca.crt cert       server.crt key        server.key dh         dh2048.pem crl-verify crl.pem tls-auth   tls-auth.key mode server tls-server topology net30 ifconfig 10.240.177.1 10.240.177.2 ifconfig-pool 10.240.177.4 10.240.177.251 route 10.240.177.0 255.255.255.0 tun-ipv6 ifconfig-ipv6 2001:db8:f0:b1::1 2001:db8:f0:b1::2 ifconfig-ipv6-pool 2001:db8:f0:b1::4/64 route-ipv6 2001:db8:f0:b1::/64 push route 10.240.128.0 255.255.254.0 push route-ipv6 2001:db8:f0:80::0/63 ifconfig-pool-persist ipp.txt keepalive 10 60
 * 1) The IP to listen on for incoming VPN connections
 * 1) PKI Stuff
 * 1) Option TLS shared secret for HMAC signing for additional security
 * 1) the actual routes are 10.240.129.0/24 and 2001:db8:f0:81::/64 but this avoids
 * 2) a bug when connecting from the private network
 * 1) server and client ping every 10 seconds, client reconnects after 60 seconds.

user nobody group nobody persist-key persist-tun ns-cert-type client remote-cert-tls client duplicate-cn # log        /var/log/openvpn-server.log log-append /var/log/openvpn.log status     /var/log/openvpn-status.log verb 3
 * 1) Allow a client to log in multiple times
 * 1) opt-verify
 * 1) Logging

OpenVPN client configuration
remote 145.99.1.67 1194 udp remote 145.99.1.67 1194 tcp-client dev tun nobind tls-client pull ca      ca.crt cert    cert.crt key     key.key tls-auth tls-auth.key tun-ipv6 persist-key persist-tun ns-cert-type server
 * 1) First try UDP
 * 1) If UDP fails, try TCP

Problems
This section describes some of the problems I encountered and how I solved them.

Problem
configure: checking for LZO Library and Header files... checking lzo/lzo1x.h usability... no checking lzo/lzo1x.h presence... no checking for lzo/lzo1x.h... no checking lzo1x.h usability... no checking lzo1x.h presence... no checking for lzo1x.h... no LZO headers were not found LZO library available from http://www.oberhumer.com/opensource/lzo/ configure: error: Or try ./configure --disable-lzo OR ./configure --enable-lzo-stub

Solution
If lzo2 library isn't yet install, install it first: sudo port install lzo2 Check where lzo2 is installed: % locate lzo1x.h /opt/local/include/lzo/lzo1x.h and tell openvpn where to find it: ./configure --with-lzo-headers=/opt/local/include --with-lzo-lib=/opt/local/lib

VPN from Private Network
There is no benefit in a connection from the private network to the VPN server. However, such connection may sometimes occur if OpenVPN is set to automatically connect to the VPN server. This leads to a problem when the VPN connection is subsequently terminated.

Problem
After the VPN connection is terminated, while the client is still in the local network, the client loses all its connectivity.

If the VPN tunnel is established in the above example, the routes 10.240.129.0/24 and 2001:db8:f0:81::/64 are pushed to the client. Since the client is connecting from this network, the routing table already contains these networks. The OpenVPN nevertheless tries to add them, which gives the error "File exists":

route: writing to routing socket: File exists add net 2001:db8:f0:81::: gateway tun0: File exists route: writing to routing socket: File exists add net 10.240.129.0 gateway 10.240.129.5: File exists

The connection proceeds as normal. The actual routing table is not changed (traffic to these ranges still takes the direct route, not the tunnel). As soon as the VPN connection is brought down, so are these routes:

delete net 10.240.129.0: gateway 10.240.129.5 delete_route_ipv6(2001:db8:f0:81::/64) delete net 2001:db8:f0:81::: gateway tun0 delete_route_ipv6(2001:db8:f0:81::/64)

Despite the mismatch of the gateway, Mac OS X still removes these routes from the routing table, meaning that the OS no longer knows how to make local connections.

Workaround
There are a few possible solutions:
 * Simply don't connect to the OpenVPN server when the laptop is the private network. This can perhaps even be automated with a script that checks the local IP address before connecting.
 * Create a custom connect and disconnect script that brings the routes up and down.
 * Make sure the route that is pushed by the OpenVPN server is different from the local subnet. What I did is push the larger subnets:

push route 10.240.128.0 255.255.254.0 push route-ipv6 2001:db8:f0:80::0/63
 * 1) the actual routes are 10.240.129.0/24 and 2001:db8:f0:81::/64 but pushing a larger
 * 2) subnet avoids a bug when connecting from the private network.

If you are using the Viscosity GUI, an alternative solution is to enable the preference "Reset network interfaces on disconnect" in the Advanced preferences tab.

Problem
While using the above example scripts, I get the following warnings:

NOTE: explicit support for IPv6 tun devices is not provided for this OS ... add_route_ipv6(2001:db8:f0:b1::/64 -> 2001:db8:f0:b1::4 metric -1683000573) dev tun0 route: writing to routing socket: File exists add net 2001:db8:f0:b1::: gateway tun0: File exists

Solution
Despite these warnings, everything works for me.

If it does not for you, I recommend to:
 * Update your tun/tap driver. I got mine from Tuntap OS X.
 * Ask on the OpenVPN mailing list or OpenVPN Forum.

Problem
% make check ... Sat Feb 11 22:46:37 2012 OpenVPN 2.x-master x86_64-apple-darwin11.2.0 [SSL (OpenSSL)] [LZO2] [eurephia] [MH] [PF_INET6] [IPv6 payload 20110522-1 (2.2.0)] built on Feb 11 2012 Sat Feb 11 22:46:37 2012 Cipher 'BF-CBC' uses a mode not supported by OpenVPN in your current configuration. CBC mode is always supported, while CFB and OFB modes are supported only when using SSL/TLS authentication and key exchange mode, and when OpenVPN has been built with ALLOW_NON_CBC_CIPHERS. Sat Feb 11 22:46:37 2012 Exiting due to fatal error FAIL: t_lpback.sh ...

The above is strange, as BF-CBC (Blowfish) seem normally compiled in: % /usr/local/sbin/openvpn --show-ciphers ... BF-CBC 128 bit default key (variable) ...

This seem to be bug introduced in revision 670f9dd91aed7ac435b79c0e28e49fa7c256642c. It has been fixed in revision 6449a149f850e9e1207233f3ca642d9342fbfbaf.

Solution
Revert to the latest revision of OpenVPN: cd openvpn make distclean git checkout master