NAT Traversal (NAT-T) » History » Version 12

Version 11 (Tobias Brunner, 29.03.2018 11:06) → Version 12/13 (Tobias Brunner, 05.11.2018 14:50)

h1. NAT Traversal (NAT-T)

{{title(NAT Traversal (NAT-T))}}

The IKEv2 protocol includes NAT traversal (NAT-T) in the core standard, but it's optional to implement. strongSwan implements it and does not require any special configuration. The @NAT_DETECTION_SOURCE/DESTINATION_IP@ notifications included in the @IKE_SA_INIT@ exchange indicate the peer's NAT-T capability and allow detecting which peer, if any, is behind a NAT device. If a NAT situation is detected, the client switches to UDP port 4500 to send the @IKE_AUTH@ request (only if it used port 500 initially, see below regarding custom ports) and UDP encapsulation will be activated for IPsec SAs.

NAT-T cannot be disabled in the charon IKE daemon. If you don't like the automatic port floating to UDP/4500 due to the [[MobIke|MOBIKE protocol]], which happens even if no NAT situation exists, then you can disable MOBIKE by disabling the _mobike_ option in your connection definition.

h2. UDP Encapsulation of ESP

Because ESP packets are unidirectional, NAT devices can't map them like they do with e.g. TCP/UDP packets by using the source and destination ports in those headers. Some NAT devices have a feature, often called something like "IPsec passthrough", that detects IKE traffic from a single host behind the NAT and will forward incoming plain ESP packets to that host. But that won't work with multiple clients behind the same NAT that use the same server. To allow multiple clients UDP encapsulation is used. Adding a UDP header to the ESP packets allows NAT devices to treat them like the IKE packets (or any other UDP packets) and to maintain port mappings to forward the packets from/to the correct hosts behind the NAT.

The UDP-encapsulated ESP packets are sent on the same ports used for IKE traffic. To distinguish them from IKE packets the latter are modified so they contain four zero bytes right after the UDP header where the SPI is located in ESP packets (known as "non-ESP marker"). This means that the UDP socket/port (4500 by default) has to handle traffic differently than the default IKE socket/port. This has some implications when using a custom server port (see below).

UDP encapsulation may also be forced, even if no NAT situation is detected, by using the _forceencaps_ and _encap_ options in [[ConnSection|ipsec.conf]] and [[swanctl.conf]], respectively. If enabled, the daemon will send a fake @NAT_DETECTION_SOURCE_IP@ notify payload so it looks to the peer as if there is a NAT situation.

h2. NAT-T Keepalives

strongSwan starts sending keepalive packets if it is behind a NAT to keep the mappings in the NAT device intact. The interval for these small packets (a single @0xff@ byte after the UDP header) may be configured with the _charon.keep_alive_ [[strongswan.conf]] option (set to 0 to disable sending keepalives, e.g. behind a static DNAT aka port forwarding).

h2. Custom Server Ports

When using custom server ports, the client, for simplicity, only uses a single remote port, configured in _rightikeport_ and _remote_port_ in [[ConnSection|ipsec.conf]] and [[swanctl.conf]], respectively. This means that there will not be a port switch while establishing the connection. As described above, if UDP encapsulation is used, the ESP packets are sent on the ports already used for IKE traffic. Therefore, the server must be prepared to process UDP-encapsulated ESP packets on that custom port and, consequently, is only able to accept IKE packets with non-ESP marker on it. That in turn forces the client to send all its IKE packets (including the initial @IKE_SA_INIT@ request) with a non-ESP marker, otherwise, they would be treated as UDP-encapsulated ESP packets.

This has implications for the client and the server configuration:

* *Server*: Because the client has to connect to a socket/port that is prepared to process UDP-encapsulated ESP packets, the right setting to specify a custom port is _charon.port_nat_t_. The _charon.port_ setting is not relevant in this scenario (i.e. the default socket/port will not be used, hence, inbound traffic to port 500 could be blocked).
* *Client*: The client must add a non-ESP marker when sending IKE packets to a custom server port or port 4500. strongSwan adds one if neither source, nor destination port is 500. This means the client can't use port 500 in order to 500, so that it will already add a non-ESP marker when sending the initial @IKE_SA_INIT@ request. This can be achieved by either setting the local port used for IKE (_leftikeport/local_port_) (_leftikeport_/_local_port_) to 4500, or by setting _charon.port_ on the client to either 0 (to allocate (so a random port) port is allocated) or any number != 500 (if if that port is not used by any other process) process so the source port won't be 500 and does not have to be set explicitly in the connection config. If the latter is done, the client will, however, switch to the second source port configured via _charon.port_nat_t_ if a NAT is detected or MOBIKE is enabled, so setting both to 0 usually makes most sense for mobile clients that connect to a custom server port (but leaving that at 4500 is usually also not a problem).

h2. IKEv1

Before strongSwan version:5.0.0, NAT discovery and traversal for IKEv1 had to be enabled by setting _nat_traversal=yes_ in the [[ConfigSetupSection|config setup]] section of [[IpsecConf|ipsec.conf]]. Otherwise, strongSwan 4.x's IKEv1 pluto daemon would not accept incoming IKE packets with a UDP source port different from 500. Since version:5.0.0 IKEv1 traffic is handled by the charon daemon, which supports NAT traversal according to "RFC 3947": (and some of its early drafts) without having to enable it explicitly (it can't be disabled either, though).