This page describes my VPN setup that allows "roadwarriors" (employees with laptops roaming around the country) to securely connect back in to my network. I have recently simplified the network greatly by removing the old gateway server (i broke it!) and replacing this with a Netgear ADSL router-modem. The Netgear unit is supplying IP addresses to my network (DHCP server enabled) and is the gateway on the system. This setup should be fairly generic and many router-modems will support this. Try to look out for VPN passthrough on the router-modem it should help a lot.
Basic router/network setup
As the router cannot deal with IPSEC it is necessary to have a computer inside the network that can. I am currently using a old laptop with a failed LCD display, it is only 450MHz and seems to cope fine. Firstly I installed Debian testing from the sarge-net install CD image on Debian's website. This was a painless process as long as you have a supported network card all you need to do is answer some simple questions. Once Debian is installed and running it is necessary to modify the network settings to give the VPN server a static IP address. Below are the entries I made to /etc/network/interfaces
# The primary network interface
#iface eth0 inet dhcp
iface eth0 inet static
address 192.168.0.2
netmask 255.255.255.0
gateway 192.168.0.1
mtu 1200
This is all fairly straight forward except perhaps the MTU parameter which will be explained later. Next it is necessary to add a few rules to the router. This Will vary from router to router but the concepts are the same. It is necessary to forward any incoming UDP 500 from the router to 192.168.0.2 and any incoming UDP 4500 from the router to 192.168.0.2. UDP-4500 was not a pre defined service on the Netgear so I had to add that on the services option and i called it ESPINUDP. Note the UDP-4500 is only needed for NAT-T (but that is a very nice thing to have). There were NO options to do anything with the ESP protocol that just seems to work with the Netgear (maybe because it specifices IPSEC pass through?).
Setting up the VPN server
Openswan seems to be the preferred "swan" in Debian so a simple
apt-get install openswan
will grab everything you need. I will assume that all the required certificates have been generated see X509 Certificate Generation. You should have 3 files from the certificate generation stage, a Certificate Authority certificate "cacert.pem", A private key "vpnserver.key", and a public key "vpnserver.pem" copy these files to the following locations :-
cacert.pem -----> /etc/ipsec.d/cacerts
vpnserver.key -----> /etc/ipsec.d/private
vpnserver.pem -----> /etc/ipsec.d/certs
There should also be a CRL (that lists revoked certificates) but it is not strictly necessary just good practise. Next add a line to /etc/ipsec.secrets to allow openswan to access the private key. Using your password as necessary
: RSA vpnserver.key "my_password_for_the_private_key"
Finally we come to the main configuration file, this is what I am currently using on the server
version 2.0
Config setup
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:174.16.0.0/12,%v4:192.168.0.0/16,%v4:!192.168.0.0/24
conn roadwarrior
dpdaction=clear
authby=rsasig
leftrsasigkey=%cert
rightrsasigkey=%cert
right=%any
rightnexthop=192.168.0.1
rightsubnet=vhost:%no,%priv
left=%defaultroute
leftcert=vpnserver.pem
auto=add
pfs=yes
leftsubnet=192.168.0.0/24
include /etc/ipsec.d/examples/no_oe.conf
IP Forwarding and masquerading
With this setup it will currently be impossible to access any machine other that the vpnserver as there is a fundamental routing problem, a packet from roadwarrior x.x.x.x destined for 192.168.0.20 will be received by the vpnserver (192.168.0.2) decrypted and dropped. If ip_forward is enabled then the packet will not be dropped but sent to 192.168.0.20. 192.168.0.20 will reply to x.x.x.x which means the reply will go directly to the gateway 192.168.0.1 and back to x.x.x.x UNENCRYPTED. Any sensible firewalls will not then drop this packet. To solve this it is necessary to do two things:-
* Enable IP Forwarding
* Enable Masquerading
To enable IP Forwarding add/change the line in /etc/network/options so it reads :-
ip_forward=yes
To enable masquerading it is necessary to run the iptables command
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
This will now masquerade any incoming packets from x.x.x.x to 192.168.0.2 so the routing works and the encryption is intact. (** TODO **) It SHOULD be possible to automatically run the above commands. I have created a script with the above commands and place it in /etc/network/if-up.d/ but i don't think it works. I am not sure if the script should have a special name such as eth0-iptables.sh I need to check this when I can down the VPN server for 5 minutes.
MTU
MTU is a problem with this setup. MTU stands for maximum transmission size and it sets how large a chunk of data can be sent from a network interface. A typical Ethernet interface has a MTU of 1500 while a PPP connection has a slightly lower size due to the overhead of the ppp layer. If we then add an IPSEC layer then overall data size reduces even further. What happens if the MTU is left at 1500 is that servers on the internal LAN will send data in 1500 chunks, the IPSEC wrapping will then be forced to fragment the data in to two packets, a full one and a partial one. This cases chaos and packet loss. To avoid this setting the ethernet to a MTU of 1200 ensures that there is always sufficeint overhead to ensure the ESP wrapper (IPSEC) doesn't cause the data to overflow a single IP frame.
In fact 1200 is very consertivative, i believe nornal ipsec requires 56 bytes and NAT-T sequires a few more ao 1400 should be OK for many situations.
Next version of server and more MTU problems!
I decided to upgrade my servers to Debian Sarge and build mail, filesharing and ipsec all on one system. I no longer had a direct connection to the internet (through a modem) but via a network with a dedicated router. This caused by chaos!. The problem is one of MTU. As the router connected to the internet via a ppp link (adsl) and then connected to the ipsec server via eth0 there are mtu issues. For me the ipsec tunnel came up but it was impossible to access things such as pop3 mail etc on the server. If i tried to access other systems (ie NOT the endpoint then providing the MTU rules as discussed above were followed then it this worked.
So access to the endpoint has a mtu issue. There are no network devices to set the mtu on so what do you do? I discovered a new command the "ip" command, i have never used this before. In fact "ip route" shows intresting routing stuff and infact you can set the mtu on a specific route :-). So I found i could change the mtu of the ipsec route no problems, and setting to 1300 fixed the pop3 etc probelsm :-)
Automating the process:- setting the route by hand is a non starter for a production situation, so how to do it automaticly. Well it seems that the updown scrips are the answer. In /usr/lib/ipsec/ there are scripts incluidng _updown, that get run by the openswan system. To change the MTU of a new ipsec connection open the /usr/lib/ipsec/_updown file and search for the line :-
case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
"0.0.0.0/0.0.0.0")
# opportunistic encryption work around
# need to provide route that eclipses default, without
# replacing it.
it="ip route $1 0.0.0.0/1 $parms2 &&
ip route $1 128.0.0.0/1 $parms2"
;;
*) it="ip route $1 $parms $parms2 $parms3"
;;
and chage it to :-
case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
"0.0.0.0/0.0.0.0")
# opportunistic encryption work around
# need to provide route that eclipses default, without
# replacing it.
it="ip route $1 0.0.0.0/1 $parms2 &&
ip route $1 128.0.0.0/1 $parms2 mtu 1300"
;;
*) it="ip route $1 $parms $parms2 $parms3 mtu 1300"
;;
Now all new ipsec connections will get a MTU of 1300. Jobs done!
References
Debian's home page
Openswan's home page
Previous page: mail-relay
Next page: GNU-Linux-IPSEC-Client
