Topic: Articles (ipv4)IPSec + GRE + Routing
03:12pm CEST, 30 Apr 2005 (Updated 03:28pm CEST, 30 Apr 2005)

This document intends to describe how to build a scalable VPN based using (IPv4) IPSec tunnels, GRE tunnels and dynamic routing protocols like OSPF and BGP. Not only does this document provide a guideline for (new) members seeking how to connect to the Undernet amp;num;ipsec VPN, but it also tries to provide configuration examples and a little design philosophy for those seeking to implement a similar VPN of their own.

1. Preface

1.1. Who should read this

This document is intended for people who are interrested in joining the VLAN project, or in general people who are interested in building a similar VPN. Knowledge on basic Unix system administration (including compiling custom kernels for your preferred flavour of Unix like operating system), routing and routing protocols and VPN technology is assumed, together with some experience in setting up a basic IPSec tunnel in your OS of choice.


1.2. Background

The experiences and configurations used in this document are currently (at date of writing) used in a wide area VPN, spanning from New Zealand to Canada to Europe. The goal of this WAVPN (we call it “VLAN”, and that's the term which will be used when referring to this functional implementation) is to function as a testbed for its members to try out new (to us) technology, and teach ourselves in the art of designing, building, configuring, managing and troubleshooting a larger scale network than would be possible with more conventional means.


1.3. Acknowledgements

Everything which is described in this document has come to be as a group effort. Without most of the people in the Undernet #ipsec IRC channel, various people in the Undernet #linux IRC channel, various people in the Undernet #linuxhelp IRC channel, people on various mailing lists and of course the numerous people who have been writing documentation on the web or in books, all this wouldn't have been possible. Credit where credit is due, without the entire FLOSS community which provides such a massive amount of software, documentation and support for free, mere mortals would be unable to undertake projects like these. Special mention deserves the people behind the Linux Advanced Routing & Traffic Control Howto (generally known as LARTC, see references). Without the work you guys put into this invaluable resource


1.4. Document layout

After you finish this, this document continues with a small explanation on how the VLAN is put together. It's short, and will leave out most details as to continue as fast as possible with the more interresting technical details. This starts with providing a list of prerequisites (“stuff you need”), only to continue with a description of how to connect your favourite IPSec implementation to the VLAN. Configuration examples and all. Not assuming everything will work in one stroke, a section on troubleshooting your connection(s) is provided, which brings you to the obligatory document endings like a list of references, literature and a glossary.


1.5. Conventions

Configuration snippets are formatted as follows:


configuration snippet
   

Furthermore, it's assumed that your local IP address is w.x.y.z, and the IP address of the IPSec peer you're connecting to is a.b.c.d with e.f.g.h as its nexthop.


1.6. Disclaimer

License


2. How it all fits together

This chapter will explain how the VLAN is fit together. This design does not pretend to be optimal, and work is in progress to design an infrastructure which is both scalable and provides failover for broken links. As it is, though, it works.


2.1. Network layout

The network is designed around the idea that there will be 3 to 4 major routing hubs (or “NAP” for “Network Access Point”) to which everyone in a certain area connects to. Currently there are just two of these NAPs, with work in progress to add a third. Each of these NAPs have a subnet assigned in which all of its attached subnetworks live. The NAPs are connected to eachother with a high bandwidth link, in effect creating a multiple star topology. The below diagram shows how it should be, the next diagram shows how it is now.


2.2. Point-to-point links

Most interconnections between endpoints are point-to-point ipsec tunnels (or: transport mode) which encapsulate a point-to-point GRE tunnel. The result is a plain, with strong encryption protected, IPv4 path between the endpoints . The reason for choosing this GRE over IPSec construction is that IPSec in itself is fairly rigid in the network addresses it allows to be routed across an IPSec tunnel. Adding a GRE tunnel inside the IPSec tunnel circumvents that feature, and allows routing of random source addresses to random destination addresses. Added advantage is that multicast and friends have no problems crossing ipsec boundaries when GRE is used, which helps a lot with designing a dynamic routing scheme. Of course this scheme has disadvantages too, two of which are potential problems with packet fragmentation and large header overhead.


3. Prerequisites

The prerequisites for connecting to VLAN are broken apart in generic prerequisites, and OS specific prerequisites.


3.1. Generic prerequisites

  • A x.509 certificate, preferably signed by the VLAN Certificate Authority.

  • An assigned subnet in the 10.64.0.0/14 range


3.2. Linux

This document describes connecting two different Linux IPSec implementations:

  • Linux kernel 2.4.x

  • (Super) FreeS/Wan

and:

  • Linux kernel 2.6.x

  • ipsec-tools or -

  • FreeS/Wan frontend

For all of the above, the rest of the requirements are:

  • IPRoute2

  • Zebra/Quagga

  • OpenSSL


3.3. BSD

  • racoon

  • Zebra/Quagga

  • OpenSSL


3.4. Windows

  • Windows 2000 (Professional, (Advanced) Server), Windows XP Professional or Windows 2003 Server

  • Patience, coffee and a RSI free mousehand


4. X.509 certificate

To get an IPSec link going to the NAP of choice, you'll need to generate an X.509 certificate, as that is the preferred way of exchanging public keys. The reason why this is easier is that with some luck it will be an automatic process, provided the IPSec peers know the DN's of eachother.

Generating a private key and the belonging X.509 certificate request (i.e. public key which needs to be acknowledged) is done with openssl using the following command:

openssl req -newkey rsa:2048 -keyout myKey.pem -out myReq.pem
  

After putting in some details which are later coded into the certificate as asn1dn, a passphrase will be asked to protect the generated private key file: myKey.pem. The “myReq.pem” file is the certificate request (read: public key) which needs signing by a Certificate Authority, preferably the one designated for VLAN. Send the request to the appropriate CA administrator for signing, and (s)he'll return you as soon as possible with the X.509 certificate. You can also sign your own certificate when you have your own CA. Setting up your own CA and signing requests is beyond the scope of this document. For more information on this subject, see the References section.

The CA will return you with a couple of files, being:

  1. Your signed X.509 certificate

  2. The root CA X.509 certificate

  3. The Certificate Revocation List, or CRL

These files only need copying to the proper location so your IPSec implementation can find it. Depending on the format your CA provided the files, you might need to convert back and forth between DER and PEM. See the openssl manual for more information (`man x509`). Note: The .cer file format Windows will accept is a DER formatted certificate.

[ToDo] Figure out how to generate a request in a Windows host.


5. Connecting things

5.1. Linux

5.1.1. Linux 2.4 with FreeS/Wan

This document assumes knowledge in configuring and compiling kernels. Also, the FreeS/WAN documentation is extensive enough to guide you through the process of compiling kernels and getting basic ipsec links up with peers. See the references section for links where you can find all the details you want. Lets concentrate on the specific case of getting a fully functional connection to the VLAN going, starting with the configuration of the kernel.


5.1.1.1. Kernel configuration

To make fully use of the VLAN link you're about to set up, your kernel will need support for a number of things. The relevant bits out of &dollar;KERNEL_SOURCE/.config are below. The support for most, if not all, of these components can be either in module (<M>) form or compiled in (<y>), depending on your preference. This is the minimum requirement for getting things to work.

CONFIG_NETFILTER=y
CONFIG_IP_MULTICAST=y
CONFIG_NET_IPGRE=y
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IPSEC=m
CONFIG_IPSEC_AUTH_HMAC_MD5=y
CONFIG_IPSEC_AUTH_HMAC_SHA1=y
CONFIG_IPSEC_ESP=y
CONFIG_IPSEC_ENC_3DES=y
CONFIG_IPSEC_IPCOMP=y
     

As you can see, it basically boils down to support for Netfilter/iptables, GRE tunnels and IPSec. Support for TCP/IP networking is implied. X.509 support in your FreeS/WAN implementation is assumed, no further kernel configuration is required for that to work. For more information on adding X.509 certificate support to FreeS/WAN, see the References section.


5.1.1.2. FreeS/Wan configuration

First thing to do is set up the x509 infrastructure, so that FreeS/Wan is able to find everything it needs.

Just for convenience the list of files used in this part of the configuration (assuming sane default names):

/etc/ipsec.d/private/myKey.pem
/etc/ipsec.secrets
/etc/x509cert.der
/etc/ipsec.d/cacerts/vpnCA.pem
/etc/ipsec.d/crls/vpnCRL.pem
     

Move the earlier generated private key file to /etc/ipsec.d/private/myKey.pem and modify /etc/ipsec.secrets so that it reads something like:

:RSA myKey.pem "my_uberl33t_passphrase"
     

on the first line of the file. This is necessary to unlock the private key which was encrypted with a passphrase when it was generated. Using this format will make FreeS/Wan assume all keyed connections will use certificates, with the indicated private key to match. For security reasons you can now chmod 600 both the myKey.pem en ipsec.secrets file, so only root can read or write to it.

Depending on which format you receive your X.509 certificate back, you either need to convert it or simply copy it to its proper location. This is because the default FreeS/Wan looks for is /etc/x509cert.der, which as the name implies needs to be your certificate in DER format. The VLAN CA sends both recognised forms (DER and PEM) back, but just in case “man x509” tells you how to convert from one format to another. In short; /etc/x509cert.der needs to be the X.509 certificate the CA signed for you in DER format (item 1). Item 2 is the CA's own public certificate, which goes in /etc/ipsec.d/cacerts/. Just copy it there and FreeS/Wan will find it. The last item you received is the list which contains all the certificates which the CA signed, but marked invalid at a later date. This file goes in /etc/ipsec.d/crls/.

The first step after setting up all the certificate stuff is to get a point-to-point IPSec link going with a NAP. This process is similar to setting up a regular IPSec link as per the FreeS/Wan documentation, with the little difference that instead of a reference to the public RSA key of both ends, there will now be a reference to the identifying DN of their X.509 certificates. Assuming that the NAP you connect to is “right” and you are “left”, your /etc/ipsec.conf should look something like the below code snippet:


config setup
 interfaces=%defaultroute
 klipsdebug=none
 plutodebug=none
 plutoload=%search
 plutostart=%search
 uniqueids=yes
conn vlan-link
 right=a.b.c.d
 rightnexthop=e.f.g.h
 rightid="C=CC, O=VLAN, E=admin@vlan.NAP"
 rightrsasigkey=%cert
 left=%defaultroute
 leftid="C=CC, O=VLAN_CLIENTNET, E=admin@vlan.clientnet"
 leftrsasigkey=%cert
 compress=yes
 authby=rsasig
 auto=start
 type=transport
     

This is a very basic configuration, but is likely to work, assuming firewalls and such are configured to allow the traffic needed (protocol 50 and port 500/udp), and your setup is fairly straightforward. Add complexity as needed for your environment.

Given that all we need out of the ipsec link is a point-to-point encrypted channel to pass GRE over, transport mode suffices, which explains the “type=transport” in the configuration.


5.1.2. Linux 2.6

As of the Linux kernel 2.5.x development series, Linux users are blessed with a native cryptography API, and an ipsec implementation for IPv4. Given that the now stabilized 2.6 series kernel will be in widespread use soon, this section will deal with configuring the builtin IPSec for use with the VLAN.


5.1.2.1. Kernel Configuration

As in the previous sections on Linux IPSec, the relevant bits out of &dollar;KERNEL_SOURCE/.config are listed below. The support for most, if not all, of these components can be either in module (<M>) form or compiled in (<y>), depending on your preference. This is the minimum requirement for getting things to work:

CONFIG_IP_MULTICAST=y
CONFIG_NET_IPGRE=y
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_NET_KEY=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_NETFILTER=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_DEFLATE=y
     

Breaking it down, it amounts to adding support for Netfilter, GRE, IPSec and the Cryptographic API. Again, being able to set all these options implies having TCP/IP networking support enabled.


5.1.2.2. The IPSec trick

We'll place all the keys and certificates under /etc/certs, with the difference that your own x509 certificate is now copied to /etc/certs/myCert.pem. So everything now looks as follows:

/etc/certs/myKey.pem
/etc/certs/myCert.pem
/etc/certs/napCert.pem
     

The /etc/certs/napCert.pem file is the x.509 certificate of the NAP you're connecting to.


5.1.2.2.1. Setting up the policies

Linux 2.6 IPsec works with policies. In the configuration sample below, two policies are defined, one for incoming traffic and one for outgoing traffic. Put this configuration in a file, e.g. /etc/ipsec.conf:

#!/sbin/setkey -f
flush;
spdflush;
spdadd a.b.c.d w.x.y.w any -P in ipsec
  esp/transport//require;
spdadd w.x.y.z. a.b.c.d any -P out ipsec
  esp/transport//require;
      

and load it into the kernel with `setkey -f /etc/ipsec.conf`.


5.1.2.2.2. Setting up the keying daemon

To automate the ipsec negotiations (exchanging keys, validating them, etc), a key management daemon is used. The ipsec-tools package which is used for Linux 2.6 ipsec contains a port of BSD's racoon for this. It's set up for use on the VLAN by building a configuration file /etc/racoon/racoon.conf as follows:

path certificate "/etc/certs";
listen
{
 isakmp w.x.y.z;
}
remote a.b.c.d
{
 exchange mode main;
 my_identifier asn1dn;
 peer_identifier asn1dn;
 peers_certfile "napCert.pem";
 certificate_type x509 "myCert.pem" "myKey.pem";
 proposal {
  encryption_algorithm 3des;
  hash_algorithm sha1;
  authentication_method rsasig;
  dh_group 2;
 }
}
sainfo address w.x.y.z any address a.b.c.d any
{
 pfs_group 2;
 encryption_algorithm 3des;
 authentication_algorithm hmac_sha1;
 compression_algorithm deflate;
}
      

Now, when traffic appears which matches one of the policies defined above, the IPSec negotiation will start, which will hopefully result in a working IPSec tunnel.


5.1.3. Adding GRE

Assuming the previous section resulted in a working IPSec connection to a NAP, you can now proceed with adding a GRE tunnel. For this the IPRoute2 package is used, which basically is another frontend to the netfilter code in the kernel. Learn to love the powerfull, but unfortunately underdocumented `ip` tool. A reference for the usage of this tool is the manual page (`man ip`), but also LARTC (see references).

A couple of assumptions are made for this part in the process, they are listed below:

  • your endpoint VPN address will be 10.64.25.1 (10.64.25.0/24 is your assigned subnet), your current public IP address is w.x.y.z

  • considering the above, your peer's VPN address will be 10.64.0.1, its public IP address is a.b.c.d

  • ipsec0 is your IPSec device used by the kernel for routing ipsec packets (where applicable)

The following commands will result in a GRE tunnel which is tied to the ipsec0 interface:

ip tunnel add vlan-link mode gre remote a.b.c.d local w.x.y.z ttl 255 dev ipsec0
ip addr add 10.64.25.1 peer 10.64.0.1 dev vlan-link
ip link set vlan-link up
    

With some luck, you'll now have another network interface “vlan-link”, which you can use to send plain IPv4 traffic to...any IPv4 traffic, including routing information, which we'll attend to next.


5.1.4. Obtaining routing information

5.1.4.1. Static

The easiest way to get your traffic routed to the VLAN is by adding a static route into your kernel routing table.

ip route add 10.64.0.0/14 via 10.64.25.1 dev vlan-link
     

However, for that to work, you will also need to convince the NAP admin to add a (static) route for your subnet into the NAP host's routing tables. This is an administrative burden, and error prone, so VLAN makes use of dynamic routing protocols to pass around routing information.


5.1.4.2. OSPF

OSPF is implemented in Linux with Zebra, or more recently, Quagga. Its configuration format has a lot of similarities with Cisco's IOS, so if you're a network admin, you'll feel right at home. Using Zebra's ospfd the following configuration can be used:

interface vlan-link
 ip ospf network point-to-point
!
router ospf
 ospf router-id 10.64.25.1
 redistribute kernel route-map vlan-filter
 redistribute connected route-map vlan-filter
 network 10.64.25.1/32 area 0
 network 10.64.0.1/32 area 0
!
access-list vlan-net permit 10.64.0.0/14
!
route-map vlan-filter permit 10
 match ip address vlan-net
!
     

Don't forget to save any changes you make to /etc/zebra/ospfd.conf. Hopefully the routers on either end of the GRE tunnel will see eachother right away which saves troubleshooting. Check with the zebra command (in the zebra console interface, telnet localhost 2604):

sh ip ospf neighbor
     

Which should produce something that looks like:

Neighbor ID     Pri   State           Dead Time   Address         Interface           RXmtL RqstL DBsmL
10.64.0.1         1   Full/DROther    00:00:38    10.64.0.1       vlan-link:10.64.25.1     0     0     0
     

The “Full/DROther” indicates a full OSPF relation between both routers. You can verify the distribution of routes with typing:

ip route show
     

in your shell, which should yield a rather large routing table with lots of “proto zebra” entries.


5.1.5. Automating

Apart from the GRE part of the process, all configuration steps are carried out using configuration files. Automating the setup of the GRE tunnel is a bit trickier as it requires the ipsec tunnel to be up and running before the attempt is made to create a GRE tunnel over it. For the lazy people amongst us, Russel Howe has solved this problem for FreeS/Wan users by creating a set of scripts which get called when an IPSec tunnel comes up or goes down. It's still work in progress (for VLAN we're working on getting rid of the configuration files which it depends on), but they're quite functional already. You can download these scripts from http://lithium.sta.man.ac.uk/˜rhowe/ipsec_gre.tar.gz. These scripts come with a manual, read it for installation instructions.


5.2. BSD

&lsqb;ToDo&rsqb; Steg promised to write this.


5.3. Windows

The “hard” way (native)

Using the tools on http://vpn.ebootis.de

OSPF routing with netsh and/or gui (http://aggriffiths.d2.net.au/andrewg/windows_ospf.html)

Add screenshots.


6. Troubleshooting

tcpdump, windump, firewall logging, registry setting, etc


7. References

  • IPSec Interoperability guide

  • LARTC

  • Nate Carlson's site

  • FreeS/Wan documentation

  • Zebra documentation

  • Linux ipsec-howto


9. Glossary

FLOSS

IRC

IPSec

VPN

GRE

NAP

DER

PEM

etc.

back to main


 Topic: