Success in the land of the VPN

I can finally report success with my recent obsession with getting a functional VPN for my home network. Actually, I can report two...

For my IPsec VPN, I have settled upon the following configuration:

My home network is setup to use
  • My main subnet range is
  • My secondary subnet is (and is empty)
  • My OpenVPN subnet range is

I decided to put my IPsec VPN’s connections at

I mention the subnets so the virtual_private and l2tp config make sense...

Additionally, I’ve obviously changed the x.509 certificate details...

version 2.0
config setup

conn %default

conn roadwarrior-l2tp

conn roadwarrior
rightid="C=ZA, ST=State, O=Organization, OU=OrgUnit CN=*, E=*"

conn roadwarrior-l2tp-psk

Certificates are used for normal connections; the PSK is used by one (and only one) connection: My iPhone. For some reason,, the iPhone doesn’t support certificates when using L2TP. Since a PSK has the password as the key, it’s got a password that’s quite long, and is composed of the 96-character ASCII printable character set. According to the NIST’s password documents, it’s equivalent in difficulty of cracking encryption greater than 128 bits, which would require boiling the oceans to crack — I think I’ll be safe until quantum computing comes into its own...

I was surprised to learn that DES is slower to encrypt than AES; AES is quite a bit faster than 3DES, and is considerably more secure.
auth file = /etc/ppp/chap-secrets
listen-addr =
debug tunnel = yes
[lns default]
ip range =
local ip =
require chap = yes
refuse pap = yes
require authentication = yes
hostname =
ppp debug = yes
length bit = yes
pppoptfile = /etc/xl2tpd/options.l2tpd

idle 1800
mtu 1410
mru 1410
connect-delay 5000

After this, I was able to get an IPsec/L2TP VPN running.

Of course, there is a catch: my office (the big place I am when I’m not at home) is well... corporate. With IT guys. So in spite of the fact the network is more porous than I’d generally like, one thing that is blocked is IPsec.

Note to Network Admins: There are more internet protocols than TCP and UDP. IPsec has two: 50 is ESP, and 51 is AH. IPv6 has several. Of the two, IPv6 is potentially more dangerous... fewer people using it, sure, but there’s no NAT in IPv6, and practically nobody firewalls for it. (Who uses IPv6 anyway?!?)

Well, since my office blocks iPsec, I had to turn to its other good alternative: OpenVPN.

OpenVPN uses SSL, and any UDP port (though you can use TCP if you so desire). Because of that, OpenVPN is quite hard to block at a firewall level. As with IPsec, OpenVPN uses x.509 certificates.

My OpenVPN config is pretty much the default: After setting up x.509 certificates (which I did for my IPsec VPN), the rest was a breeze.

port 1194
proto udp
dev tun
ca /etc/ipsec.d/cacerts/cacert.pem
cert certs/openvpnCert.pem
key certs/openvpnKey.pem
crl-verify /etc/ipsec.d/crls/crl.pem
dh certs/dh1024.pem
ifconfig-pool-persist ipp.txt
# This allows connections to _only_
#push "route"
# This allows connections everywhere...
push "redirect-gateway def1"
push "dhcp-option DNS"
push "dhcp-option DOMAIN"
push "dhcp-option NTP”
keepalive 10 120
tls-auth certs/ta.key 0 # This file is secret
cipher AES-128-CBC # AES
user nobody
group nobody
status openvpn-status.log
verb 3

The only ‘tricky’ things was configuring the dh cert, and the tls-auth cert.
Do build the DH paramaters, you run:
openssl dhparam -out [dir]/dh[key_size].pem [key size]

For additional security, with OpenVPN, you can create a TLS shared secret key:
openvpn --genkey --secret ta.key

Lastly, there’s the jewels (to me, at least): Creating and using your own x.509 Certificate Authority and certificates.

I started by grabbing the system openssl.cnf (the default isn’t overly useful), and modified it for my use.
The config file itself is pretty self-explanatory. I decided to have my own config and just load it when I need it, rather than editing the system config.

To set the config, use the environment variable:
# export OPENSSL_CONF=/etc/ipsec.d/openssl.cnf

One important note: If you are going to be using OS X or iOS clients, you need the VPN server’s certificate to have:
Note: This is for the server’s certificate, not the x.509 Certificate Authority.

To create your own CA using OpenSSL:
# openssl req -x509 -days 3652 -newkey rsa:1024 -keyout caKey.pem -out caCert.pem

There are a few prompts - you feed in your country, state, city, organization, org uniit, hostname, and an email address. Nothing too interesting.

Next, from /etc/ipsec.d:
# mkdir newcerts
# touch index.txt
# echo “00” > serial
(Some have “01” to serial - it’s just a number, so it doesn’t really matter.)

Next, to create host certificates:
For the VPN server, I modified the openssl.cnf to add

And generated its key. Then for the clients, I commented out the line.

To generate the key, use:
# openssl req -key -newkey rsa:1024 -keyout mykey.pem -out keyReq.pem

This generates the private key and an x.509 certificate signing request.

Next, we sign the certificate signing request using our CA:
# openssl ca -in keyReq.pem -days 365 -out myCert.pem -notext -cert caCert.pem -keyfile caKey.pem

Next, you update the /etc/ipsec.secrets to have the server’s private key passphrase, as well as the PSK password for the iPhone VPN.

For Windows (and OS X, actually), it’s useful to put the CA Certificate, client certificate, and client private key into a PKCS#12 file:
# openssl pkcs12 -export -inkey mykey.pem -in myCert.pem -name UserName -certfile caCert.pem -caname “YourOrg Root CA” -out clientcert.p12
I think you can leave the -name UserName and -caname “YourOrg Root CA” out...

Last, we set up x.509 certificate revocation lists:
# echo “00” > /etc/ipsec.d/crlnumber
# openssl ca -gencrl -crldays 15 -out crl.pem -keyfile caKey.pem -cert caCert.pem

To revoke a certificate, you need the public certificate. (Look at /etc/ipsec.d/index.txt to get them - they should be in /etc/ipsec.d/newcerts.)
# openssl ca -revoke revokedCert.pem -keyfile caKey.pem -cert caCert.pem

Next, update the crl.pem:
# openssl crl -in crl.pem -noout -text

OpenVPN will automatically re-read the revocation list - revocation is effective immediately. With Openswan, you have to notify ipsec:
# ipsec auto --rereadcrls

In both cases, revoking a cert won’t cause the server to drop any current connections with that cert. The connection will stay up until the next rekey or reconnect — and then it will be rejected.