Mobile IPv6/NEMO testbed
Introduction
Below, you'll find all the steps required to setup a complete IPsec/IKE-protected Mobile IPv6 environment under Linux. This document provides the required information to patch and build the 3 main parts: racoon, UMIP and a custom kernel. Once you have completed those steps, two additional sections provide detailed configuration notes for racoon and UMIP.
Before you enter the funny part (the practice), it is important that you understand how the theoretical parts fit together. Let's first take some time to describe the building blocks, their implementation status, their lacks and how they are intended to work together.
-
Linux Kernel: for quite some time now, thanks to the continuous effort of USAGI developers, Linux Kernel is IPv6 and MIPv6 ready. For the MIPv6 part, only a little amount of MIPv6-specific code is maintained in the kernel, mainly to support the extension headers (RH2, HAO in Dest. Opt. Header) work and the IPsec protection (using XFRM framework for both). Most of the functionalities are implemented in userland (in UMIP, see below).
At the time of writing, the kernel fully implements the MIGRATE mechanism part of expired version 04 of MIGRATE draft but SADB_X_EXT_PACKET part is not implemented (and will probably never be due to associated complexity and lacks) which makes things useless for dynamic keying with IKE. A simple extension of MIGRATE design allows to remove the need for SADB_X_EXT_PACKET extension. This is covered in an informational document written by A. Ebalard and S. Decugis, and is implemented in Kernel 2.6.28 and above. Current kernels however still need to be patched, as explained below.
-
UMIP: The UMIP version available in our umip.git repository now supports MIGRATEv2 and does not need to be patched.
-
racoon: IPsec-Tools is a port of KAME's IPsec utilities to the Linux-2.6 IPsec implementation. It provides an IKE (version 1) daemon implementation called racoon. The current version does not provide any Mobile IPv6 support out of the box. A set of patches (discussed below) are required at the time of writing.
Note: This document is based on racoon, which only supports IKEv1. If you are interested in IKEv2, patches and documentation are available for racoon2 in this howto written by Sebastien Decugis. Note that the whole setup he describes there is based on SADB_X_EXT_PACKET mechanism (as specified in expired 04 version of MIGRATE draft) which has been replaced in the set of patches presented here by some improvements of MIGRATE design.
Building a MIGRATEv2-ready Kernel
This section describes all the steps to patch, configure, build and install a MIGRATEv2-enabled kernel that will support IPv6 mobility in IPsec environments using Dynamic Keying (IKE). The current document is based on a 2.6.29.5 kernel.
Download the kernel sources from kernel.org. For example with a 2.6.29.5 kernel:
$ cd /usr/src/ $ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.29.5.tar.gz
Verify the integrity of the downloaded kernel sources:
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.29.5.tar.gz.sign $ gpg --keyserver wwwkeys.pgp.net --recv-keys 0x517D0F0E $ gpg --verify linux-2.6.29.5.tar.gz.sign gpg: Signature made Mon 15 Jun 2009 09:12:59 PM CEST using DSA key ID 517D0F0E gpg: Good signature from "Linux Kernel Archives Verification Key <ftpadmin@kernel.org>"
Uncompress the sources, and create a symbolic link to the kernel sources:
$ tar zxf linux-2.6.29.tar.gz $ rm linux-2.6.29.tar.gz* $ ln -s /usr/src/linux-2.6.29.5/include /usr/src/linux $ cd linux-2.6.29
Let's now grab MIGRATEv2 kernel patches. The set of patches is a quilt repository maintained using git. After issuing the following command, you will be provided with a patches/ folder at the root of your kernel tree.
$ git clone git://git.umip.org/migrate2_kernel_patches.git Cloning into migrate2_kernel_patches... remote: Counting objects: 192, done. remote: Compressing objects: 100% (192/192), done. remote: Total 192 (delta 0), reused 192 (delta 0) Receiving objects: 100% (192/192), 211.38 KiB, done.
I encourage you to perform a "git log" call to get some information on the latest patchset (tip) to verify that the set of patches is suitable for your version of the kernel.
$ cd patches/
$ git log
commit f4116df8af1e507590b3b126bcd08a18d92f5e7a
Author: Arnaud Ebalard <arno@natisbad.org>
Date: Wed Mar 25 14:20:40 2009 +0100
Update for 2.6.29
...
$ cd ..
For the reader not familiar with quilt, all the files in the patches/ folder (apart from the series file) are patches and the series file provide the order in which the patches will be applied.
$ ls patches/ prevent_larval_states_migration.patch series set_mip6_ipsec_fw_kernel_options.patch $ cat patches/series set_mip6_ipsec_fw_kernel_options.patch prevent_larval_states_migration.patch
quilt is used to simplify the application of patches. This is done by issuing the following command (you may need to install the quilt package for your operating system):
$ quilt push -a Applying patch set_mip6_ipsec_fw_kernel_options.patch patching file set_mip6_ipsec_fw_kernel_options.sh Applying patch prevent_larval_states_migration.patch patching file net/xfrm/xfrm_state.c Now at patch prevent_larval_states_migration.patch
Now that you have a patched kernel, it can be configured, and then compiled, as usual. Because UMIP and racoon will require some options to be set and to avoid the burden of finding and setting them, a script is provided for that purpose (if you want to do it by hand, just skip the associated step described below). Note that the script configures the kernel with static support (i.e. not module) for required features. Feel free to modify it to suit your needs. In practice, you can simply (and usually) reuse your old running kernel configuration and then set the required options:
$ make oldconfig $ chmod u+x set_mip6_ipsec_fw_kernel_options.sh $ ./set_mip6_ipsec_fw_kernel_options.sh .config
You can now proceed to the kernel compilation and installation:
$ make # make install # make modules_install
Verify your bootloader configuration and reboot on your new kernel.
Building the UMIP Userland from the Sources
MIGRATEv2 support for UMIP is available from our umip.git repository. Simply follow the instructions available on this page to build UMIP. As an alternative, you can also use our UMIP Debian packages.
The necessary UMIP configuration is described later in the document, after the IPsec-tools (racoon) packages generation.
Racoon
IPsec-Tools is a port of KAME's IPsec utilities to the Linux-2.6 IPsec implementation. It supports NetBSD and FreeBSD as well. It is mainly composed of following parts:
- libipsec: Library with PF_KEY implementation.
- setkey: Tool to dump and interact with the kernel Security Policy Database and Security Association Database (SADB).
- racoon: Internet Key Exchange (IKEv1) daemon for automatically keying IPsec connections.
At the time of writing, racoon does not support MIGRATE (neither the 04 version, nor 05 version of the draft). For that reason, it needs to be patched. We will use the development tree of ipsec-tools which is maintained with CVS. It can be checked out using the following command:
$ cd /usr/src/ $ cvs -danoncvs@anoncvs.netbsd.org:/cvsroot co ipsec-tools cvs checkout: Updating ipsec-tools U ipsec-tools/.cvsignore U ipsec-tools/ChangeLog U ipsec-tools/Makefile.am U ipsec-tools/NEWS ...
We provide two git repositories destined to racoon: one contains the necessary patches to support MIGRATE, another one can be used to build easily Debian packages. Under Debian, the process to assemble all the pieces together and then build the package is the following:
$ mv ipsec-tools ipsec-tools-umip-0.7 $ cd ipsec-tools-umip-0.7 $ git clone git://git.umip.org/racoon/debian.git $ cd debian/ $ git clone git://git.umip.org/racoon/patches.git $ cd ..
When dpkg-buildpackage is called (see below), quilt takes care (as asked in the Debian "rule" file in the debian/ folder) of applying the patches from the debian/patches/ directory. Before issuing the following command, please verify that:
- You are running the patched kernel with MIGRATEv2 support we compiled and you have kernel headers installed (in /lib/modules/2.6.29.5/build/include/ for our 2.6.29.5 kernel).
- Your environment satisfies the build dependencies (look at the control file in the debian/ folder)
$ dpkg-buildpackage -us -uc -sd -b -i -I.git
...
dh_builddeb
dpkg-deb --build debian/ipsec-tools-umip ..
dpkg-deb: building package `ipsec-tools-umip' in `../ipsec-tools-umip_0.7-17_i386.deb'.
dpkg-deb --build debian/racoon-umip ..
dpkg-deb: building package `racoon-umip' in `../racoon-umip_0.7-17_i386.deb'.
# we have no indep packages
# we have no architecture independant stuff yet
dpkg-genchanges -b -sd >../ipsec-tools-umip_0.7-17_i386.changes
dpkg-genchanges: binary-only upload - not including any source code
dpkg-buildpackage: binary only upload (no source included)
You can then install the packages:
$ sudo dpkg -i ../ipsec-tools-umip_0.7-17_i386.deb $ sudo dpkg -i ../racoon-umip_0.7-17_i386.deb
As an alternative, you can also use our UMIP Debian repository that includes the racoon-umip and ipsec-tools-umip packages.
Racoon configuration is described in the next section.
UMIP and Racoon Configuration
The testbed topology is exactly the same as the one exposed in the static IPsec keying Mobile IPv6 documentation. It is thus preferable that you already have a working Mobile IPv6 testbed before going any further. We will cover here the changes required to use dynamic keying (instead of static keying) on the HA first, then on the MN.
To avoid spending hours at debugging stupid issues, you should definitely get familiar with racoon and UMIP configuration in general (reading the man pages, setting up simple configuration of UMIP without dynamic keying, and simple configuration of racoon without mobility).
Configuring the Home Agent
In this subsection, we cover the configuration of the HA: first the UMIP part, and then the IPsec/IKE related part.
UMIP configuration
Here is a modified UMIP Home Agent configuration with dynamic keying. Changes made in the file are marked with DYNAMIC KEYING. Modify your /usr/local/etc/mip6d.conf file accordingly.
# Sample UMIP configuration file for a MIPv6 Home Agent
NodeConfig HA;
# Set DebugLevel to 0 if you do not want debug messages
DebugLevel 10;
# Replace eth0 with the interface connected to the home link
Interface "eth0";
# Binding information
BindingAclPolicy 2001:db8:ffff:0::1 allow;
DefaultBindingAclPolicy deny;
# Enable IPsec static keying
UseMnHaIPsec enabled;
KeyMngMobCapability enabled; ## DYNAMIC KEYING ##
# IPsec Security Policies information
IPsecPolicySet {
HomeAgentAddress 2001:db8:ffff:0::1000
HomeAddress 2001:db8:ffff:0::1/64;
IPsecPolicy Mh UseESP; ## DYNAMIC KEYING ##
IPsecPolicy TunnelPayload UseESP; ## DYNAMIC KEYING ##
}
The KeyMngMobCapability parameter is set to enabled. It allows to set the K bit in Binding Acknowledgments sent to the peer, indicating that our IKE daemon support movement (i.e. is able to update its Security Aassociations and Security Policies on movement). In practice though, the value is not considered in the UMIP code. The IPsecPolicy parameters have also been updated: we have removed the last arguments.
Similarly as the static keying configuration, we simply ask for IPsec protection using ESP for signaling traffic between the MN and the HA, i.e. traffic using Mobility Header (IPsecPolicy Mh UseESP;), and for data traffic tunneled between the MN and the HA (IPsecPolicy TunnelPayload UseESP;) Those rules cover all traffic (data and MIPv6 signaling) between the MN and the HA.
UMIP will use the configuration information to setup a set of specific IPsec Security Policies for the two rules, which will require SA to be present or negotiated in order for associated traffic to flow. In our setup, the negotiation of the SA is performed dynamically by the IKE daemon (racoon). UMIP will also send locally the required messages (MIGRATE) to the IPsec stack and the IKE daemon upon movement.
Without entering the details of the implementation, UMIP sends MIGRATE messages using Netlink so that they get processed by XFRM framework in the kernel (update of Security Policies / Security Associations). XFRM then handles the emission of the MIGRATE messages to the registered key managers, no matter if they use PF_KEY or Netlink. For racoon, PF_KEY is used.
Racoon configuration
Now that UMIP configuration has been performed, the HA still lacks the Security Associations to protect the flows referenced by the Security Policies we have required. We delegate that job to racoon, both on the HA and the MN. We will thus not need to write any IPsec SA configuration by ourselves (contrary to the static keying testbed). Below, we cover the HA part.
The racoon configuration is composed of a main file and specific configuration files for every user, which are included in the main configuration. On the HA, the main configuration file (/etc/racoon/racoon.conf) looks like this:
path certificate "/etc/racoon/certs/";
path script "/etc/racoon/scripts";
path backupsa "/var/log/racoon_sa_dump.log";
#log debug2;
#privsep {} will be seen later.
timer {
# All timers are set to their default values.
counter 5;
interval 10 secs;
persend 1;
phase1 30 secs;
phase2 20 secs;
#natt_keepalive 20 secs;
}
listen {
}
gss_id_enc utf-16le ;
remote anonymous {
exchange_mode main;
doi ipsec_doi;
situation identity_only;
my_identifier asn1dn ;
peers_identifier asn1dn "C=FR, ST=FRANCE, O=NATISBAD, \
OU=IPsec Services, CN=*, emailAddress=*";
verify_identifier on;
certificate_type x509 "ha.crt" "ha.key";
ca_type x509 "ca_ipsec-crt.pem";
verify_cert on;
lifetime time 24 hour;
ike_frag on;
# esp_frag fraglen;
initial_contact on;
passive on;
proposal_check obey;
support_proxy on;
nonce_size 16;
proposal {
encryption_algorithm aes; # only for Oakley
hash_algorithm sha1;
authentication_method rsasig;
dh_group modp2048;
lifetime time 4 hours ;
}
}
padding {
randomize off;
randomize_length on ; # set it in the future
maximum_length 20 ; # set it in the future
exclusive_tail off ;
strict_check off;
}
include "/etc/racoon/racoon.conf.d/one.user.racoon.conf";
#include "/etc/racoon/racoon.conf.d/another.user.conf";
Our purpose is not to document racoon configuration from scratch but comment the differences and important points required for things to work correctly in a Mobile IPv6 context.
The path parameters reflects the folder where the certificates and keys are stored. We do not use scripts in our setup.
Privilege separation (privsep) is not configured/enabled because we did not take the time to test it yet.
We have some common values for timers. You should be able to change them to fit your needs afterwhile.
Because we have multiple interfaces on the HA, we simply let racoon bind on all interfaces.
For handling our MN and negotiate Phase 1 with the remote peers that use unknown CoA, we use an anonymous remote section. During the setup of this ISAKMP SA, the HA will send the DN of its certificate as ID (configuration of our MNs expect that as we will see later). In the end, the first set of important parameters are the following:
remote anonymous {
...
my_identifier asn1dn ;
peers_identifier asn1dn "C=FR, ST=FRANCE, O=NATISBAD, \
OU=IPsec Services, CN=*, emailAddress=*";
verify_identifier on;
certificate_type x509 "ha.crt" "ha.key";
ca_type x509 "ca_ipsec-crt.pem";
verify_cert on;
...
}
The HA will use the DN of its certificate (provided with its key by certificate_type x509 ... parameter) because it is told to do so by my_identifier asn1dn ...; option. Verification of peer certificate will occur (because verify_cert is enabled) using the X.509 anchor pointed by ca_type x509 ... parameter.
Additionally, to filter the peers on the ID they present during Phase 1, verify_identifier is enabled and a string with wildcard is provided using peers_identifier asn1dn ...;. If you intend to do that to, please test your setup first without verify_identifier enabled and then activate it to avoid stacking multiple issues: racoon is quite touchy with that option.
In the rest of the configuration, among important parameters, passive should be enabled on the HA, the beginning of the negotiation been done by the MN.
support_proxy must be enabled to allow the peer to negotiate SA for addresses different than the one it perform the negotiation with. MIPv6 bootstrapping process with IKE requires that (CoA is used to negotiate SA for the HoA).
There is no specific comment for our proposal: we use the same set of parameters for all nodes (AES 128, SHA1 with a 2048 bits DH group).
There are some parameters of remote section that are not listed here but deserve some comments. For instance, we expect generate_policy to be deactivated, which is done by default. DPD monitoring is deactivated (advertised but not used), which is what we want to avoid temporary deconnections to make SA timeout.
The next block deals with padding options. Just select the values you want and simply make sure that compatible value are configured on the peers.
We now cover the user-specific configuration files associated with every MN. They are all included using the include parameter. For example, our MN will use the following /etc/racoon/racoon.conf.d/one.user.racoon.conf file:
sainfo address 2001:db8:ffff:0::1000[0] 135
address 2001:db8:ffff:0::1[0] 135
from asn1dn "C=FR, ST=FRANCE, O=NATISBAD, OU=IPsec Services, \
CN=arno, emailAddress=arno@natisbad.org"
{
pfs_group modp2048;
lifetime time 4 hours;
encryption_algorithm aes 128;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
}
sainfo subnet ::/0[0] 0
address 2001:db8:ffff:0::1[0] 0
from asn1dn "C=FR, ST=FRANCE, O=NATISBAD, OU=IPsec Services, \
CN=arno, emailAddress=arno@natisbad.org"
{
pfs_group modp2048;
lifetime time 4 hours;
encryption_algorithm aes 128;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
}
As you can see (if you are already familiar with racoon configuration), the amount of per-user configuration is very limited. The two sainfo blocks respectively protect:
- MH traffic: this SA is for protocol 135 (MH traffic) and all MH types (the 0 between brackets). The first address is the address of the HA (reference in mip6d.conf file) and the second is the HoA of the MN.
- data traffic: this SA is for all traffic (note the subnet ::/0[0] 0, indicating all IPv6 traffic, no matter the next header type and possibly subtype) to the HoA of the MN.
Both SA are specifically matched against the ID presented (verified during Phase 1) due to the from asn1dn parameters which creates the binding required by RFC 3775 and RFC 3776 between the identity of the MN (its certificate, here) and the HoA.
Other configurations
Other configurations (Router Advertisments, IPv6 forwarding, daemon starting) should be done as explained in the static IPsec keying Mobile IPv6 documentation. Note that setkey should not be executed: you should set the following parameter into the /etc/default/setkey file:
RUN_SETKEY=no
Also, note that racoon must be started before mip6d. Make sure your init.d scripts are called in the correct order (first racoon, then mip6d). You can start racoon manually with:
# /etc/init.d/racoon start
Configuring the Mobile Node
Now that the configuration of the HA has been covered in the previous section, we deal here with the configuration of the MN. We will first cover the UMIP part, and then the IPsec/IKE related part.
UMIP configuration
Here is a modified UMIP Mobile Node configuration with dynamic keying. Changes made in the file are marked with DYNAMIC KEYING. Modify your /usr/local/etc/mip6d.conf file accordingly.
# Sample UMIP configuration file for a MIPv6 Mobile Node
NodeConfig MN;
# Set DebugLevel to 0 if you do not want debug messages
DebugLevel 10;
# Enable the optimistic handovers
OptimisticHandoff enabled;
# Disable RO with other MNs (it is not compatible
# with IPsec Tunnel Payload)
DoRouteOptimizationMN disabled;
# The Binding Lifetime (in sec.)
MnMaxHaBindingLife 60;
# List here the interfaces that you will use
# on your mobile node. The available one with
# the smallest preference number will be used.
Interface "eth0" {
MnIfPreference 1;
}
Interface "wlan0" {
MnIfPreference 2;
}
# Replace eth0 with one of your interface used on
# your mobile node
MnHomeLink "eth0" {
HomeAgentAddress 2001:db8:ffff:0::1000;
HomeAddress 2001:db8:ffff:0::1/64;
}
# Enable IPsec static keying
UseMnHaIPsec enabled;
KeyMngMobCapability enabled; ## DYNAMIC KEYING ##
# IPsec Security Policies information
IPsecPolicySet {
HomeAgentAddress 2001:db8:ffff:0::1000;
HomeAddress 2001:db8:ffff:0::1/64 ;
IPsecPolicy Mh UseESP; ## DYNAMIC KEYING ##
IPsecPolicy TunnelPayload UseESP; ## DYNAMIC KEYING ##
}
The changes operated on the MN configuration file are the same as the one we did on the HA configuration. The other parameters keep the same values as for the static keying testbed.
Racoon configuration
Let's now take a look at the MN's /etc/racoon/racoon.conf file and comment the differences with the previously studied HA's racoon configuration file. Note that we do not have a split version of the configuration on the MN, i.e. sainfo { ... } blocks are in the main file.
path certificate "/etc/racoon/certs/";
path script "/etc/racoon/scripts";
path backupsa "/var/log/racoon_sa_dump.log";
gss_id_enc utf-16le ;
timer {
# All timers are set to their default values.
counter 5;
interval 5 secs;
persend 1;
phase1 300 secs;
phase2 600 secs;
#natt_keepalive 20 secs;
}
listen {
}
remote 2001:db8:ffff:0::1000
{
exchange_mode main;
doi ipsec_doi;
situation identity_only;
my_identifier asn1dn ;
peers_identifier asn1dn "C=FR, ST=FRANCE, O=NATISBAD, OU=IPsec Services, \
CN=ha1, emailAddress=arno@natisbad.org";
certificate_type x509 "arno-crt.pem" "arno.key";
ca_type x509 "ca_ipsec-crt.pem";
verify_identifier on;
verify_cert on;
lifetime time 24 hour;
ike_frag on;
initial_contact on;
passive off;
proposal_check obey;
support_proxy on;
generate_policy off;
nonce_size 16;
proposal {
encryption_algorithm aes ;
hash_algorithm sha1;
authentication_method rsasig;
dh_group modp2048;
lifetime time 4 hours ;
}
}
sainfo address 2001:db8:ffff:0::1[0] 135
address 2001:db8:ffff:0::1000[0] 135
from asn1dn "C=FR, ST=FRANCE, O=NATISBAD, OU=IPsec Services, \
CN=ha1, emailAddress=arno@natisbad.org";
{
pfs_group modp2048;
lifetime time 2 hours;
encryption_algorithm aes 128;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
}
sainfo address 2001:db8:ffff:0::1[0] 0
subnet ::/0[0] 0
from asn1dn "C=FR, ST=FRANCE, O=NATISBAD, OU=IPsec Services, \
CN=ha1, emailAddress=arno@natisbad.org";
{
pfs_group modp2048;
lifetime time 2 hours;
encryption_algorithm aes 128;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
}
padding {
randomize off;
randomize_length on;
maximum_length 20;
exclusive_tail off;
strict_check off;
}
The first difference is that the remote block is no more anonymous. The address of MN's HA is provided (2001:db8:ffff:0::1000). In that block, the peer_identifier that the MN should provide as ID during Phase 1 is set in an unambiguous fashion, without a wildcard for the CN RDN ("ha1" is expected here). Like it was required on the HA, the ID presented during Phase 1 will be checked against the subject's DN of the peers certificate (verify_identifier being enabled).
Still in remote block, the passive parameter is set to off this time in order to have racoon initiate a negotiation with the IKE daemon on its HA when a packet matching a SP previously configured on the system (by UMIP) has triggered a PF_KEY ACQUIRE message by the kernel.
Then, in the rest of the configuration, the only thing you might be interested in checking is that the address of sainfo blocks are in the correct (reversed) order, when compared to their counterpart in HA configuration file
Other configurations
Similarly to the Home Agent, other configurations for the MN should be done as explained in the static IPsec keying Mobile IPv6 documentation. Note that setkey should not be executed: you should set the following parameter into the /etc/default/setkey file:
RUN_SETKEY=no
Also, note that racoon must be started before mip6d. Make sure your init.d scripts are called in the correct order (first racoon, then mip6d). You can start racoon manually with:
# /etc/init.d/racoon start
NEMO Basic Support and Dynamic Keying
You may also be interested in using dynamic keying between your Mobile Router and your Home Agent. This is pretty straigthforward: simply follow the NEMO Basic Support documentation. Nothing more is needed on the racoon side! The reason is that the tunnel mode SA racoon will negotiate are suitable for handling the protection of tunneled traffic by default. The Security Policies that UMIP will put for the prefixes will do the rest of the magic.
Changelog
- 2013/03/21: Fixed typos and added info on how to disable setkey.
- 2011/03/19: Switch all remaining hg repos to git.
- 2010/10/05: The migrate patch is now merged in the umip.git tree.
- 2010/02/15: First version of this document.