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
Topology for nat-traversal ike src port != 500 testing
Description: Binary data
right=IP NOT WORKING for nat-traversal when ike src port != 500
Description: Binary data
right=%any WORKING for nat-traversal when ike src port != 500
Description: Binary data
right=IP WORKING for nat-traversal when ike src port == 500
Description: Binary data
_______________________________________________ Dev mailing list [email protected] https://lists.strongswan.org/mailman/listinfo/dev
