*** Disclaimer: This is not supported by Rackspace. If it blows up, we can’t help you fix it. I’ve tested it a fair bit and it seems to be working fine, however if it does not work for you, you’re pretty much on your own. I would advise thorough testing before deploying this solution to a production environment. ***


After a long hiatus from writing articles, I found something interesting to tinker with again after a customer asked about VPN, I had never tried it so my answer was “It should be possible, but I’m not sure”. Now I can say that it is definitely possible, and give you a practical setup utilizing IPSEC to hook into your sweet Cisco ASAs in your corporate networks. This was tested using two cloud networks,  but it should work for cloud network to anything that supports IPSEC. You could also potentially do this with any other VPN solution, such as OpenVPN.

This guide will walk you through setting up an openswan ipsec tunnel that connects one network to another, as well as a dhcpd server to make it mostly automatic to anything on the network.  Read on after the jump.



The setup:

We need 6 servers and 2 networks. (Granted, you could do just 2, but 6 is a good number).  For my setup, I have created the following servers/networks:

  • Network A:
  • Swan A:
  • Client A-1: (Will eventually be DHCPed, but it is on the network)
  • Client A-2: (Will eventually be DHCPed, but it is on the network)
  • Network B:
  • Swan B:
  • Client B-1: (Will eventually be DHCPed, but it is on the network)
  • Client B-1: (Will eventually be DHCPed, but it is on the network)

Since we will be setting up openswan with x509 certificate certifications, we first need to create some certificates. I am going to go through creating a CA to sign these all with, however if you have your own already feel free to use those.


First thing we need to do is install openssl, which is easy enough:

# aptitude update
# aptitude install openssl

Next we will set up our root CA’s directory structure:

# mkdir /root/CA
# cd /root/CA
/root/CA# mkdir certs  crl  newcerts  private
# chmod -R 700 /root/CA/
# touch /root/CA/index.txt
# echo -e "01\n" > /root/CA/serial

After that we make our initial CA cert, I use a fairly large key for this, but feel free to make it smaller or larger.

# openssl genrsa -out ca.key 8192
# openssl req -new -x509 -extensions v3_ca -key ca.key -out ca.crt -days 3650

This will ask you quite a bunch of questions, answer what makes sense for your setup. For instance here is my root CA:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Failverse
Organizational Unit Name (eg, section) []:TMH
Common Name (eg, YOUR name) []:ca.failverse.com
Email Address []:

This will give you a root certificate, so now we can move everything where it belongs, then edit the openssl.cnf to use these certs.

# mv ca.crt certs/ && mv ca.key private/
# chmod 400 /root/CA/certs/ca.key
# vim /etc/ssl/openssl.cnf

In the openssl.cnf file locate the following lines and modify them to match (or edit for your settings):

dir = /root/CA
certificate = $dir/certs/ca.crt
private_key = $dir/private/ca.key

Now that we have our CA set up, lets create our certificates for both of our openswan servers:

# openssl genrsa -out swana.key 4096
# openssl req -new -key swana.key -out swana.csr

This will prompt you with more questions. answer them like you did for your CA. I used ‘vpn1.failverse.com’ for the Common Name this time around. Once you have done this, you’ll rerun the commands for the other VPN server:

# openssl genrsa -out swanb.key 4096
# openssl req -new -key swanb.key -out swanb.csr

Now we sign our certs with the CA:

# openssl ca -out swana.crt -infiles swana.csr
# openssl ca -out swanb.crt -infiles swanb.csr

Next we will start setting up openswan, which will be the software that enabled us to do ipsec. For the obvious of getting it installed.

# aptitude install openswan

This will ask some questions, say yes to x509, and import, but you can just leave the fields blank. Repeat this on both swanA and swanB

Next place the certificates and keys in the correct places.

On SwanA:

  • Copy swana.crt and swanb.crt into /etc/ipsec.d/certs/
  • Copy ca.crt to /etc/ipsec.d/cacerts
  • Copy swana.key to /etc/ipsec.d/private

Edit /etc/ipsec.secrets with the following:

: RSA /etc/ipsec.d/private/swana.key

Repeat the same process on SwanB, except don’t copy swana to the private directory and instead copy swanb. (Edit the ipsec.secrets with swanb, as well)

Now that we have our keys in place, we need to edit a couple parameters with sysctl, these should do the trick and make it persist through reboots:

# for var in `sysctl -a | egrep "accept_redirects|send_redirects" | awk '{print $1}'`; do sysctl -w $var=0 >> /etc/sysctl.conf; done
# sysctl -w net.ipv4.ip_forward=1 >> /etc/sysctl.conf

If this doesn’t work for you, the goal is to have every net.ip*.conf.*.accept_redirects set to 0, as having the redirects will cause oddness in the tunnel. You can verify that it is fixed with ipsec verify

Now that our kernel is all done, here is the ipsec.conf file:

On swan A: /etc/ipsec.conf

# /etc/ipsec.conf - Openswan IPsec configuration file

# This file:  /usr/share/doc/openswan/ipsec.conf-sample
# Manual:     ipsec.conf.5

version	2.0	# conforms to second version of ipsec.conf specification

# basic configuration
config setup

conn vpn


On SwanB set rightnexthop=%defaultroute, and leftnexthop to The Public IP of SwanA. Our policy is to have a tunnel from to, as such we need to make a route on our swan boxes.

On SwanA:

#  ip r add via

Now you can test and should get a response:

# root@swan-a:/etc/ipsec.d# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_req=1 ttl=64 time=2.25 ms

Since it’s working, we can make this permanent, edit /etc/network/interfaces, and under the eth2 section add the following:

On SwanA:
up route add -net netmask gw

On SwanB:
up route add -net netmask gw

To test a client, simply add the same route and try to ping to the other network, for instance:

root@client1-a# ip r add via
root@client1-a# ping
# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_req=1 ttl=64 time=2.25 ms

You now have a choice to make. You can either set up dhcpd on your vpn servers and have them act as gateways and NAT everything to your servers, or you can set up routes on every client in the networks.
Pros of dhcpd-server:

  • You can disable public interfaces if you would like
  • No Client Config Needed

Cons of dhcpd-server:

  • Entire LAN limited to bandwidth of the VPN gateway
  • Single point of failure – if the gateway goes down, all servers lose internet access


While you decide that, let’s make sure everything comes up on boot:

# ln -s /etc/init.d/ipsec /etc/rc1.d/K10ipsec
# ln -s /etc/init.d/ipsec /etc/rc2.d/S10ipsec
# ln -s /etc/init.d/ipsec /etc/rc3.d/S10ipsec
# ln -s /etc/init.d/ipsec /etc/rc4.d/S10ipsec
# ln -s /etc/init.d/ipsec /etc/rc5.d/S10ipsec
# ln -s /etc/init.d/ipsec /etc/rc6.d/K10ipsec

If you’ve decided to just set up routes on each client, make sure that you set them in /etc/network/interfaces so that it persists through reboots.

If you are deciding to use a dhcpd server, the rest of this guide will walk you through it:

On SwanA:

# aptitide install dhcp3-server


subnet netmask {
  option domain-name-servers,;  # grab these out of your /etc/resolve.conf
  option routers;
  option broadcast-address;
  default-lease-time 600;
  max-lease-time 7200;

Then start it and make it start on boot:

# service isc-dhcp-server start
# update-rc.d isc-dhcp-server enable

Next set up proper NAT:

# iptables -t nat -A POSTROUTING ! -d -o eth0 -j MASQUERADE
# iptables-save >> /etc/iptables.save

Next edit /etc/network/interfaces and add the following in the eth2 section:

post-up iptables-restore < /etc/iptables.save

You'll need to do the same thing on SwanB, replacing values as needed. On your client, you will need to edit /etc/network/interfaces, comment out the eth0 sections, then edit the eth2 section to this:

auto eth2 
iface eth2 inet dhcp

Make sure you SSH in from eth2 (via the gateway) and then restart networking, it will get a new IP address from the dhcp server and be able to communicate out through it, as well as over the VPN tunnel.

As some final notes, you may consider setting up static dhcp leases, and locking down your iptables some more. If you opt to lock down iptables, make sure your forward chain remains open, you have an established,related rule, and udp500 remains open.