Created attachment 145951 [details] patch for problem. Consider an IPSEC policy such as: spdadd 0.0.0.0/0 XXX.XXX.XXX.XXX/32[1701] udp -P out ipsec esp/transport//require; spdadd XXX.XXX.XXX.XXX/32[1701] 0.0.0.0/0 udp -P in ipsec esp/transport//require; When triggered it sends a PF_KEY ACQUIRE message that causes ISAKMP negotiations to occur with the remote. Unfortunately the key_acquire routine in sys/netipsec/key.c doesn't contain any code to propagate the port / protocol information as part of the ACQUIRE message ... as a result racoon sees an ACQUIRE message for all traffic to the remote system and supplies that as the proposal which fails since the remote system is only willing to protect L2TP with IPSEC ... not all traffic. Note that RFC 2367 3.1.6 SADB_ACQUIRE says: The address(SD) extensions MUST have the port fields filled in with the port numbers of the session requiring keys if appropriate. With the supplied patch I'm able to successfully establish a L2TP protected by IPSEC connection from FreeBSD 10-stable to a Cisco 3845 router.
A commit references this bug: Author: ae Date: Mon Jul 6 12:40:32 UTC 2015 New revision: 285204 URL: https://svnweb.freebsd.org/changeset/base/285204 Log: Fill the port and protocol information in the SADB_ACQUIRE message in case when security policy has it as required by RFC 2367. PR: 192774 Differential Revision: https://reviews.freebsd.org/D2972 MFC after: 1 week Changes: head/sys/netipsec/key.c
A commit references this bug: Author: ae Date: Wed Jul 15 21:09:39 UTC 2015 New revision: 285614 URL: https://svnweb.freebsd.org/changeset/base/285614 Log: MFC r285204: Fill the port and protocol information in the SADB_ACQUIRE message in case when security policy has it as required by RFC 2367. PR: 192774 Approved by: re (delphij) Changes: _U stable/10/ stable/10/sys/netipsec/key.c
Merged to stable/10. Thanks!
After updating on old FreeBSD V8 server to 10 Stable my L2TP/IPSEC connections were broken. The reason for this was the commit 285204 given in this bug report. Racoon tried to connect to the remote server on port 1701 instead of 500: initiate new phase 1 negotiation: 192.168.14.23[500]<=>192.168.14.3[1701] The following patch for racoon solved this problem for me: --- src/racoon/pfkey.c.orig 2012-08-23 13:10:45.000000000 +0200 +++ src/racoon/pfkey.c 2018-04-10 15:35:17.603722000 +0200 @@ -1931,11 +1931,13 @@ delph2(iph2); return -1; } + set_port(iph2->dst, 0); iph2->src = dupsaddr(src); if (iph2->src == NULL) { delph2(iph2); return -1; } + set_port(iph2->src, 0); /* If sa_src and sa_dst have been set, this mean we have to * set iph2->sa_src and iph2->sa_dst to provide the addresses I suggest this patch should go in the files directory of the port security/ipsec-tools.
Regarding racoon here's the fix I supplied to ipsec-tools-devel@lists.sourceforge.net in 2014: To: ipsec-tools-devel@lists.sourceforge.net Subject: ipsec-tools-0.8.2 patch to properly set isakmp ph1 port Currently copy_ph1addresses assumes that an initiation is indicated by the port numbers in the ACQUIRE msg equaling zero. In the case of an policy such as: spdadd 0.0.0.0/0 XXX.XXX.XXX.XXX/32[1701] udp -P out ipsec esp/transport//require; spdadd XXX.XXX.XXX.XXX/32[1701] 0.0.0.0/0 udp -P in ipsec esp/transport//require; (designed to provide IPSEC protection for L2TP) the ACQUIRE msg contains port information causing racoon to attempt initiate ISAKMP phase 1 with the remote on port 1701 instead of port 500. The supplied patch adds an explict flag to copy_ph1addresses which indicates if the addresses are being used to initiate ISAKMP. With this patch I'm able to successfully establish a L2TP protected by IPSEC connection from FreeBSD 10-stable to a Cisco 3845 router. -- John -----------------8<------------------------8<---------------------------- --- src/racoon/isakmp.c.ORIGINAL 2012-08-29 04:55:26.000000000 -0400 +++ src/racoon/isakmp.c 2014-08-16 22:27:10.336976657 -0400 @@ -1074,7 +1074,7 @@ isakmp_ph1begin_i(rmconf, remote, local) iph1->approval = NULL; /* XXX copy remote address */ - if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { + if (copy_ph1addresses(iph1, rmconf, remote, local, TRUE) < 0) { delph1(iph1); return NULL; } @@ -1188,7 +1188,7 @@ isakmp_ph1begin_r(msg, remote, local, et /* copy remote address; remote and local always contain * port numbers so rmconf is not needed */ - if (copy_ph1addresses(iph1, NULL, remote, local) < 0) { + if (copy_ph1addresses(iph1, NULL, remote, local, FALSE) < 0) { delph1(iph1); return -1; } @@ -2904,10 +2904,11 @@ isakmp_printpacket(msg, from, my, decode #endif /*HAVE_PRINT_ISAKMP_C*/ int -copy_ph1addresses(iph1, rmconf, remote, local) +copy_ph1addresses(iph1, rmconf, remote, local, initiator) struct ph1handle *iph1; struct remoteconf *rmconf; struct sockaddr *remote, *local; + int initiator; { u_int16_t port; @@ -2923,7 +2924,7 @@ copy_ph1addresses(iph1, rmconf, remote, * if remote has port # (in case of responder - from recvfrom(2)) * respect content of "remote". */ - if (extract_port(iph1->remote) == 0) { + if (initiator || extract_port(iph1->remote) == 0) { port = 0; if (rmconf != NULL) port = extract_port(rmconf->remote); @@ -2939,7 +2940,7 @@ copy_ph1addresses(iph1, rmconf, remote, if (iph1->local == NULL) return -1; - if (extract_port(iph1->local) == 0) { + if (initiator || extract_port(iph1->local) == 0) { port = myaddr_getsport(iph1->local); if (port == 0) port = PORT_ISAKMP; --- src/racoon/isakmp_inf.c.ORIGINAL 2013-04-12 05:53:52.000000000 -0400 +++ src/racoon/isakmp_inf.c 2014-08-16 22:29:35.793972202 -0400 @@ -724,7 +724,7 @@ isakmp_info_send_nx(isakmp, remote, loca #endif /* copy remote address */ - if (copy_ph1addresses(iph1, NULL, remote, local) < 0) + if (copy_ph1addresses(iph1, NULL, remote, local, FALSE) < 0) goto end; tlen = sizeof(*n) + spisiz; --- src/racoon/isakmp_var.h.ORIGINAL 2010-11-12 05:36:37.000000000 -0500 +++ src/racoon/isakmp_var.h 2014-08-16 22:25:55.863985365 -0400 @@ -128,7 +128,8 @@ extern void isakmp_printpacket __P((vcha #endif extern int copy_ph1addresses __P(( struct ph1handle *, - struct remoteconf *, struct sockaddr *, struct sockaddr *)); + struct remoteconf *, struct sockaddr *, struct sockaddr *, + int initiator)); extern void log_ph1established __P((const struct ph1handle *)); extern void script_hook __P((struct ph1handle *, int)); ------------------------------------------------------------------------- | Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com | | John Wehle | Fax: 1-215-540-5495 | | -------------------------------------------------------------------------
A commit references this bug: Author: eugen Date: Sun Apr 29 10:00:02 UTC 2018 New revision: 468617 URL: https://svnweb.freebsd.org/changeset/ports/468617 Log: Fix phase 1 initiation in the racoon daemon after base system change r285204 PR: 192774, 222065 Submitted by: Andreas Longwitz <longwitz@incore.de> Approved by: VANHULLEBUS Yvan (maintainer, implicitly) Changes: head/security/ipsec-tools/Makefile head/security/ipsec-tools/files/patch-isakmpinit