Adding NAT-T to openiked on FreeBSD

Michael Cardell Widerkrantz mc at hack.org
Tue Feb 12 14:03:15 UTC 2013


Hello,

I'm trying to add NAT-traversal support on FreeBSD to the portable
version of OpenBSD's IKEv2 daemon, openiked. See http://openiked.org/
for more. My NAT-T branch is called "natt" and lives here:
http://github.com/mchackorg/openiked/

It seems to work, but only one way. The receiving node doesn't seem to
unpack the ESP from UDP.

The IKE dialogue succesfully negotiates security associations and both
ends agree to use UDP-ESP. When I try to ping a node on the other end my
ICMP packets are succesfully encapsulated as UDP-ESP but seems to be
thrown away at the other end.

I'm stuck. Does anyone have any idea what's happening here and what I
can do about it?

The network looks like this:

    192.168.0.2 - em0-192.168.0.1 10.0.2.1-em1 - 10.0.2.2
       alice                  NAT box              bob

The 192.168.0.0/24 network is the private network here. Everything sent
from nodes on that network looks like 10.0.2.1 to bob.

Here's some output of setkey from ipsec-tools (which knows about NAT-T):

alice, 192.168.0.2:

# ./setkey -D
192.168.0.2[4500] 10.0.2.2[4500] 
        esp-udp mode=tunnel spi=3488009807(0xcfe6ce4f)
        reqid=0(0x00000000)
        E: aes-cbc  07e091ae 7c3ff9ba 62061151 83969ff9 ad95a7dd
        1484ef05 bc92393d 6819cd00
        A: hmac-sha256  36513976 f54ead88 f9e50769 23a5440b 20cd52a8
        a9609d34 d2a0f1d5 243b84bc
        seq=0x00000000 replay=64 flags=0x00000000 state=mature 
        created: Feb 12 13:58:24 2013   current: Feb 12 13:59:24 2013
        diff: 60(s)     hard: 10800(s)  soft: 9741(s)
        last:                           hard: 0(s)      soft: 0(s)
        current: 0(bytes)       hard: 536870912(bytes)  soft:
        484257562(bytes)
        allocated: 0    hard: 0 soft: 0
        sadb_seq=1 pid=1794 refcnt=1
10.0.2.2[4500] 192.168.0.2[4500] 
        esp-udp mode=tunnel spi=1821072731(0x6c8b5d5b)
        reqid=0(0x00000000)
        E: aes-cbc  cc21a55c 4ec81ca4 ea93641a 2ea0db9f 422173a9
        b6c22c99 d8f78e3f 2fc7b175
        A: hmac-sha256  67b08cc7 3dd0409d 27dfeb18 c4435eb3 72ac32dd
        b4d084c3 6b13225e f94d92b6
        seq=0x00000000 replay=64 flags=0x00000000 state=mature 
        created: Feb 12 13:58:24 2013   current: Feb 12 13:59:24 2013
        diff: 60(s)     hard: 10800(s)  soft: 9698(s)
        last:                           hard: 0(s)      soft: 0(s)
        current: 0(bytes)       hard: 536870912(bytes)  soft:
        482110078(bytes)
        allocated: 0    hard: 0 soft: 0
        sadb_seq=0 pid=1794 refcnt=1

# ./setkey -DP
10.0.2.0/24[any] 192.168.0.0/24[any] 255
        in ipsec
        esp/tunnel/10.0.2.2-192.168.0.2/use
        spid=6 seq=1 pid=1795
        refcnt=1
192.168.0.0/24[any] 10.0.2.0/24[any] 255
        out ipsec
        esp/tunnel/192.168.0.2-10.0.2.2/require
        spid=5 seq=0 pid=1795
        refcnt=1

bob, 10.0.2.2:

# ./setkey -D
10.0.2.2[4500] 10.0.2.1[4500] 
        esp-udp mode=tunnel spi=1821072731(0x6c8b5d5b)
        reqid=0(0x00000000)
        E: aes-cbc  cc21a55c 4ec81ca4 ea93641a 2ea0db9f 422173a9
        b6c22c99 d8f78e3f 2fc7b175
        A: hmac-sha256  67b08cc7 3dd0409d 27dfeb18 c4435eb3 72ac32dd
        b4d084c3 6b13225e f94d92b6
        seq=0x00000000 replay=64 flags=0x00000000 state=mature 
        created: Feb 12 13:58:28 2013   current: Feb 12 13:58:49 2013
        diff: 21(s)     hard: 10800(s)  soft: 10054(s)
        last:                           hard: 0(s)      soft: 0(s)
        current: 0(bytes)       hard: 536870912(bytes)  soft:
        499826819(bytes)
        allocated: 0    hard: 0 soft: 0
        sadb_seq=1 pid=6046 refcnt=1
10.0.2.1[4500] 10.0.2.2[4500] 
        esp-udp mode=tunnel spi=3488009807(0xcfe6ce4f)
        reqid=0(0x00000000)
        E: aes-cbc  07e091ae 7c3ff9ba 62061151 83969ff9 ad95a7dd
        1484ef05 bc92393d 6819cd00
        A: hmac-sha256  36513976 f54ead88 f9e50769 23a5440b 20cd52a8
        a9609d34 d2a0f1d5 243b84bc
        seq=0x00000000 replay=64 flags=0x00000000 state=mature 
        created: Feb 12 13:58:28 2013   current: Feb 12 13:58:49 2013
        diff: 21(s)     hard: 10800(s)  soft: 9633(s)
        last:                           hard: 0(s)      soft: 0(s)
        current: 0(bytes)       hard: 536870912(bytes)  soft:
        478888853(bytes)
        allocated: 0    hard: 0 soft: 0
        sadb_seq=0 pid=6046 refcnt=1

# ./setkey -DP
192.168.0.0/24[any] 10.0.2.0/24[any] 255
        in ipsec
        esp/tunnel/10.0.2.1-10.0.2.2/use
        spid=12 seq=1 pid=6052
        refcnt=1
10.0.2.0/24[any] 192.168.0.0/24[any] 255
        out ipsec
        esp/tunnel/10.0.2.2-10.0.2.1/require
        spid=11 seq=0 pid=6052
        refcnt=1

Listening on 192.168.0.2 when doing ping from 10.0.2.2:

14:00:21.434961 IP 10.0.2.2.4500 > 192.168.0.2.4500: UDP-encap:
ESP(spi=0x6c8b5d5b,seq=0x1), length 136
14:00:22.435662 IP 10.0.2.2.4500 > 192.168.0.2.4500: UDP-encap:
ESP(spi=0x6c8b5d5b,seq=0x2), length 136

Listening on 10.0.2.2 when doing ping from 192.168.0.2 (NATted to
10.0.2.1):

14:00:53.932671 IP 10.0.2.1.4500 > 10.0.2.2.4500: UDP-encap:
ESP(spi=0xcfe6ce4f,seq=0x1), length 136
14:00:54.942653 IP 10.0.2.1.4500 > 10.0.2.2.4500: UDP-encap:
ESP(spi=0xcfe6ce4f,seq=0x2), length 136

I looked through the kernel to find the way packets are unpacked. The
packets seem to go this path:

  sys/netinet/udp_usrreq.c: udp_input() -> udp_append() -> udp4_espdecap()

In udp_append() there's some code dealing with UDP encapsulated ESP, so
I added a small debug printout:

----------------- 8< -----------------

--- udp_usrreq.c-orig   2013-02-12 14:28:30.000000000 +0100
+++ udp_usrreq.c        2013-02-12 14:28:08.000000000 +0100
@@ -284,6 +284,7 @@ udp_append(struct inpcb *inp, struct ip 
 #ifdef IPSEC_NAT_T
        up = intoudpcb(inp);
        KASSERT(up != NULL, ("%s: udpcb NULL", __func__));
+       log(LOG_DEBUG, "udp_append in NAT_T. up->u_flags: %d\n", up->u_flags);
        if (up->u_flags & UF_ESPINUDP_ALL) {    /* IPSec UDP encaps. */
                n = udp4_espdecap(inp, n, off);
                if (n == NULL)                          /* Consumed. */

----------------- 8< -----------------

When I see UDP-ESP traffic coming in I see this in the log for every UDP-ESP
packet received:

  udp_append in NAT_T. up->u_flags: 0

I was expecting this flag variable to be set. Where should it be set?

Any other ideas?

-- 
MC, http://hack.org/mc/


More information about the freebsd-net mailing list