*** 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: 192.168.5.0/24
- Swan A: 192.168.5.1
- Client A-1: (Will eventually be DHCPed, but it is on the 192.168.5.0/24 network)
- Client A-2: (Will eventually be DHCPed, but it is on the 192.168.5.0/24 network)
- Network B: 192.168.6.0/24
- Swan B: 192.168.6.2
- Client B-1: (Will eventually be DHCPed, but it is on the 192.168.6.0/24 network)
- Client B-1: (Will eventually be DHCPed, but it is on the 192.168.6.0/24 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 oe=off protostack=netkey interfaces=%defaultroute conn vpn left=SWANAPUBLICIP leftcert=swana.crt leftrsasigkey=%cert leftsubnet=192.168.5.0/24 leftnexthop=%defaultroute right=SWANBPUBLICIP rightcert=swanb.crt rightsubnet=192.168.6.0/24 rightrsasigkey=%cert rightnexthop=SWANAPUBLICIP auto=start
On SwanB set rightnexthop=%defaultroute, and leftnexthop to The Public IP of SwanA. Our policy is to have a tunnel from 192.168.5.0/24 to 192.168.6.0/24, as such we need to make a route on our swan boxes.
On SwanA:
# ip r add 192.168.6.0/24 via 192.168.5.1
Now you can test and should get a response:
# root@swan-a:/etc/ipsec.d# ping 192.168.6.2 PING 192.168.6.2 (192.168.6.2) 56(84) bytes of data. 64 bytes from 192.168.6.2: icmp_req=1 ttl=64 time=2.25 ms ^C
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 192.168.6.0 netmask 255.255.255.0 gw 192.168.5.1 On SwanB: up route add -net 192.168.5.0 netmask 255.255.255.0 gw 192.168.6.2
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 192.168.6.0/24 via 192.168.5.1 root@client1-a# ping 192.168.6.2 # ping 192.168.6.2 PING 192.168.6.2 (192.168.6.2) 56(84) bytes of data. 64 bytes from 192.168.6.2: icmp_req=1 ttl=64 time=2.25 ms ^C
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
/etc/dhcp/dhcpd.conf
subnet 192.168.5.0 netmask 255.255.255.0 { range 192.168.5.100 192.168.5.150; option domain-name-servers 72.3.128.241, 72.3.128.240; # grab these out of your /etc/resolve.conf option routers 192.168.5.1; option broadcast-address 192.168.5.255; 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 192.168.6.0/24 -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.