<?xml version="1.0"?>
<!DOCTYPE webpage
 PUBLIC "-//NetBSD//DTD Website-based NetBSD Extension//EN"
        "http://www.NetBSD.org/XML/htdocs/lang/share/xml/website-netbsd.dtd">

<webpage id="docs-network-ipsec-index">
  <config param="desc" value="NetBSD IPsec FAQ"/>
  <config param="cvstag" value="$NetBSD: index.xml,v 1.5 2009/01/15 09:50:23 hubertf Exp $"/>
  <config param="rcsdate" value="$Date: 2009/01/15 09:50:23 $"/>

  <head>
    <!-- Copyright (c) 1994-2006
	The NetBSD Foundation, Inc.  ALL RIGHTS RESERVED. -->

    <title>NetBSD IPsec FAQ</title>
  </head>

  <para>This page is developing, and we welcome any
    <ulink url="http://www.NetBSD.org/cgi-bin/feedback.cgi">comments or suggestions</ulink>.</para>

  <sect1 role="toc">

    <sect2 id="IPsecFAQ">
      <title>IPsec FAQ</title>

      <sect3 id="getting_started">
	<title>Getting Started</title>

	<para>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.</para>

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

	<para>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.</para>

	<note>
	  <para>We sometimes use the word <quote>IP security</quote> in more broader sense,
	    like IP firewalls, packet filtering, and so forth.</para>
	</note>
      </sect3>

      <sect3 id="ipsec_breakdown">
	<title>IPsec = AH + ESP + IPcomp + IKE</title>

	<para>IPsec consists of a couple of separate protocols, listed below:</para>

	<itemizedlist>
	  <listitem>Authentication Header (AH): provides authenticity guarantee for packets,
	    by attaching strong crypto checksum to packets.
	    If you receive a packet with AH and the checksum operation was
	    successful, you can be sure about two things <emphasis>if you and the
	      peer share a secret key, and no other party knows the key</emphasis>:
	    <itemizedlist>
	      <listitem>The packet was originated by the expected peer.
	        The packet was not generated by impersonator.
	      </listitem>

	      <listitem>The packet was not modified in transit.
	      </listitem>
	    </itemizedlist>
	    Unlike other protocols, AH covers the whole packet, from the IP header
	    to the end of the packet.
	  </listitem>

	  <listitem>Encapsulating Security Payload (ESP): provides confidentiality guarantee
	    for packets, by encrypting packets with encryption algorithms.
	    If you receive a packet with ESP and successfully decrypted it,
	    you can be sure that the packet was not wiretapped in the middle,
	    <emphasis>if you and the peer share a secret key, and no other party
	      knows the key</emphasis>.
	  </listitem>

	  <listitem>IP payload compression (IPcomp): ESP provides encryption service to the
	    packets.
	    However, encryption tend to give negative impact to compression on
	    the wire (such as ppp compression).
	    IPcomp provides a way to compress packet before encryption by ESP
	    (Of course, you can use IPcomp alone if you wish to).
	  </listitem>

	  <listitem>Internet Key Exchange (IKE): As noted above, AH and ESP needs shared
	    secret key between peers.
	    For communication between distant location, we need to provide ways
	    to negotiate keys in secrecy.
	    IKE will make it possible.
	  </listitem>
	</itemizedlist>

	<para>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.</para>

	<para>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.</para>

	<note>
	  <para><emphasis role="bold">security of IPsec protocols depend on the secrecy of secret keys.
	    </emphasis>
	    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 they may lead to information leakage.</para>
	</note>

	<para>There two set of RFCs published; old IPsec suite starts from <!--RFC-->RFC1825,
	  and new IPsec suite starts from <!--RFC-->RFC2401.
	  Though NetBSD implements both, it is recommended to use new IPsec suite.</para>

	<programlisting>

        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 &lt;-------&gt; AH/ESP/IPcomp logic
          ^ |
          | v
        Network drivers (ethernet)
</programlisting>
      </sect3>

      <sect3 id="trans_tunnel">
	<title>Transport mode and tunnel mode</title>

	<para>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.</para>

	<programlisting>
[[transport mode]]
my host ======== peer's host
        transport
        mode

packets: [IP: me->peer] ESP payload
                        &lt;---------&gt; 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
                                   &lt;------------------------&gt; encrypted
packets on (c): [IP: me->peer] payload
</programlisting>
      </sect3>

      <sect3 id="policy">
	<title>IPsec <quote>policy</quote> management</title>

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

	<para>IPsec policy can be configured in per-packet, or per-socket manner:</para>

	<itemizedlist>
	  <listitem>Per-packet: configured into the kernel just like packet filters.
	    You can specify like <quote>encrypt outgoing packets if I'm sending
	    to 10.1.1.0/24</quote>.
	    This works well when you are running an IPsec router.
	  </listitem>

	  <listitem>Per-socket: configured via &man.setsockopt.2; for a certain socket.
	    You can specify like <quote>encrypt outgoing packets from this socket</quote>.
	    This works well when you would like to run IPsec-aware server program.
	  </listitem>
	</itemizedlist>

	<para>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.</para>
      </sect3>

      <sect3 id="config_kernel">
	<title>Configuring IPsec kernel</title>

	<para>Refer to <ulink url="../../current/"><emphasis>tracking NetBSD-current</emphasis></ulink>
	  for more details of the build process.</para>

	<orderedlist>
	  <listitem>In your kernel configuration file, enable the following portion
	    and build a new kernel.
	    <programlisting>
options IPSEC
options IPSEC_ESP
</programlisting>
	  </listitem>

	  <listitem>Build a new kernel as usual.
	  </listitem>

	  <listitem>Replace the kernel and reboot.
	  </listitem>
	</orderedlist>

	<para>Userland tools include IPsec support by default,
	  and no userland rebuild is necessary.</para>

	<para>Additionally, you may want to use &man.racoon.8;, which comes with NetBSD or
	  install <filename role="pkg">security/isakmpd</filename>.</para>
      </sect3>

      <sect3 id="sample_esp">
	<title>Configuration examples: host-to-host encryption</title>

	<para>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 &man.setkey.8; to configure the manual keys.</para>

	<programlisting>
#! /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 &lt;&lt;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
</programlisting>

	<para>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.</para>

	<itemizedlist>
	  <listitem>From 10.1.1.1 to 20.1.1.1, we'd use the 3DES-CBC algorithm,
	    with secret key <code>"hogehogehogehogehogehoge"</code>.
	    The traffic will be identified by SPI 9876.
	  </listitem>

	  <listitem>From 20.1.1.1 to 10.1.1.1, we'd use 3DES-CBC algorithm,
	    with secret key <code>0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef</code>.
	  </listitem>
	</itemizedlist>

	<para>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:</para>

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

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

	<programlisting>
#! /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 &lt;&lt;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
</programlisting>

	<para>The syntax for policy configuration is documented in &man.ipsec.set.policy.3;.</para>

	<para>Try running &man.tcpdump.8; to see the encrypted packets on the wire -
	  they are encrypted, it is no longer possible to wiretap those packets.</para>

	<para>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.</para>

	<para>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 &man.setkey.8;.</para>

	<para>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.</para>

	<programlisting>
#! /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 &lt;&lt;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
</programlisting>
      </sect3>

      <sect3 id="sample_ah">
	<title>Configuration examples: host-to-host authentication</title>

	<para>Just like ESP, you can configure AH.</para>

	<programlisting>
#! /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 &lt;&lt;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
</programlisting>
      </sect3>

      <sect3 id="sample_both">
	<title>Configuration examples: host-to-host encryption+authentication</title>

	<para>If you configure secret keys for both AH and ESP, you can use both of them.
	  IPsec document suggests to apply AH after ESP.</para>

	<programlisting>
#! /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 &lt;&lt;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
</programlisting>
      </sect3>

      <sect3 id="sample_vpn">
	<title>Configuration examples: IPsec VPN</title>

	<para>First of all, here are couple of issues with IPsec VPN configuration.</para>

	<itemizedlist>
	  <listitem>Routing setup must be done properly.
	  </listitem>

	  <listitem>Do not try to use IPsec tunnel device to behave as the NAT box,
	    or filtering firewall, at the same time.
	    IPsec and NAT are inherently not compatible protocol.
	    Also, due to implementation and specification limitations in 1.5,
	    they do not play nice.
	    We are trying to improve this situation.
	    See <ulink url="#ipf-interaction">"Interaction with ipfilter"</ulink>
	    for more details.
	  </listitem>

	  <listitem>VPN configuration differs from installations to installations.
	    Actually, there's no clear definition of what <quote>VPN</quote> means.
	    If you make questions on mailing lists, you need to clarify your need,
	    your current situation and your network configuration as a whole.
	  </listitem>
	</itemizedlist>

	<para>The following example assumes the following network configuration.
	  The goals of the example are:</para>

	<itemizedlist>
	  <listitem>To somehow connect machines inside two private-address cloud
	    (10.0.1.0/24 and 10.0.2.0/24, think of it as Tokyo branch of your company
	    and NY headquarters).
	  </listitem>

	  <listitem>The traffic between two cloud needs to be securely exchanged between
	    the gateways.
	  </listitem>

	  <listitem>We do not want to pay transpacific leased line charge, so we locally
	    contract with ISP (in Tokyo and in NY) and tunnel traffic between gateways.
	  </listitem>
	</itemizedlist>

	<programlisting>
((( 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
</programlisting>

	<para>The following text presents configuration for gateway 1.</para>

	<programlisting>
#! /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 &lt;&lt;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
</programlisting>

	<para>(contributed by Per Harald Myrvang)</para>
      </sect3>

      <sect3 id="sample_leaftunnel">
	<title>Configuration examples: Leaf-node tunnel</title>

	<para>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).</para>

	<para>For the leaf node, use:</para>

	<programlisting>
#! /bin/sh
#
# the node is on 10.0.1.5, router is on 10.0.1.1
setkey -c &lt;&lt;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
</programlisting>

	<para>For the router, swap the <quote>out</quote> and <quote>in</quote> keywords on the spdadd
	  commands.</para>
      </sect3>

      <sect3 id="config_ike">
	<title>Configuring AH/ESP keys by using IKE</title>

	<para>Here we describe the following configuration:</para>

	<itemizedlist>
	  <listitem>Node A and B will use transport-mode ESP.
	  </listitem>

	  <listitem>It is required for both ends to use ESP to exchange packets, for all
	    protocols.
	  </listitem>

	  <listitem>During IKE, node A and B authenticate each other by using shared secret
	    exchange.
	  </listitem>
	</itemizedlist>

	<para>Please follow the steps carefully.
	  Run &man.tcpdump.8; to check how the packets are exchanged between two nodes.
	  Statistics by <quote><code>netstat -sn</code></quote>
	  is also useful to know how kernel IPsec portion is working.</para>

	<orderedlist>
	  <listitem>Copy <code>/usr/share/examples/racoon/racoon.conf.sample</code> into
	    <code>/etc/racoon/racoon.conf</code>.
	    Modify parameters declared in <code>racoon.conf</code> as necessary.
	    It is VERY critical that both ends use the same configuration -
	    you will want less differences in racoon.conf.
	  </listitem>

	  <listitem> 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
	    &man.setkey.8;.
	    On node A, configure IPsec policy like this.
	    In the example, <quote>A</quote> and <quote>B</quote> are IPv4/v6 numeric addresses.
	    <programlisting>
A# setkey -c
spdadd A B any -P out ipsec esp/transport//require;
spdadd B A any -P in ipsec esp/transport//require;
^D
</programlisting>
	  </listitem>

	  <listitem>On node B, configure IPsec policy like this by using &man.setkey.8;:
	    <programlisting>
B# setkey -c
spdadd B A any -P out ipsec esp/transport//require;
spdadd A B any -P in ipsec esp/transport//require;
^D
</programlisting>
	  </listitem>

	  <listitem>On both nodes, prepare pre-shared key file.
	    It is <emphasis role="bold">VERY</emphasis> critical to set file permission properly,
	    otherwise it worth nothing to use IPsec - it will do nothing other than
	    wasting your CPU time
	    (&man.racoon.8; will not read files with weak permissions).
	    Again <quote>A</quote> and <quote>B</quote> are numeric IPv4/v6 addresses.
	    <programlisting>
A# cat &gt;/etc/racoon/psk.txt
B       spamspamspam
^D
A# chmod 600 /etc/racoon/psk.txt

B# cat &gt;/etc/racoon/psk.txt
A       spamspamspam
^D
B# chmod 600 /etc/racoon/psk.txt
</programlisting>
	  </listitem>

	  <listitem>Run <code>racoon</code>.
	    If you wish see the debug trace, arguments would be like below:
	    <programlisting>
# racoon -f /etc/racoon/racoon.conf -dddddd
</programlisting>
	  </listitem>

	  <listitem>Try to exchange packet between A and B.
	    You will see some messages from racoon to console,
	    and key will be established.
	    <programlisting>
A# ping -n B
(with some delay, you will start seeing replies)
^C
A# setkey -D
(you will see keys exchanged by racoon)
</programlisting>
	  </listitem>
	</orderedlist>

	<para>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:</para>

	<itemizedlist>
	  <listitem>A is a mail server.
	    A wishes to enforce the use of transport mode AH, to everyone contacts
	    A with POP protocol (TCP port 110).
	    B is a client which wishes to contact A.
	    <orderedlist>
	      <listitem>The policy configuration on A avoids of AH for local
	        traffic (note that racoon cannot negotiate keys with itself).
	        The order of the policy is highly important.
	        If you reorder them, the configuration will not work.
	        <programlisting>
A# setkey -c
spdadd A[110] A tcp -P out none;
spdadd A A[110] tcp -P in none;
spdadd A[110] 0.0.0.0/0 tcp -P out ipsec ah/transport//require;
spdadd 0.0.0.0/0 A[110] tcp -P in ipsec ah/transport//require;
^D

B# setkey -c
spdadd B A[110] tcp -P out ipsec ah/transport//require;
spdadd A[110] B tcp -P in ipsec ah/transport//require;
^D
</programlisting>
	      </listitem>

	      <listitem>Other than policy configuration part, configure just like the previous
	        example.
	      </listitem>
	    </orderedlist>
	  </listitem>
	</itemizedlist>

	<para>If you have any problem in configuring it, be sure to look at full debug
	  logs (racoon -dddddd) and see where it chokes.
	  Every configuration difference leads to unsuccessful negotiation.</para>
      </sect3>

      <sect3 id="configboot">
	<title>Setting up IPsec manual keys and policies on bootstrap</title>

	<para>&man.rc.conf.5; has an entry for IPsec, named <quote><code>ipsec</code></quote>.
	  <code>ipsec=YES</code> will run the following command at bootstrap time,
	  before any of the network activities:</para>

	<programlisting>
/sbin/setkey -f /etc/ipsec.conf
</programlisting>

	<para>For example, you can perform encrypted NFS mount for /usr.

	  <code>/etc/ipsec.conf</code> should contain valid commands to &man.setkey.8;;
	  similar to the configuration examples above without the
	  <code>setkey -c &lt;&lt;EOF</code> ... <code>EOF</code> sections.</para>
      </sect3>

      <sect3 id="ipf-interaction">
	<title>Interaction with ipfilter</title>

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

	<para>Even with the processing order, please aware of the following:</para>

	<itemizedlist>
	  <listitem>If you want IPsec packets to go through &man.ipf.4;, you should not drop them
	    by &man.ipf.4; rules.
	    You need to let IP packets with relevant protocol number
	    (50 for ESP, 51 for AH) go through.

	    <note>
	      <para>protocol numbers are completely different thing from TCP/UDP port numbers.</para>
	    </note>
	  </listitem>

	  <listitem>Packet came from tunnel devices (&man.gif.4; and &man.ipip.4;) will still
	    go through &man.ipf.4;.
	    You may need to identify these packets by using interface name directive
	    in &man.ipf.conf.5;.
	  </listitem>
	</itemizedlist>
      </sect3>

      <sect3 id="procorder">
	<title>Processing order</title>

	<para>The following diagram summarizes new inbound processing order:</para>

	<programlisting>
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 &lt;-------&gt; AH/ESP/IPcomp logic
  v       ^          ^                      |
tunnel    |          +----------------------+ decapsulated IPsec packets
devices   |
  |     ipfilter rule
  |       ^
  +------>|
          |
        Network drivers (ethernet)
</programlisting>

	<para>The following diagram summarizes new outbound processing order:</para>

	<programlisting>
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 &lt;-------&gt; AH/ESP/IPcomp logic
  |         |                           (incl. IPsec tunnel encapsulation)
tunnel      |
devices     |
  |     ipfilter rules
  |         |
  +---------+
            v
        Network drivers (ethernet)
</programlisting>
      </sect3>

      <sect3 id="pitfalls">
	<title>Common pitfalls, and debugging techniques</title>

	<itemizedlist>
	  <listitem>Some people mix up the following three items.
	    Take caution if you try to interoperate with other implementations.
	    If you mix them up, you will never be able to make a interoperable
	    configuration.
	    Documentations may be using different words for them (sigh).
	    <itemizedlist>
	      <listitem><emphasis role="bold">IPsec with manual key</emphasis><html:br/>
	        In NetBSD case, this way uses &man.setkey.8; to configure IPsec
	        secret key.
	        IPsec secret key will not change over time.
	      </listitem>

	      <listitem><emphasis role="bold">IPsec with IKE, with pre-shared secret</emphasis><html:br/>
	        In NetBSD case, this uses &man.racoon.8;.
	        We authenticate peer with pre-shared secret.
	        &man.racoon.8; will negotiate IPsec keys dynamically
	        and installs it into the kernel.
	        IPsec secret key changes over time.
	      </listitem>

	      <listitem><emphasis role="bold">IPsec with IKE, with certificates</emphasis><html:br/>
	        In NetBSD case, this uses &man.racoon.8;.
	        We authenticate peer with certificate files.
	        &man.racoon.8; will negotiate IPsec keys dynamically
	        and installs it into the kernel.
	        IPsec secret key changes over time.
	      </listitem>
	    </itemizedlist>
	  </listitem>

	  <listitem>The configuration of IPsec is NOT EASY.
	    There are way too many knobs to play with, and debugging is very hard
	    due to wiretap-resistant nature of IPsec.  Basically, we can't guess
	    what is going on from packet trace.
	    Try reading some books and standard documents/RFCs, hire consultants
	    or whatever, before you try to configure it.
	  </listitem>

	  <listitem>Always run tcpdump while you debug the network.
	    Even though the traffic is encrypted, you can get some idea if the
	    packet is really on the wire or not.
	  </listitem>

	  <listitem>&man.netstat.1; is your friend.
	    Run <code>netstat -sn</code> and check the IPsec packet counters.
	  </listitem>

	  <listitem>If you have trouble running &man.racoon.8;, try running
	    it with maximum debugging output and look at the output.
	    (command line argument <code>-dddddd</code>)
	  </listitem>

	  <listitem>You really really need to configure your NetBSD device with peer's device
	    <emphasis role="bold">exactly the same</emphasis> to make them interoperate.
	    Your packet needs to be generated by using exactly the same protocol,
	    and encryption algorithm, as the other end is expecting.
	    By failing to do so, you will experience very hard-to-track errors.
	    In IPsec, encryption/authentication failures are modelled as packet
	    drops.
	    So configuration failures will make your packets to be dropped onto
	    the floor with no error indications.
	    &man.tcpdump.8; will not help you much,
	    since the content of packet is now not de-cipherable.
	    Make very very sure that you configure carefully with the other end.
	  </listitem>

	  <listitem>On slow machines, you may not be able to negotiate keys with racoon IKE
	    daemon, as IKE negotiation has to finish within net.key.larval_lifetime
	    sysctl MIB, which is 30 seconds by default.
	    Try raising the value if you got a really-slow machines.
	  </listitem>
	</itemizedlist>
      </sect3>

      <sect3 id="issues">
	<title>Known issues</title>

	<itemizedlist>
	  <listitem>Tunnel mode AH does not work as you might expect, due to restrictions
	    in kernel IPsec policy engine.
	    Do not try to use tunnel mode AH.
	  </listitem>

	  <listitem>IPsec and &man.ipf.4; code do not play nicely together.
	    See <ulink url="#ipf-interaction">"Interaction with ipfilter"</ulink>
	    for detail.
	  </listitem>

	  <listitem>IPsec policy rule is not tested enough for explicit protocol
	    specification other than tcp/udp.  Use protocol <quote>any</quote> (= address match
	    only) if you would like to take a safer side.  The issue here is
	    generic to any packet filters - normal packet filter descriptions do
	    not play nicely with header chains.
	  </listitem>
	</itemizedlist>
      </sect3>

      <sect3 id="conformance">
	<title>Conformance to standard, interoperability</title>

	<para>KAME IPsec implementation (which is included in NetBSD tree)
	  conforms to latest set of IPsec standards.
	  <ulink url="http://orange.kame.net/dev/cvsweb.cgi/kame/netbsd/sys/netinet6/IMPLEMENTATION">KAME's
	    NetBSD Implementation Note</ulink>
	  has comprehensive list of standard documents to which the implementation
	  conforms.</para>

	<para>Interoperability with other implementation has been confirmed in various
	  occasions.
	  <ulink url="http://orange.kame.net/dev/cvsweb.cgi/kame/netbsd/sys/netinet6/IMPLEMENTATION">KAME's
	    NetBSD Implementation Note</ulink>
	  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.</para>

	<para>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
	  <emphasis role="bold">exactly the same</emphasis> to make them interoperate.</para>
      </sect3>

      <sect3 id="compatibility">
	<title>API compatibility with other IPsec stacks</title>

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

	<para>We have <!--RFC-->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.</para>

	<para>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.</para>

	<para>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.</para>

	<para>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.</para>

	<itemizedlist>
	  <listitem>NetBSD 1.5 incorporates KAME IPsec stack of early June 2000.
	  </listitem>

	  <listitem>FreeBSD 4.0-RELEASE incorporates KAME IPsec stack of early November 1999.
	  </listitem>

	  <listitem>There is no difference in manual ipsec key configuration,
	    kernel behavior on AH/ESP operation, or &man.ipsec.set.policy.3; API.
	  </listitem>

	  <listitem>There are differences in behavior of PF_KEY socket, libipsec
	    API for PF_KEY wrapper functions and several other locations.
	    The difference may bite you if you want to implement application
	    that manipulates PF_KEY socket directly (i.e. IKE daemon like
	    &man.racoon.8; or key config program like &man.setkey.8;).
	  </listitem>
	</itemizedlist>

	<para>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.</para>
      </sect3>

      <sect3 id="readings">
	<title>Books and other reading materials?</title>

	<para>There are literally tons of books available.</para>

	<itemizedlist>
	  <listitem><ulink url="http://search.barnesandnoble.com/booksearch/results.asp?WRD=ipsec">
	      Search Barnes &amp; Noble for books on <quote>IPsec</quote></ulink>
	    (NOTE: we are not making any particular recommendation about bookstore)
	  </listitem>
	</itemizedlist>
      </sect3>
    </sect2>

    <sect2 id="Other_links">
      <title>Other links</title>

      <sect3 id="linklist">
	<title>Miscellaneous links</title>

	<itemizedlist>
	  <listitem><ulink url="rasvpn.html">How to build a remote user access VPN with Racoon</ulink>
	  </listitem>

	  <listitem><ulink url="http://asherah.dyndns.org/~josh/ipsec-howto.txt">FreeBSD IPsec mini-HOWTO</ulink>, including interoperation with Windows 2000
	  </listitem>

	  <listitem><ulink url="http://www.kame.net/">KAME project</ulink>,
	    where the IPv6 and IPsec implementations come from
	  </listitem>

	  <listitem><ulink url="http://orange.kame.net/dev/cvsweb.cgi/kame/netbsd/sys/netinet6/IMPLEMENTATION">KAME's
	      NetBSD Implementation Note</ulink>
	  </listitem>

	  <listitem><ulink url="http://orange.kame.net/dev/cvsweb.cgi/kame/IMPLEMENTATION">KAME's
	      Implementation Note</ulink> - portions may not be applicable to NetBSD
	  </listitem>

	  <listitem><ulink url="http://orange.kame.net/dev/cvsweb.cgi/kame/COVERAGE">
	      implementation differences between KAME platforms</ulink>
	  </listitem>

	  <listitem><ulink url="../../../about/crypto-export.html">
	      Exportability of NetBSD crypto code</ulink>
	  </listitem>
	</itemizedlist>
      </sect3>
    </sect2>
  </sect1>
  <parentsec url="../" text="NetBSD Documentation: Network"/>
</webpage>
