tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: UDP_ENCAP_ESPINUDP_NON_IKE



On 5/22/2018 11:11 PM, Chuck Zmudzinski wrote:
On 5/22/2018 12:07 PM, Chuck Zmudzinski wrote:
On 5/21/2018 1:07 PM, Maxime Villard wrote:
Le 21/05/2018 à 17:47, Chuck Zmudzinski a écrit :
We would have to configure a remote host that uses the non-IKE markers and doesn't use the RFC to test the way the kernel currently deals with that
case.

Yes, and that's a case that we are not supposed to support. Just like we're not supposed to support all the drafts that led to the many RFCs available
out there.

So I suggest we disable ENABLE_NATT_00. This will disable draft-00, in such a way that racoon will never use non-IKE markers. Then we remove ESPINUDP_NON_IKE
from the kernel.

If we do this, we will find out if the old code was working and someone was relying on it, because this will break it and that person will file a bug
report!

What? The kernel code doesn't work in the first place.

Disabling NATT_00 on racoon under NetBSD does not remove a feature, since it
already doesn't work on NetBSD.

To me the current code in racoon is wrong, it shouldn't automatically use
non-IKE markers when there is no NAT-T.

Yest, that is definitely a bug in the current code in racoon.



And no, there won't be a bug report, for the same reason we didn't get a
report in the last 13 years about broken non-IKE markers in the kernel.

I agree.


(Well, there was one guy that figured this out a few months ago, and it was
you.)

I actually have been working on this for several years and I forget exactly what prompted me to post about this problem to the mailing lists a few months ago, but I am pleased that we are getting this fixed in NetBSD!

Can you recompile racoon without ENABLE_NATT_00 and test again? You should be able to do so by uncommenting the #define in /src/lib/libipsec/config.h.

note: I meant _commenting_, as you probably understood.


Maxime

It looks to me like that will work. I will try it when I get a chance. I can most quickly test it on NetBSD 7.x because that is the version I am using in
my environment, and if that works as expected I will also test it with
NetBSD 8 and current and let you know what I find.

Thanks,
Maxime

This worked exactly as expected on netbsd-7. I did not test a full build, but it compiled and ran exactly as expected when I rebuilt in /src/lib/libipsec and in /src/usr.sbin/racoon on netbsd-7 after commenting out the #define of ENABLE_NATT_00 in /src/lib/libipsec/config.h and installing the new racoon and libipsec.so.3.0 in my netbsd-7 system that is modified with a kernel that patched the UDP_ENCAP_ESPINUDP_NON_IKE code to deal with my misconfigured racoon configuration.

Results as reported by the racoon log:

Before patching racoon:

May 20 21:06:12 ave racoon: INFO: respond new phase 1 negotiation: 192.168.xxx.xxx[500]<=>xxx.xxx.xxx.xxx[500]
May 20 21:06:12 ave racoon: INFO: begin Identity Protection mode.
May 20 21:06:12 ave racoon: INFO: received Vendor ID: RFC 3947
May 20 21:06:12 ave racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02 May 20 21:06:12 ave racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02 May 20 21:06:12 ave racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-00
May 20 21:06:12 ave racoon: INFO: received Vendor ID: DPD
May 20 21:06:12 ave racoon: [xxx.xxx.xxx.xxx] INFO: Selected NAT-T version: RFC 3947

After patching racoon by commenting out the #define of ENABLE_NATT_00 in /src/lib/libipsec/config.h:

May 20 22:10:08 ave racoon: INFO: respond new phase 1 negotiation: 192.168.xxx.xxx[500]<=>xxx.xxx.xxx.xxx[500]
May 20 22:10:08 ave racoon: INFO: begin Identity Protection mode.
May 20 22:10:08 ave racoon: INFO: received broken Microsoft ID: MS NT5 ISAKMPOAKLEY
May 20 22:10:08 ave racoon: INFO: received Vendor ID: RFC 3947
May 20 22:10:08 ave racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02
May 20 22:10:08 ave racoon: INFO: received Vendor ID: FRAGMENTATION
May 20 22:10:08 ave racoon: [xxx.xxx.xxx.xxx] INFO: Selected NAT-T version: RFC 3947

Vendor ID draft-ietf-ipsec-nat-t-ike-00 is no longer received from the remote host, as expected.

I also edited my kernel to report if it is using the UDP_ENCAP_ESPINUDP_NON_IKE branch or the UDP_ENCAP_ESPINUDP branch in udp_usrreq.c. As expected, now I get this in /var/log/messages:

May 20 21:13:53 ave /netbsd: udp4_espinudp: UDP_ENCAP_ESPINUDP is set.

It is working correctly now because racoon is not incorrectly telling the kernel it is using NON_IKE markers.

Things get a little more complicated for the case with the patched racoon and racoon.conf configured incorrectly. To remind you, the incorrect configuration was that I had the wrong statement in the listen directive of racoon.conf for port 4500. I used isakmp instead of isakmp_natt in the listen directive.

As I predicted, it does not work in this case, because in this case, racoon is configured to not do any version of ESP in UDP, so after phase 1 and phase 2 are negotiated successfully and the ESPINUDP packets start coming from the remote host, the kernel tries to do normal UDP processing on them instead of decapsulating them and sending them for processing by ipsec. The racoon log indicates the kernel sends the ESP in UDP back to racoon which complains about packets being too big and after a while the connection attempt fails and the remote host eventually terminates the connection with an error.

Is this a bug? Well, on one hand, we should not support a misconfigured setup, so it is correct for the connection to fail. On the other hand, I would argue that it is still a bug in racoon to try to negotiate a connection based on RFC 3947 and 3948 and actually let the connection get to the point where the remote host is sending us ESP in UDP packets that we cannot handle correctly. In this case, I think the correct behavior is for racoon to detect that it is not configured correctly to support RFC 3947 and 3948 at startup and at least log a warning or even exit with an error and report that racoon is not configured correctly to handle NAT-T connections using RFC 3947 and 3948. I am working on a patch to racoon to do that. Even this patched racoon does not provide much useful information in its log messages to assist in the debugging process. This is why no one has solved this problem for the last 13 years.

Thank you for all your help. I am glad to help get support for this feature in NetBSD.

Chuck


Update on my testing. I ran my NetBSD 7 userland including racoon without support for draft-ietf-ipsec-nat-t-ike-00 on an unmodified NetBSD 8.0 RC1 kernel and I was able to connect L2TP/IPSEC clients without any modifications to the NetBSD 8.0 RC1 kernel. This means that  ipsec4_fixup_checksum() in ipsec_intput.c on NetBSD 8.0 RC1 does work in my setup and I won't need to worry about patching NetBSD 8.x kernels to get nat-traversal working for L2TP/IPSEC VPN connections. Next I will try a current kernel and I expect it will work also. As for NetBSD 7, I ask if ipsec4_fixup_checksum() can be ported into netbsd-7. I would rather use a port of the official netbsd solution than my old patch in NetBSD 7.

In my latest tests, though, I noticed something unexpected. With this new setup that has a more correctly configured racoon, I got this in the log when the remote host was using an unpatched racoon on NetBSD (instead of Microsoft Windows):

May 22 21:27:39 ave racoon: INFO: respond new phase 1 negotiation: 192.168.xxx.xxx[500]<=>xxx.xxx.xxx.xxx[500]
May 22 21:27:39 ave racoon: INFO: begin Identity Protection mode.
May 22 21:27:39 ave racoon: INFO: received Vendor ID: RFC 3947
May 22 21:27:39 ave racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02 May 22 21:27:39 ave racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02 May 22 21:27:39 ave racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-00
May 22 21:27:39 ave racoon: INFO: received Vendor ID: DPD
May 22 21:27:39 ave racoon: [xxx.xxx.xxx.xxx] INFO: Selected NAT-T version: RFC 3947

With the NetBSD/racoon client, our racoon that is not supposed to have support for draft-ietf-ipsec-nat-t-ike-00 compiled in still recognizes that deprecated version when logging information while it was negotiating phase 1. I do not see this with Windows clients and the new racoon. I saw it with Windows clients and the old racoon. So that is a little weird. I think we at least have a functional setup now, but I am sure it will still be very buggy.

Chuck


Last update on my testing of the proposed racoon patch:

I tested a NetBSD 8.0 RC1 kernel with the attached patch to udp_usrreq.c that comments out the branch that processes packets with the UDP_ENCAP_ESPINUDP_NON_IKE socket option to test what would happen if we remove that from the kernel, and ran my NetBSD 7 system on it with the unpatched racoon and with our racoon that has support for ENABLE_NATT_00 removed. As expected, with the old racoon, the connection attempt fails on this kernel because of the bug in racoon that mistakenly causes the kernel to use that branch of the kernel that I removed in this kernel. Also, as expected, our patch to racoon that removes support for ENABLE_NATT_00 fixes the problem on this kernel without UDP_ENCAP_ESPINUDP_NON_IKE so I think this solution will work on NetBSD 8.x. This is good news.

The bad news: I started testing with a recent current kernel downloaded from daily snapshots. It is about a week old. I ran my NetBSD 7 system on that current kernel with the new racoon without support for ENABLE_NATT_00, and as expected it connected fine. However, as soon as I disconnected the VPN connection on the remote host, the current kernel crashed. I could not recover the log to see what happened when I rebooted after the crash.

I think I have done enough testing to show that our patch to racoon is a good place to begin, but if you want to test this on the current kernel, be prepared to deal with kernel crashes. I guess that is always true when using current kernels...

Chuck

--- udp_usrreq.c.orig	2018-05-22 15:29:56.078274000 -0400
+++ udp_usrreq.c	2018-05-23 14:04:52.850788000 -0400
@@ -1303,21 +1303,21 @@
 		if ((len <= sizeof(struct esp)) || (*st == 0))
 			return 0; /* Normal UDP processing */
 
 		skip = sizeof(struct udphdr);
 	}
-
+#if 0
 	if (inp->inp_flags & INP_ESPINUDP_NON_IKE) {
 		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);
 	}
-
+#endif
 	/*
 	 * Get the UDP ports. They are handled in network 
 	 * order everywhere in IPSEC_NAT_T code.
 	 */
 	udphdr = (struct udphdr *)((char *)data - skip);


Home | Main Index | Thread Index | Old Index