Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Apr 2012 22:10:01 +0200
From:      Andreas Longwitz <longwitz@incore.de>
To:        freebsd-stable@freebsd.org
Subject:   Re: Support for IPSec NAT-T in transoprt mode
Message-ID:  <4F970899.2040105@incore.de>

next in thread | raw e-mail | index | archive | help
I run FreeBSD 8.2, ipsec-tools-0.8.0_2 and mpd-5.5.
To get NATed VPN clients working through L2TP/IPSec I use the patches
given in kern/146190 for the files esp_var.h, ipsec.c, ipsec_input.c
(only the "Ignore checksum" part) and xform_esp.c. Further the following
patch:

--- key.c.1st   2011-09-29 10:39:44.000000000 +0200
+++ key.c       2012-04-24 21:40:55.000000000 +0200
@@ -1312,11 +1312,14 @@
                        continue;
                if (key_cmpspidx_exactly(spidx, &sp->spidx)) {
                        SP_ADDREF(sp);
-                       break;
+                       SPTREE_UNLOCK();
+                       goto found;
                }
        }
        SPTREE_UNLOCK();
+       return NULL;

+   found:
        return sp;
 }

@@ -2967,11 +2970,15 @@
        LIST_FOREACH(sah, &V_sahtree, chain) {
                if (sah->state == SADB_SASTATE_DEAD)
                        continue;
-               if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID))
-                       break;
+               if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID)) {
+                       SAHTREE_UNLOCK();
+                       goto found;
+               }
        }
        SAHTREE_UNLOCK();
+       return NULL;

+   found:
        return sah;
 }

@@ -4064,10 +4071,12 @@
                /*
                 * If NAT-T is enabled, check ports for tunnel mode.
                * Do not check ports if they are set to zero in the SPD.
-                * Also do not do it for transport mode, as there is no
+                * Also do not do it for native transport mode, as there
is no
                 * port information available in the SP.
                 */
-               if (saidx1->mode == IPSEC_MODE_TUNNEL &&
+               if ((saidx1->mode == IPSEC_MODE_TUNNEL ||
+                   (saidx1->mode == IPSEC_MODE_TRANSPORT &&
+                   saidx1->proto == IPPROTO_ESP)) &&
                    saidx1->src.sa.sa_family == AF_INET &&
                    saidx1->dst.sa.sa_family == AF_INET &&

Then a NATed FreeBSD or Android client works fine with L2TP/IPSec (PSK
or certificate), also every iPhone with L2TP/IPSec (PSK). I don't know
if we can handle the server side of Cisco IPSEC used by Apple for
certificates on the iphone. Hints are very welcome.

There is one limitation I would like to get over. From man 8 setkey:
System that do not perform the port check cannot support multiple
endpoints behind the same NAT. I think this is a FreeBSD kernel restriction:
For the first incoming L2TP packet the IPSEC part of the kernel does not
save the source port in the corresponding SA (maybe a field like
natt_l2tp_port). So the kernel does for outgoing L2TP packets not know
the correct SA, if two ore more SA's with the same IP exists.

I would like to know if the patch mentioned in this thread adresses this
problem.


-- 
Dr. Andreas Longwitz

Data Service GmbH
Beethovenstr. 2A
23617 Stockelsdorf
Amtsgericht Lübeck, HRB 318 BS
Geschäftsführer: Wilfried Paepcke, Dr. Andreas Longwitz, Josef Flatau



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4F970899.2040105>