ike-natd: Float to the NAT-T port early when not connecting to port 500
When using port 4500 for IKE_SA_INIT, Windows Server 2016, 2025 and possibly others send back all packets to the port initially used by the client, not the one floated to before sending IKE_AUTH. So if UDP encapsulation is used, no traffic can be received as the initial socket can't have UDP decapsulation enabled. tcpdump output: ``` IP <client-ip>.47547 > <server-ip>.4500: UDP-encap: ESP(spi=0xfd4e5fc2,seq=...) IP <server-ip>.4500 > <client-ip>.57962: UDP-encap: ESP(spi=0xccc5e213,seq=...) ``` Avoid this by floating early if a non-default destination port is used. This also ensures we don't send packets from port 500 (without non-ESP marker) if ephemeral source ports are not used. Closes strongswan/strongswan#2664 Signed-off-by: Michael Braun <michael-dev@fami-braun.de> Co-authored-by: Tobias Brunner <tobias@strongswan.org>
This commit is contained in:
committed by
Tobias Brunner
co-authored by
Tobias Brunner
parent
882b19c1df
commit
bff500dfd0
@@ -340,7 +340,29 @@ METHOD(task_t, build_i, status_t,
|
||||
|
||||
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
|
||||
|
||||
host = message->get_source(message);
|
||||
host = message->get_destination(message);
|
||||
if (host->get_port(host) != IKEV2_UDP_PORT)
|
||||
{
|
||||
/* if not connecting to port 500, the destination socket has to enable
|
||||
* UDP-encap (we can't float to a different destination port later
|
||||
* if there is a NAT), so we have to use non-ESP markers from the start.
|
||||
* that is, our source port can't be 500 at this point. we can use two
|
||||
* different ephemeral ports and float from one to the other as we'd do
|
||||
* normally (if neither port is 500, a marker is added). unfortunately,
|
||||
* some implementations don't reply to the correct port when we do that,
|
||||
* breaking UDP-encap as our first socket can't process such messages.
|
||||
* so we switch now, which ensures (1) that we don't send from port 500
|
||||
* if no ephemeral ports are used and (2) that the source port doesn't
|
||||
* change later (at least not because of us) */
|
||||
this->ike_sa->float_ports(this->ike_sa);
|
||||
host = this->ike_sa->get_my_host(this->ike_sa);
|
||||
message->set_source(message, host->clone(host));
|
||||
}
|
||||
else
|
||||
{
|
||||
host = message->get_source(message);
|
||||
}
|
||||
|
||||
if (!host->is_anyaddr(host) || force_encap(ike_cfg))
|
||||
{
|
||||
notify = build_natd_payload(this, NAT_DETECTION_SOURCE_IP, host);
|
||||
|
||||
Reference in New Issue
Block a user