Building a site-to-site VPN with Debian/Ubuntu and Openswan

Got two or more places you want to connect in a secure manner?
Then building a VPN might be a good idea.
For opensource VPN solutions you have two choices (roughly said) – OpenVPN or IPsec

OpenVPN is great for connections from roadwarriors, and some cases for site-to-site, but securing all trafiic between two sites – including between the two routers, is a pain. Another thing to consider is: both endpoints have to run OpenVPN.

IPsec on the other hand is fairly easy to use, once you’ve tried it once + you can use a lot of different equipment as endpoints.
This blog will look at setting up a VPN between two Debian/Ubuntu nodes.

Openswan setup
To illustrate the setup I want to build I’ve made this ascii “drawing” – hopy you can understand it 🙂

Host1 -- LAN1 -- Router1 --[BIG, BAD INTERNET]-- Router2 -- LAN2 -- Host2
  • LAN1: 192.168.0.0/24
  • LAN2: 192.168.1.0/24
  • Router1: eth0: 172.16.0.1/24 / eth1: 192.168.0.1/24
  • Router2: eth0: 172.16.1.1/24 / eth1: 192.168.1.1/24
  • Host1: 192.168.0.20/24
  • Host2: 192.168.1.20/24

tunnel or transport mode?
Dealing with IPsec there’s two primary modes a connection can have: transport and tunnel.
Transport mode secures a point to point connection (Router1 – Router2)
Tunnel mode secures subnet to subnet (LAN1 – LAN2)
Luckily we can combine them in a way so the tunnel mode can be on top of transport mode + you can make host to subnet connections, and this is what you’re likely to want.

Installing Openswan
Installing Openswan is as easy as it gets

apt-get install openswan

During installation the installer will ask if you want to use certificates for authentication, and if you want it to generate certificates for you – I always say no, since I have my own certificates I want to use.

Configuring Openswan
It’s possible to use either PSK (Pre shared keys), or certificates for authentication. Here I’ll use certificates

Config for Router1

config setup
 oe=off
 protostack=netkey

conn router1-router2
 left=172.16.0.1
 leftrsasigkey=%cert 
 leftcert=router1.crt
 leftid="C=SomeCountry, ST=n/a, L=SomeCity, O=SomeOrganisation, CN=Router1, E=ResponsibleEmail"
 right=172.16.1.1
 rightrsasigkey=%cert 
 rightcert=router2.crt
 rightid="C=SomeCountry, ST=n/a, L=SomeCity, O=SomeOrganisation, CN=Router2, E=ResponsibleEmail"
 auto=start

conn lan1-lan2
 leftsubnet=192.168.0.0/24
 rightsubnet=192.168.1.0/24
 also=router1-router2

conn router1-lan2
 rightsubnet=192.168.1.0/24
 also=router1-router2

conn lan1-router2
 leftsubnet=192.168.0.0/24
 also=router1-router2 

For Router2 it should be easy to figure out what to change.

iptables
There’s no fun in having a nice encrypted tunnel, and not getting packets through.
You could just tell iptables to pass all to/from the protected subnets, but what would happen if the tunnel wasn’t up? You would send unencrypted things out on the net … not good

In our example network the following would be a good suggestion on Router1 (not complete iptables ruleset, but the important ones here in this scope):

iptables -A POSTROUTING -t nat -d 192.168.1.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -A INPUT -m policy --dir in --pol ipsec -j ACCEPT
iptables -A INPUT -p udp -m multiports --dports 500,4500 -j ACCEPT
iptables -A INPUT -p esp -j ACCEPT
iptables -A FORWARD -m policy --dir in --pol ipsec -j ACCEPT

If you’re getting problems with mtu, remember to allow icmp fragmentation-needed in firewall

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.