[strongSwan-dev] responder - 'no connection has been authorized' when NAT router in front of initiator uses ike src port != 500
Mohit Mehta
mohit.mehta at vyatta.com
Fri Jan 28 03:48:45 CET 2011
Hi Strongswan developers,
***** CAUTION : This email is the result of couple of days' of trying and testing so it's LONG, please be patient when reading it :-) *****
This problem was noticed in an effort to get Strongswan [responder] to work with a Cisco ASA [initiator] which is sitting behind a NAT router using IKE. Cisco ASA was defined in the connection definition on Strongswan as :
right="PUBLIC IP of NAT router sitting in front of CISCO ASA"
rigtid="PRIVATE IP of CISCO ASA"
authby=secret
It was noticed that upon Cisco ASA initiating a connection, the NAT router in front of Cisco ASA chose to use a source port other than 500 for IKE traffic. Strongswan received this packet and reported that it is unable to find a suitable connection for it and logs the following :
packet from 1.1.1.225:1500: initial Main Mode message received on 1.1.1.160:500 but no connection has been authorized with policy=PSK
At first, I thought this should be expected since the IKE source port in this case is not 500 and thus, Strongswan complains about the received packet. However, on reading RFC 3947 'Negotiation of NAT-Traversal in the IKE', this turned out to be untrue i.e. to me it seems like Strongswan should be accepting this packet [some relevant text from RFC 3947 below] :
[snip]
3. Phase 1
[snip]
The NAT may change the IKE UDP source port, and recipients MUST be
able to process IKE packets whose source port is different from 500.
[snip]
For example, when the initiator sends a packet with source and
destination port 500, the NAT may change it to a packet with source
port 12312 and destination port 500. The responder must be able to
process the packet whose source port is 12312. It must reply back
with a packet whose source port is 500 and destination port is 12312.
The NAT will then translate this packet to source port 500 and
destination port 500.
[snip]
4. Changing to New Ports
[snip]
Here is an example of a Phase 1 exchange using NAT-Traversal in Main
Mode (authentication with signatures) with changing port:
Initiator Responder
------------ ------------
UDP(500,500) HDR, SA, VID -->
<-- UDP(500,X) HDR, SA, VID
UDP(500,500) HDR, KE, Ni,
NAT-D, NAT-D -->
<-- UDP(500,X) HDR, KE, Nr,
NAT-D, NAT-D
UDP(4500,4500) HDR*#, IDii,
[CERT, ]SIG_I -->
<-- UDP(4500,Y) HDR*#, IDir,
[ CERT, ], SIG_R
[snip]
Intrigued by this finding, I started to test Strongswan as a responder with another Strongswan as the initiator sitting behind NAT. I used the following topology [Topology also attached as "Topology for nat-traversal ike src port != 500 testing"] :
RESPONDER NAT ROUTER INITIATOR
------ ------ ------
192.168.74.0/24| |.160 1.1.1.0/24 .225| |.225 172.16.117.0/24 .200| |10.3.0.0./24
============|vDUT-2|==========================|vDUT-4|===========================|vDUT-3|===========
[.160]eth1| |eth0 eth1| |eth0 eth0| |eth3[.200]
------ ------ ------
I ran the following cases :
* CASE 1 : connection on RESPONDER is defined with right=%any and NAT ROUTER changes IKE source port to something other than port 500 when INITIATOR initiates a connection
RESULT : RESPONDER responds and connection establishes successfully. See attached file "right=%any WORKING for nat-traversal when ike src port != 500"
* CASE 2 : connection on RESPONDER is defined with right=%any and NAT ROUTER keeps IKE source port 500 when INITIATOR initiates a connection
RESULT : RESPONDER responds and connection establishes successfully. Log file is similar to previous case.
* CASE 3 : connection on RESPONDER is defined with right=1.1.1.225 and NAT router keeps IKE source port 500 when INITIATOR initiates a connection
RESULT : RESPONDER responds and connection establishes successfully. See attached file "right=IP WORKING for nat-traversal when ike src port == 500"
* CASE 4 : connection on RESPONDER is defined with right=1.1.1.225 and NAT router changes IKE source port to something other than port 500 when INITIATOR initiates a connection
RESULT : RESPONDER complains that it cannot find a suitable connection for the received packet and does not respond to received Main Mode message. See attached file "right=IP NOT WORKING for nat-traversal when ike src port != 500"
So, the only case where Strongswan doesn't respond is "CASE 4" i.e. when right is defined as a specific IP address and the NAT router changes IKE source port to something other than 500. Trying to debug this in the code I found that changing the check below in find_host_pair_connections() makes Strongswan work for this case as well :
buildVM-debian-squeeze:~/mendocino/pkgs/vyatta-strongswan# git diff
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index 5b09556..06340a9 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -149,7 +149,7 @@ find_host_pair_connections(const ip_address *myaddr, u_int16_t myport
if (nat_traversal_enabled && hp && hisaddr)
{
struct connection *c;
for (c = hp->connections; c != NULL; c = c->hp_next)
{
- if (c->spd.this.host_port == myport && c->spd.that.host_port == hisport)
+ if (c->spd.this.host_port == myport)
return c;
}
return NULL;
}
The check *ONLY* happens when NAT-T is enabled and address of the remote-end [hisaddr] is defined. Trying to understand the code more, I also noted that the *ONLY* time find_host_connection() [function that calls the above changed function find_host_pair_connections()] gets called with a specific IP address is from main_inI1_outR1() [in pluto/ipsec_doi.c]. So, this change will only have an impact on cases where Strongswan is the responder to the first Main Mode message, NAT-T is enabled and right is defined as a specific IP.
Also, the following code in find_host_pair() [in pluto/connections.c] used by find_host_pair_connections() indicates that ports are to be ignored anyways when to trying to find a pair of hosts that match the received packet :
if (nat_traversal_enabled)
{
/**
* port is not relevant in host_pair. with nat_traversal we
* always use pluto_port (500)
*/
myport = pluto_port;
hisport = pluto_port;
}
However, ports are then checked again in find_host_pair_connections() when find_host_pair() [in pluto/connections.c] returns back to find_host_pair_connections().
So, there you have it. All interpretations and findings from the past couple of days on paper. It'd be nice if the Strongswan Maintainers took a look and provided their feedback on this.
Thanks in advance,
Mohit
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Topology for nat-traversal ike src port != 500 testing
Type: application/octet-stream
Size: 590 bytes
Desc: not available
URL: <http://lists.strongswan.org/pipermail/dev/attachments/20110127/044d70b8/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: right=IP NOT WORKING for nat-traversal when ike src port != 500
Type: application/octet-stream
Size: 4614 bytes
Desc: not available
URL: <http://lists.strongswan.org/pipermail/dev/attachments/20110127/044d70b8/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: right=%any WORKING for nat-traversal when ike src port != 500
Type: application/octet-stream
Size: 6164 bytes
Desc: not available
URL: <http://lists.strongswan.org/pipermail/dev/attachments/20110127/044d70b8/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: right=IP WORKING for nat-traversal when ike src port == 500
Type: application/octet-stream
Size: 5603 bytes
Desc: not available
URL: <http://lists.strongswan.org/pipermail/dev/attachments/20110127/044d70b8/attachment-0003.obj>
More information about the Dev
mailing list