NetBSD Problem Report #53334

From frchuckz@gmail.com  Thu May 31 01:14:25 2018
Return-Path: <frchuckz@gmail.com>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id B40647A103
	for <gnats-bugs@gnats.NetBSD.org>; Thu, 31 May 2018 01:14:25 +0000 (UTC)
Message-Id: <20180531011500.F2F4355C8D@ave.localdomain>
Date: Wed, 30 May 2018 21:15:00 -0400 (EDT)
From: frchuckz@gmail.com
Reply-To: frchuckz@gmail.com
To: gnats-bugs@NetBSD.org
Subject: Broken enforcement of RFC 3947/3948 - IPSec through NAT-T
X-Send-Pr-Version: 3.95

>Number:         53334
>Category:       standards
>Synopsis:       racoon does not configure sockets for IPSec through NAT according to
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    standards-manager
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu May 31 01:15:00 +0000 2018
>Closed-Date:    Thu May 31 20:27:41 +0000 2018
>Last-Modified:  Thu May 31 20:27:41 +0000 2018
>Originator:     Chuck Zmudzinski
>Release:        NetBSD 8.0 RC1 / NetBSD 7.1
>Organization:
NetBSD User Community	
>Environment:


System: NetBSD ave 8.0_RC1 NetBSD 8.0_RC1 (XEN3_DOMU) #0: Tue May 15 13:50:20 UTC 2018  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/xen/compile/XEN3_DOMU amd64.

I am using an 8.0 RC1 kernel because it supports fixing NAT-T checksums in transport mode, which is required for L2TP/IPsec connections through a NAT device. This support is not available in NetBSD 7.x and lower. The rest of my environment is NetBSD 7.1. I plan on upgrading the userland to 8 when 8.0 is released.
Architecture: x86_64
Machine: amd64
>Description:
I discovered this bug during a discussion on the tech-net mailing list (http://mail-index.netbsd.org/tech-net/2018/05/21/msg006889.html). It is basically a bug in racoon that causes the UDP_ENCAP_ESPINUDP_NON_IKE socket option to be set even when racoon is configured to not set any UDP_ENCAP option. This bug causes problems in trying to configure racoon and the kernel to work together to configure a NetBSD system to behave according to RFC 3947 and 3948. This makes it difficult to get IPsec through NAT devices (Nat-traversal or NAT-T) working according to industry wide standards on NetBSD. The UDP_ENCAP_ESPINUDP_NON_IKE option applies only to outdated deprecated drafts, but racoon still wants to use it, and the NetBSD kernel currently supports it.	
>How-To-Repeat:
The problem is subtle and not immediately obvious but causes big problems in trying to get NAT-T working correctly on NetBSD. One way to see it is to configure racoon to not listen on a port configured to do nat traversal. This can be done by setting at least one isakmp statement in the listen directive of racoon.conf for port 500, but do not set any isakmp_natt statements in the listen directive for port 4500 or for any other port on your listening address. 

Snippet from racoon.conf:

listen
{
	isakmp 192.168.1.254[500];
}

192.168.1.254 is the address of the interface on your NetBSD box that will listen for requests to configure an IPsec connection.

When racoon starts up, you will see something like this in /var/log/messages when racoon starts:

May 20 21:05:51 ave racoon: INFO: @(#)ipsec-tools cvs (http://ipsec-tools.sourceforge.net)
May 20 21:05:51 ave racoon: INFO: @(#)This product linked OpenSSL 1.0.1u  22 Sep 2016 (http://www.openssl.org/)
May 20 21:05:51 ave racoon: INFO: Reading configuration from "/etc/racoon/racoon.conf"
May 20 21:05:51 ave racoon: INFO: 192.168.1.254[500] used for NAT-T
May 20 21:05:51 ave racoon: INFO: 192.168.1.254[500] used as isakmp port (fd=9)

The problem is that in racoon.conf, we asked racoon to not configure any sockets for NAT-T, yet it configured for NAT-T on port 500. Not only that, port 500 is the wrong port for NAT-T. According to RFC 3947, it should be port 4500. Even worse, after further investigation, it configures the socket to use the outdated UDP_ENCAP_ESPINUDP_NON_IKE version of the protocol instead of the UDP_ENCAP_ESPINUDP version that is compatible with RFC 3947/3948 (although this cannot easily be verified without debugging racoon and the kernel, but this was done as discussed in the tecn-net thread referenced earlier). From this simple test we can see racoon does not do what RFC 3947 calls for.	
>Fix:
The proposed fix is to remove support for the deprecated UDP_ENCAP_ESPINUDP_NON_IKE protocol from racoon and the kernel so the kernel will refuse to configure sockets or process packets according to that deprecated draft and always use the RFC version of the protocol, which is flagged as the UDP_ENCAP_ESPINUDP protocol in NetBSD. The only other fix would be to patch racoon and test the patches until it can be verified it always uses the correct protocol. That would be tedious because racoon does not even provide a configuration option for the encapsulation protocol in racoon.conf; the protocol that is actually used is determined by the logic in the source code of racoon and the kernel. So the recommended solution is to remove UDP_ENCAP_ESPINUDP_NON_IKE from NetBSD so the only encapsulation option in the system is the RFC 3947/3948 encapsulation protocol.

Steps to apply the fix of removing UDP_ENCAP_ESPINUDP_NON_IKE from NetBSD:

1. Apply the patch, available at http://mail-index.netbsd.org/tech-net/2018/05/26/msg006903.html, to the netbsd-8 branch which removes support for the deprecated draft from both the NetBSD kernel and racoon
2. Rebuild libipsec, racoon, and your kernel
3. Replace your kernel with the new kernel, /usr/sbin/racoon with the new racoon, and /lib/libipsec.so.3.0 with the new libipsec.so.3.0. 
4. Replace /usr/share/man/man4/udp.4 after applying the patch to update the kernel documentation that support for UDP_ENCAP_ESPINUDP_NON_IKE has been removed.
5. Reboot
6. More complete solution: also fix pkgsrc racoon, check pkgsrc racoon2 to see if it needs fixing. Probably also rebuild /usr/sbin/setkey and anything else that depends on libipsec to fully apply the solution and verify it works in a full build of the whole src tree.

After applying the proposed fix (if you correctly configure racoon to not configure for NAT-T), you will see something like this in /var/log/messages when racoon starts:

May 24 02:04:55 ave racoon: INFO: @(#)ipsec-tools cvs (http://ipsec-tools.sourceforge.net)
May 24 02:04:55 ave racoon: INFO: @(#)This product linked OpenSSL 1.0.1u  22 Sep 2016 (http://www.openssl.org/)
May 24 02:04:55 ave racoon: INFO: Reading configuration from "/etc/racoon/racoon.conf"
May 24 02:04:55 ave racoon: INFO: 192.168.1.254[500] used as isakmp port (fd=9)

With the fix, racoon is following our instructions from racoon.conf and not configuring a socket to do NAT-T.

Moreover, with this fix, if a socket is configured for NAT-T on the standard port for that, which is UDP port 4500, it will use the RFC version of the protocol instead of the deprecated draft version. This can be done by adding a isakmp_natt statement for port 4500 in the listen directive of racoon.conf and restarting racoon:

Snippet from racoon.conf:

listen
{
	isakmp 192.168.1.254[500];
	isakmp_natt 192.168.1.254[4500];
}

The proposed patch is designed to notify any program that tries to configure the UDP_ENCAP_ESPINUDP_NON_IKE socket option that the option is not available. I tested the patched kernel by running an unpatched racoon on top of it and when an unpatched racoon tries to configure a socket with UDP encapsulation, I got this in /var/log/messages when racoon started:

May 26 12:28:57 ave racoon: INFO: @(#)ipsec-tools cvs (http://ipsec-tools.sourceforge.net)
May 26 12:28:57 ave racoon: INFO: @(#)This product linked OpenSSL 1.0.1u  22 Sep 2016 (http://www.openssl.org/)
May 26 12:28:57 ave racoon: INFO: Reading configuration from "/etc/racoon/racoon.conf"
May 26 12:28:57 ave racoon: INFO: 192.168.1.254[4500] used for NAT-T
May 26 12:28:57 ave racoon: INFO: 192.168.1.254[4500] used as isakmp port (fd=11)
May 26 12:28:57 ave racoon: WARNING: setsockopt(UDP_ENCAP_ESPINUDP_NON_IKE): UDP_ENCAP Protocol option not available
May 26 12:28:57 ave racoon: INFO: 192.168.1.254[500] used as isakmp port (fd=12)

Unpatched racoon tried to set both the UDP_ENCAP_ESPINUDP_NON_IKE option and the UDP_ENCAP_ESPINUDP option but only the UDP_ENCAP_ESPINUDP option succeeded on our new kernel. The warning disappears after racoon is rebuilt with the proposed patch and installed and racoon restarted because the new version of racoon will not try to configure the deprecated encapsulation option:

May 26 12:29:57 ave racoon: INFO: @(#)ipsec-tools cvs (http://ipsec-tools.sourceforge.net)
May 26 12:29:57 ave racoon: INFO: @(#)This product linked OpenSSL 1.0.1u  22 Sep 2016 (http://www.openssl.org/)
May 26 12:29:57 ave racoon: INFO: Reading configuration from "/etc/racoon/racoon.conf"
May 26 12:29:57 ave racoon: INFO: 192.168.1.254[4500] used for NAT-T
May 26 12:29:57 ave racoon: INFO: 192.168.1.254[4500] used as isakmp port (fd=11)
May 26 12:29:57 ave racoon: INFO: 192.168.1.254[500] used as isakmp port (fd=12)

The proposed patch also includes a couple of messages from the kernel that an unexpected socket option was encountered. Those are there only to notify users something unexpected happened. If the patch is correct, those messages should never be encountered. If they are, then the patch did not successfully remove support for UDP_ENCAP_ESPINUDP_NON_IKE and some dubugging will need to be done to figure out how to prevent the UDP_ENCAP_ESPINUDP_NON_IKE option from being used in the kernel.

Finally, the comment in last line in the patch at http://mail-index.netbsd.org/tech-net/2018/05/26/msg006903.html is incorrect. Instead of saying /* Normal UDP Processing */ it should say /* Error, m is freed */


>Release-Note:

>Audit-Trail:
From: "Maxime Villard" <maxv@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/53334 CVS commit: src
Date: Thu, 31 May 2018 07:03:58 +0000

 Module Name:	src
 Committed By:	maxv
 Date:		Thu May 31 07:03:57 UTC 2018

 Modified Files:
 	src/share/man/man4: udp.4
 	src/sys/netinet: in_pcb.h udp_usrreq.c
 	src/sys/netipsec: ipsec_output.c ipsecif.c

 Log Message:
 Remove support for non-IKE markers in the kernel. Discussed on tech-net@,
 and now in PR/53334. Basically non-IKE markers come from a deprecated
 draft, and our kernel code for them has never worked.

 Setsockopt will now reject UDP_ENCAP_ESPINUDP_NON_IKE.

 Perhaps we should also add a check in key_handle_natt_info(), to make
 sure we also reject UDP_ENCAP_ESPINUDP_NON_IKE in the SADB.


 To generate a diff of this commit:
 cvs rdiff -u -r1.14 -r1.15 src/share/man/man4/udp.4
 cvs rdiff -u -r1.65 -r1.66 src/sys/netinet/in_pcb.h
 cvs rdiff -u -r1.252 -r1.253 src/sys/netinet/udp_usrreq.c
 cvs rdiff -u -r1.78 -r1.79 src/sys/netipsec/ipsec_output.c
 cvs rdiff -u -r1.9 -r1.10 src/sys/netipsec/ipsecif.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Maxime Villard" <maxv@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/53334 CVS commit: src/lib/libipsec
Date: Thu, 31 May 2018 07:16:17 +0000

 Module Name:	src
 Committed By:	maxv
 Date:		Thu May 31 07:16:17 UTC 2018

 Modified Files:
 	src/lib/libipsec: config.h

 Log Message:
 Disable draft_00 in racoon, discussed on tech-net@ and now in PR/53334.
 While here clarify the comments, no #undef.

 No need to increase the library version I guess, since draft_00 is not
 used in libipsec.


 To generate a diff of this commit:
 cvs rdiff -u -r1.7 -r1.8 src/lib/libipsec/config.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Chuck Zmudzinski <frchuckz@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: Maxime Villard <max@m00nbsd.net>, Ryota Ozaki <ozaki-r@iij.ad.jp>
Subject: Re: standards/53334
Date: Thu, 31 May 2018 16:03:08 -0400

 I tested a current kernel with the recent commits for this problem and 
 it works well with my NetBSD 7 environment. The current kernel also 
 includes the fix for the kernel panic I was experiencing in my 
 environment and that also works and I am not getting the panic anymore.

 Thanks,

 Chuck Zmudzinski

State-Changed-From-To: open->closed
State-Changed-By: wiz@NetBSD.org
State-Changed-When: Thu, 31 May 2018 20:27:41 +0000
State-Changed-Why:
Confirmed fixed, thanks for the bug report!


>Unformatted:
 standards	<synopsis of the problem (one line)>

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.