Le 19/05/2018 à 16:16, Chuck Zmudzinski a écrit :
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'm not sure I understand. NetBSD _does_ support RFC3948. See
udp4_espinudp()
in netinet/udp_usrreq.c.
What I was saying, is that we have code for
draft-ietf-ipsec-udp-encaps-00,
that this code doesn't work, and that I don't think we are supposed to
support drafts.
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>.
I don't think the checksum part is necessary anymore. See
ipsec4_fixup_checksum() in ipsec_intput.c.
(This is not available on netbsd-7, though.)
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.
Indeed. So you fixed the problem I was talking about: if we substract
8 bytes
we hit the IP header, and not the UDP header.
However, it appears that you (or your application) got confused at
some point.
This branch is taken when UDP_ENCAP_ESPINUDP_NON_IKE is set. This flag
means
that we always want a "non-IKE marker", see [1].
The non-IKE marker is a 8-byte-sized zeroed area. So no, st[0] is not
the SPI,
and st[1] is not the sequence number.
The fact that your application somehow reached this branch means that
it did
set the UDP_ENCAP_ESPINUDP_NON_IKE flag. Therefore, for some reason, your
application is explicitly requesting non-IKE markers.
To me it looks like a misconfiguration. Your application requests non-IKE
markers, but it receives non-ESP markers. Given that in such a case
st[1]!=0,
the kernel always thinks it needs to do normal UDP processing, while
it should
do ESP processing. As a result nothing works.
What is your configuration? I bet that if you somehow change it to drop
non-IKE markers, it will work perfectly fine.t