|
(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.
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.
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.
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
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.
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.
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.
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.
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.
The prerequisites for connecting to VLAN are broken apart
in generic prerequisites, and OS specific prerequisites.
-
A x.509 certificate, preferably signed by the VLAN
Certificate Authority.
-
An assigned subnet in the 10.64.0.0/14 range
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
-
racoon
-
Zebra/Quagga
-
OpenSSL
-
Windows 2000 (Professional, (Advanced) Server),
Windows XP Professional or Windows 2003 Server
-
Patience, coffee and a RSI free mousehand
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:
-
Your signed X.509 certificate
-
The root CA X.509 certificate
-
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.
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.
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
$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.
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.
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.
As in the previous sections on Linux IPSec, the
relevant bits out of $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.
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.
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`.
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.
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.
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.
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.
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.
[ToDo] Steg promised to write
this.
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.
tcpdump, windump, firewall logging, registry setting,
etc
FLOSS
IRC
IPSec
VPN
GRE
NAP
DER
PEM
etc.
back to main
|