What about RFC 3948 <https://tools.ietf.org/html/rfc3948>? I have an
application that relies on this RFC, which is a NetBSD L2TP/IPSEC
server for Windows clients behind NAT, and the NetBSD server also
behind NAT. I was able to get this working to make a L2TP/IPSEC VPN
connection from Windows clients to home networks such as the network
behind AT&T U-verse or Comcast Xfinity resdential gateways.
The caveat is that I was not able to get this working with an
unpatched NetBSD kernel because it appears code to support RFC 3948 is
not enabled in NetBSD (at least not NetBSD 6 and 7).
FreeBSD removed this but they had code to support RFC 3948 that
according to your reference 1 they suggested moving to
netipsec/udpencap.c. There is no such code in NetBSD as far as I know.
I got my system to work by applying my patch shown in a previous
message
<http://mail-index.netbsd.org/tech-net/2017/09/22/msg006456.html>.
You are correct that the code in udp_usrreq.c does not work with
Windows clients, which presumably uses RFC 3948 rather than
draft-ietf-ipsec-udp-encaps-00. After some debugging I got this to
work with Windows clients by patching that section of udp_usrreq.c
(NetBSD 7.x) that is supposed to handle esp packets encapsulated in
udp as follows:
--- netinet/udp_usrreq.c 2014-08-09 01:33:01.000000000 -0400
+++ netinet/udp_usrreq.c 2017-08-23 23:40:47.571414000 -0400
@@ -1324,10 +1405,13 @@
u_int32_t *st = (u_int32_t *)data;
if ((len <= sizeof(u_int64_t) + sizeof(struct esp))
- || ((st[0] | st[1]) != 0))
- return 0; /* Normal UDP processing */
-
- skip = sizeof(struct udphdr) + sizeof(u_int64_t);
+ || ((st[0] | st[1]) != 0)) {
+ /* From rfc 2406, 4303 for esp, st[0] is the spi */
+ /* From rfc 2406, 4303 for esp, st[1] is the sequence
number */
+ if (!key_spiexists(st[0])) /* This is not an espinudp
packet */
+ return 0; /* Normal UDP processing */
+ }
+ skip = sizeof(struct udphdr);
}
/*
Notice that my patch had to change the value of the skip variable to
make my setup work. This patch is part of my much larger patch that I
posted in an earlier thread on the tech-net mailing list
<http://mail-index.netbsd.org/netbsd-users/2017/09/22/msg020168.html>
where more details about my patch to make the VPN server work through
NAT devices are given.
Chuck Zmudzinski
On 5/17/2018 2:16 AM, Maxime Villard wrote:
I think it would be good to retire UDP_ENCAP_ESPINUDP_NON_IKE. It is not
part of any RFC, it was just introduced in a draft, and then
subsequently
removed from that draft.
RFC3948 makes authority, and it documents only the Non-ESP marker - that
is to say, UDP_ENCAP_ESPINUDP.
I think we are not supposed to support undocumented options.
FreeBSD did the same, see [1]. OpenBSD has never had that, it seems.
The reason I'm bringing this, is because there appears to be a bug with
UDP_ENCAP_ESPINUDP_NON_IKE, in udp_usrreq.c:
1317 skip = sizeof(struct udphdr) + 2 * sizeof(uint32_t);
1318 }
1319
1320 /*
1321 * Get the UDP ports. They are handled in network order
1322 * everywhere in the IPSEC_NAT_T code.
1323 */
1324 udphdr = (struct udphdr *)((char *)data - skip);
Here we have:
data = mtod(m) + IP_header_len + sizeof(struct udphdr)
So it is wrong to substract 'skip', because then 'udphdr' will point to
some data in the IP header. I'm not sure if it means the code has never
worked, or if I'm just completely misreading it.
What do you think? I asked Ryota and Kengo, they don't know. One
concern is
raccoon, because it supports each draft that led to the RFC [2]. To
me this
is wrong too, there shouldn't be support for temporary specs, that
have no
meaning once the RFC is out.
Don't know.
Maxime
[1] http://freshbsd.org/commit/freebsd/r309808
[2]
https://nxr.netbsd.org/xref/src/crypto/dist/ipsec-tools/src/racoon/vendorid.c#67