BSD daemon

NetBSD Documentation:

NetBSD IPsec

This page is developing, and we welcome any comments or suggestions.

IPsec FAQ

Other links


IPsec FAQ


Getting Started (top)

IPsec (IP security protocol) is part of the NetBSD distributions, it provides per-packet authenticity/confidentiality guarantees between peers communicate using IPsec. IPsec is available for both IPv6 and IPv4.

Note that, however, kernel re-configuration is necessary to use IPsec. It is not turned on for default GENERIC kernel.

Userland code includes IPsec support where possible, by default, so no rebuild of userland is necessary even if you switch between kernel with IPsec, and without IPsec.

NOTE: We sometimes use the word "IP security" in more broader sense, like IP firewalls, packet filtering, and so forth.

IPsec = AH + ESP + IPcomp + IKE (top)

IPsec consists of a couple of separate protocols, listed below: AH, ESP and IPcomp are implemented in the kernel code. IKE is implemented as daemon process in the userland. Kernel part and userland part will cooperate by using key management table in between.

IKE is actually optional, you can configure secret keys manually for AH/ESP. However, please understand it: you cannot use the same secret key forever. If you use the same secret key for a long period of time, your traffic become more and more likely to get compromised.

NOTE: security of IPsec protocols depend on the secrecy of secret keys. If secret keys are compromised, IPsec protocols can no longer be secure. Take caution about permission mode of configuration files, key database files, or whatever thay may lead to information leakage.

There two set of RFCs published; old IPsec suite starts from RFC1825, and new IPsec suite starts from RFC2401. Though NetBSD implements both, it is recommended to use new IPsec suite.


        userland programs               IKE daemon
          ^ | AF_INET{,6} socket          ^ | PF_KEY socket
========= | | =========================== | | ======== Kernel/user boundary
          | v                             | v
        transport layer, TCP/UDP        key management table
          ^ |                             ^ | key information
          | |                             | |
          | v                             | v
        IP input/output logic <-------> AH/ESP/IPcomp logic
          ^ |
          | v
        Network drivers (ethernet)

Transport mode and tunnel mode (top)

AH, ESP and IPcomp have two modes of operation: transport mode and tunnel mode. Transport mode encrypts normal communication between peers. Tunnel mode will encapsulate packet into new IPv4/v6 header. Tunnel mode is designed to be used by VPN gateways.
[[transport mode]]
my host ======== peer's host
	transport
	mode

packets: [IP: me->peer] ESP payload
			<---------> encrypted


[[tunnel mode]]
	(a)		     (b)			(c)
my host ---- my VPN gateway ======== peer's VPN gateway ---- peer's host
			    tunnel mode

packets on (a): [IP: me->peer] payload
packets on (b): [IP: mygw->peergw] ESP [IP: me->peer] payload
			  	   <------------------------> encrypted
packets on (c): [IP: me->peer] payload

IPsec "policy" management (top)

Though the kernel knows how to secure packets, it does not know which packet requires security. We need to tell kernel about which packet needs to be secured. IPsec "policy" configuration allows us to specify it.

IPsec policy can be configured in per-packet, or per-socket manner:

IPsec policy decides which IPsec protocols (AH, ESP or IPcomp) to be used against a packet. You can configure kernel to use any combination of AH, ESP and IPcomp against a packet. You can even apply same protocol multiple times, like multiple ESP operation against single packet. It is questionable if multiple ESP operation has any benefit, but certainly interesting for test/debug use.

Configuring IPsec kernel (top)

Refer to tracking NetBSD-current for more details of the build process.
  1. In your kernel configuration file, enable the following portion and build a new kernel.
    options IPSEC
    options IPSEC_ESP
    
  2. Build a new kernel as usual.
  3. Replace the kernel and reboot.

Userland tools include IPsec support by default, and no userland rebuild is necessary.

Additionally, you may want to use racoon(8), which comes with NetBSD or install isakmpd.

Configuration examples: host-to-host encryption (top)

If you would like to run host-to-host (transport mode) encryption with manually configured secret keys, the following configuration should be enough. We use setkey(8) to configure the manual keys.
#! /bin/sh
#
# packet will look like this: IPv4 ESP payload
# the node is on 10.1.1.1, peer is on 20.1.1.1
setkey -c <<EOF
add 10.1.1.1 20.1.1.1 esp 9876 -E 3des-cbc "hogehogehogehogehogehoge";
add 20.1.1.1 10.1.1.1 esp 10000 -E 3des-cbc 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef;
spdadd 10.1.1.1 20.1.1.1 any -P out ipsec esp/transport//use;
EOF

The first two lines configure secret keys to be used by ESP. The decimal numbers that appear as the fourth word are called SPI (security parameter index). The value will be attached to ESP packet, and it lets the receiving side lookup the secret key from the packet. The number needs to be unique for a node.

The last line configures per-packet IPsec policy for the node. With the configuration, the node (10.1.1.1) to transmit packets to the peer (20.1.1.1) encrypted, whenever secret key is configured into the kernel. The configuration does not prohibit unencrypted packets from 20.1.1.1 to reach 10.1.1.1. If you would like to reject unencrypted packet, add the following line:

spdadd 20.1.1.1 10.1.1.1 any -P in ipsec esp/transport//require;

On the other end (20.1.1.1), the configuration will be like this. Note that the addresses need to be swapped on the "spdadd" line, but not the "add" lines.

#! /bin/sh
#
# packet will look like this: IPv4 ESP payload
# the node is on 20.1.1.1, peer is on 10.1.1.1
setkey -c <<EOF
add 10.1.1.1 20.1.1.1 esp 9876 -E 3des-cbc "hogehogehogehogehogehoge";
add 20.1.1.1 10.1.1.1 esp 10000 -E 3des-cbc 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef;
spdadd 20.1.1.1 10.1.1.1 any -P out ipsec esp/transport//use;
EOF

The syntax for policy configuration is documented in ipsec_set_policy(3).

Try running tcpdump(8) to see the encrypted packets on the wire - they are encrypted, it is no longer possible to wiretap those packets.

The above example uses human-readable secret keys. However, use of human-readable secret key is discouraged by the specification (since it will have more chance to be compromised, than binary keys). You'd better use binary keys for real operation.

Key length is determined by algorithms. For 3des-cbc, the secret key MUST be 192 bits (= 24 bytes). If you specify shorter/longer key, you will get error from setkey(8).

If you wish to use other algorithms, the configuration is very similar. Here's an example with rijndael-cbc (also known as AES). rijndael-cbc takes 128, 192 or 256 bits of secret keys. Here we use 128bit keys.

#! /bin/sh
#
# packet will look like this: IPv4 ESP payload
# the node is on 10.1.1.1, peer is on 20.1.1.1
# rijndael-cbc with 128bit key
setkey -c <<EOF
add 10.1.1.1 20.1.1.1 esp 9876 -E rijndael-cbc "hogehogehogehoge";
add 20.1.1.1 10.1.1.1 esp 10000 -E rijndael-cbc 0xdeadbeefdeadbeefdeadbeefdeadbeef;
spdadd 10.1.1.1 20.1.1.1 any -P out ipsec esp/transport//use;
EOF

Configuration examples: host-to-host authentication (top)

Just like ESP, you can configure AH.
#! /bin/sh
#
# packet will look like this: IPv4 AH payload
# the node is on 10.1.1.1, peer is on 20.1.1.1
setkey -c <<EOF
add 10.1.1.1 20.1.1.1 ah 9877 -A hmac-md5 "hogehogehogehoge";
add 20.1.1.1 10.1.1.1 ah 10001 -A hmac-md5 "mogamogamogamoga";
spdadd 10.1.1.1 20.1.1.1 any -P out ipsec ah/transport//use;
EOF

Configuration examples: host-to-host encryption+authentication (top)

If you configure secret keys for both AH and ESP, you can use both of them. IPsec document suggests to apply AH after ESP.
#! /bin/sh
#
# packet will look like this: IPv4 AH ESP payload
# the node is on 10.1.1.1, peer is on 20.1.1.1
setkey -c <<EOF
add 10.1.1.1 20.1.1.1 esp 9876 -E 3des-cbc "hogehogehogehogehogehoge";
add 20.1.1.1 10.1.1.1 esp 10000 -E 3des-cbc 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef;
add 10.1.1.1 20.1.1.1 ah 9877 -A hmac-md5 "hogehogehogehoge";
add 20.1.1.1 10.1.1.1 ah 10001 -A hmac-md5 "mogamogamogamoga";
spdadd 10.1.1.1 20.1.1.1 any -P out ipsec esp/transport//use ah/transport//use;
EOF

Configuration examples: IPsec VPN (top)

First of all, here are couple of issues with IPsec VPN configuration.

The following example assumes the following network configuration. The goals of the example are:

((( 10.0.1.0/24 )))	VPN'ed network, Tokyo branch office
  |10.0.1.1
gateway 1
  |20.0.0.1
  |IPsec tunnel
  |20.0.0.2
gateway 2
  |10.0.2.1
((( 10.0.2.0/24 )))	VPN'ed network, NY headquarters

The following text presents configuration for gateway 1.

#! /bin/sh
#
# Note that routing should be set up in advance, i.e. for this example:
#	route -n add -net 10.0.2.0 10.0.2.1
#	route -n add 10.0.2.1 10.0.1.1
# packet will look like this: IPv4 ESP IPv4 payload
# the node is on 10.0.1.1/20.0.0.1, peer is on 10.0.2.1/20.0.0.2
setkey -c <<EOF
add 20.0.0.1 20.0.0.2 esp 13245 -E blowfish-cbc "blowfishtest.001" ;
add 20.0.0.2 20.0.0.1 esp 13246 -E blowfish-cbc 0xdeadbeefdeadbeefdeadbeefdeadbeef;
spdadd 10.0.1.0/24 10.0.2.0/24 any -P out ipsec esp/tunnel/20.0.0.1-20.0.0.2/require ;
spdadd 10.0.2.0/24 10.0.1.0/24 any -P in ipsec esp/tunnel/20.0.0.2-20.0.0.1/require ;
EOF

(contributed by Per Harald Myrvang)

Configuration examples: Leaf-node tunnel (top)

Tunnel mode can be used in situations where all traffic from a given leaf node is to be encrypted to the next-hop router, and unencrypted from there (for example, a wireless node to a router, because 802.11 WEP is inadequate).

For the leaf node, use:

#! /bin/sh
#
# the node is on 10.0.1.5, router is on 10.0.1.1
setkey -c <<EOF
add 10.0.1.1 10.0.1.5 esp 1011 -E rijndael-cbc "rijndaeltest.001" ;
add 10.0.1.5 10.0.1.1 esp 1012 -E rijndael-cbc 0xdeadbeefdeadbeefdeadbeefdeadbeef;
spdadd 10.0.1.5/32 0.0.0.0/0 any -P out ipsec esp/tunnel/10.0.1.5-10.0.1.1/require;
spdadd 0.0.0.0/0 10.0.1.5/32 any -P in ipsec esp/tunnel/10.0.1.1-10.0.1.5/require;
EOF

For the router, swap the 'out' and 'in' keywords on the spdadd commands.

Configuring AH/ESP keys by using IKE (top)

Here we describe the following configuration:

Please follow the steps carefully. Run tcpdump(8) to check how the packets are exchanged between two nodes. Statistics by "netstat -sn" is also useful to know how kernel IPsec portion is working.

  1. Copy /usr/share/examples/racoon/racoon.conf.sample into /etc/racoon/racoon.conf. Modify parameters declared in racoon.conf as necessary. It is VERY critical that both ends use the same configuration - you will want less differences in racoon.conf.
  2. racoon will obey the IPsec policy settings in the kernel when it negotiates IPsec keys. Therefore, we need to configure IPsec policy into the kernel by using setkey(8). On node A, configure IPsec policy like this. In the example, "A" and "B" are IPv4/v6 numeric addresses.
    A# setkey -c
    spdadd A B any -P out ipsec esp/transport//require;
    spdadd B A any -P in ipsec esp/transport//require;
    ^D
    
  3. On node B, configure IPsec policy like this by using setkey(8):
    B# setkey -c
    spdadd B A any -P out ipsec esp/transport//require;
    spdadd A B any -P in ipsec esp/transport//require;
    ^D
    
  4. On both nodes, prepare pre-shared key file. It is VERY critical to set file permission properly, otherwise it worth nothing to use IPsec - it will do nothing other than wasting your CPU time (racoon will not read files with weak permissions). Again "A" and "B" are numeric IPv4/v6 addresses.
    A# cat >/etc/racoon/psk.txt
    B	spamspamspam
    ^D
    A# chmod 600 /etc/racoon/psk.txt
    
    B# cat >/etc/racoon/psk.txt
    A	spamspamspam
    ^D
    B# chmod 600 /etc/racoon/psk.txt
    
  5. Run racoon. If you wish see the debug trace, arguments would be like below:
    # racoon -f /etc/racoon/racoon.conf -d 0xffffffff
    
  6. Try to exchange packet between A and B. You will see some messages from racoon to console, and key will be established.
    A# ping -n B
    (with some delay, you will start seeing replies)
    ^C
    A# setkey -D
    (you will see keys exchanged by racoon)
    
racoon will negotiate keys based on the policy definition. By changing policy definition, we can easily configure for other cases. Next example configure keys for the following situation: If you have any problem in configuring it, be sure to look at full debug logs (racoon -d 0xffffffff) and see where it chokes. Every configuration difference leads to unsuccessful negotiation.

Setting up IPsec manual keys and policies on bootstrap (top)

rc.conf(5) has an entry for IPsec, named "ipsec". ipsec=YES will run the following command at bootstrap time, before any of the network activities:
/sbin/setkey -f /etc/ipsec.conf
For example, you can perform encrypted NFS mount for /usr. /etc/ipsec.conf should contain valid commands to setkey(8); similar to the configuration examples above without the setkey -c <<EOF ... EOF sections.

Interaction with ipfilter (top)

NetBSD implements ipf(4), ipfilter by Darren Reed. ipf(4) filters packets, and IPsec policy processing is inherently similar to packet filter. Therefore, they implement conflicting functionality. ipf(4)/IPsec interaction is specified as: ipf(4) looks at packets in native wire format only. ipf(4) looks at packets before IPsec processing on inbound, and after IPsec processing on outbound.

Even with the processing order, please aware of the following:

The following diagram summarizes new processing order.

inbound processing:
        userland programs               IKE daemon
          ^ AF_INET{,6} socket            ^ | PF_KEY socket
========= | ============================= | | ======== Kernel/user boundary
          |                               | v
        transport layer, TCP/UDP        key management table
          ^                               ^ | key information
          |                               | |
          |                               | v
  +-----IP input/output logic <-------> AH/ESP/IPcomp logic
  v       ^          ^                      |
tunnel    |          +----------------------+ decapsulated IPsec packets
devices   |
  |     ipfilter rules
  |       ^
  +------>|
          |
        Network drivers (ethernet)

outbound processing:
        userland programs               IKE daemon
            | AF_INET{,6} socket          ^ | PF_KEY socket
=========== | =========================== | | ======== Kernel/user boundary
            v                             | v
        transport layer, TCP/UDP        key management table
            |                             ^ | key information
            |                             | |
            v                             | v
  +---->IP input/output logic <-------> AH/ESP/IPcomp logic
  |         |                           (incl. IPsec tunnel encapsulation)
tunnel      |
devices     |
  |     ipfilter rules
  |         |
  +---------+
            v
        Network drivers (ethernet)

Common pitfalls, and debugging techniques (top)

Known issues (top)

Conformance to standard, interoperability (top)

KAME IPsec implementation (which is included in NetBSD tree) conforms to latest set of IPsec standards. KAME's NetBSD Implementation Note has comprehensive list of standard documents to which the implementation conforms.

Interoperability with other implementation has been confirmed in various occasions. KAME's NetBSD Implementation Note includes list of implementations which we have confirmed interoperability in the past. Note that, however, it is possible for both sides to change the code after interoperability tests, and it is possible that they no longer interoperate. It is also possible that NetBSD device and peer's device interoperate in certain configuration only.

If you try to configure NetBSD device with other implementation, please note that IPsec specifications/implementations have too many knobs to play with. You need to configure your NetBSD device with peer's device exactly the same to make them interoperate.

API compatibility with other IPsec stacks (top)

If you write userland code that is aware of IPsec, you may become curious about API compatibility across IPsec platforms.

We have RFC2367 PF_KEY API for manipulating secret key database in the kernel. Basic portion of this API is available on other UNIX-based IPsec stacks as well, and may be compatible to certain degree (for example, OpenBSD implements PF_KEY API as well). KAME IPsec stack extends this in certain way, just like other parties do. Extended portion is not compatible with other (non-KAME) IPsec stacks.

There is no document that specifies IPsec policy management API. Therefore, we can expect no compatibility with (non-KAME) IPsec stacks in IPsec policy management API.

There is no standard for configuration file syntax. You will need to convert them if you would like to copy configuration from/to non-NetBSD IPsec devices.

Since NetBSD and FreeBSD share IPsec codebase from the same origin (KAME), there is a good chance for API compatibility. Note that, however, there are differences in NetBSD IPsec code and FreeBSD IPsec code, since they merged in KAME code of different date. As of writing, normal userland applications do not need to worry about the difference. However, if you plan to implement IPsec key management daemons, you will need to worry about differences in PF_KEY API.

During NetBSD-current development between NetBSD 1.4 to NetBSD 1.5, we have imported KAME IPsec portion three times. Those imports contain backward-incompatible changes in the API. Please make sure to use the latest code, if you are on NetBSD-current between 1.4 and 1.5. with NetBSD 1.5 shipped, we will provide complete binary compatibility, or API version number check, to the API present in NetBSD 1.5.

Books and other reading materials? (top)

There are literally tons of books available.

Up to NetBSD Documentation: Network
Home page
Documentation top level

(Contact us) $NetBSD: index.html,v 1.81 2005/09/28 17:24:21 mishka Exp $
Copyright © 1994-2005 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.
NetBSD® is a registered trademark of The NetBSD Foundation, Inc.