Today I want to take a closer look about what UDP hole punching is and how it works. Commonly it is used by peer-to-peer software where clients homed in the internal network and sitting behind a NAT firewall, needs to communicate directly with other remote clients also sitting behind a NAT firewall.

By default these clients cannot communicate with each other as they couldn’t be reached directly through an endpoint using the public IP and port number (socket).


Behind a firewall usually homed multiple internal computers with internal IPv4 addresses. In order they can communicate with the public internet, they need a public IPv4 address which is routeable over the internet.

This post doesn’t cover IPv6 which does not mandatory needs NAT. Nevertheless also IPv6 supports some NAT techniques.

The equivalent to NAT in IPv4 (aka NAT44) is NAT66 for IPv6. It is also a stateful network address translation on a router or firewall. It will translate an IPv6 address from one interface and network into another IPv6 address assigned on another interface and network. Further NAT66 also provides port address translation (PAT, in IPv6 called PAT66) but is not really needed because of the large supply of IPv6 addresses.

Another NAT technique for IPv6 is IPv6 Network Prefix Translation (NPt)

NPt does NOT function like traditional outbound/overload NAT/PAT. NPt cannot be used to map an internal prefix to prefix or single address in use on a WAN, it must be used with a routed prefix.
https://docs.netgate.com/pfsense/en/latest/nat/npt.html

There is also one more NAT technique which will establish communication between IPv6 and IPv4 hosts and is named NAT64.

https://en.wikipedia.org/wiki/NAT64


The firewall or router will translate the computers internal IPv4 address into its external public IPv4 address assigned on the WAN interface from the router. By doing this the router will also maintain a NAT table where each row in the table is basically a mapping from one private address to one public address.

Further the router will not only translate the internal IP address into a public one, it will also maybe translate the internal port number (source port) the computer is using to establish an outbound connection into another source port. This is normally the case if multiple internal computers wants to establish a connection to the same external system and destination port and randomly the same internal source port was assigned dynamically.

If in that case the router would just translate the internal IP address into the external and appending the same source ports for the mapping in its NAT table, the router wouldn’t be able to send the reply packages to the correct internal computer as there were some identical mapping entries in its table.

Therefore the NAT table will also maintain the mapping (translation) of the ports aka port address translation (PAT).

RFC 2663 uses the term network address and port translation (NAPT) for this type of NAT. Other names include port address translation (PAT)IP masqueradingNAT overload and many-to-one NAT. This is the most common type of NAT and has become synonymous with the term NAT in common usage.

Source: https://en.wikipedia.org/wiki/Network_address_translation


So by using NAT the internal computers are able to connect to external systems on the internet. The other way accessing the internal computers from the internet by default is not possible and initiated connections would be dropped by the firewall.

The only traffic the firewall will allow inbound to the internal computers, are the reply traffic for the requests coming from the internal clients. So if a client for example is opening a website, the reply traffic from the external webserver will of course be routed back to the client.

To determine what traffic is legitimate and that the reply is from a request coming from an internal client, the firewall will use its NAT table as mentioned above.


Now how does peer-to-peer software like for example Skype get around the problem that you normally could not inititate a connection from outside to an internal client.

To get around the peer-to-peer software needs to pretend against the firewall, that there is still a connection between the internal client and the external peer-to-peer software, and therefore traffic from the peer-to-peer software is inbound reply traffic for the request initiated from the internal client.

Skype for example anyway will use for audio traffic the stateless UDP protocol which just includes the IP addresses and ports from the source- and destination system. If they will match for incoming traffic with the NAT table from the firewall, the packets will be routed to the internal computer.

TCP hole punching is much more complex as TCP is a stateful protocol and each packet will include additional connection state information.




Steps Peer-to-Peer Software will perform to do UDP Hole Punching

Below I will describe in a simplified way the separate steps how peer-to-peer software will establish a direct connection between two internal clients.

Suppose we have have two internal clients named John and Fred.

John’s external IP is 1.1.1.1
Fred’s external IP is 2.2.2.2


In order that John’s client can initiate a direct connection to Fred’s client, first John needs to know under which public IP address and port number Fred’s client is listening at the moment.

Therefore we need a third party homed in the internet which takes the role of a mediation server (STUN & TURN server).

The mediation server usually will also be a STUN and TURN server, more about both roles you will find further below in my post.


Both clients will establish an outbound connection to the mediation server. Therefore the mediation server knows from both clients, which public IP address and port they used to connect to it and listening for reply traffic.

The mediation server will also cause the clients to initiate a program specific request to determine the used source port for. For example Skype will initiate an audio test to see which source port will be used for transmitting audio data.

For our example we assume John is using the source port 33200 for this specific peer-to-peer software and Fred is using 44200.


If now John’s client now wants to connect to Fred’s client, John is first announcing the request to the mediation server. The mediation server then will send the public IP and port number John is using for the specific program (Skype audio port) to Fred’s client, in our case it is the source port 33200.

This is the moment where Fred’s client will punch a hole in its own firewall by sending an UDP packet to John’s public IP 1.1.1.1 and source port number 33200.


The firewall from John now of course will drop the packet as it won’t find a match for the mapping in its NAT table.

The firewalls NAT table will only contain a mapping between John’s client and the mediation server.


Nevertheless Fred’s firewall won’t notice that John’s firewall was dropping the UPD packet, because UDP is as stateless protocol. But from now on Fred’s firewall maintains a mapping in its own NAT table that there is a connection outbound from Fred’s client to John’s client IP address 1.1.1.1 and destination port 33200.

Therefore Fred’s firewall will assume from now on, that UDP traffic coming from John’s client IP address 1.1.1.1 and port 33200, will be the reply to the request from Fred’s client and be legitimate and route it to Fred’s client.

Now the mediation server will send the public IP 2.2.2.2 from Fred and its port number 44200 to John’s client which is then trying to connect to Fred’s client by using the destination socket 2.2.2.2:44200 and its own source socket 1.1.1.1:33200.

As Fred’s firewall have a coresponding mapping in its NAT table as mentioned, traffic will be assumed as reply (legitimate traffic) and be routed to Fred’s client. In case of Skype it will ringing on Fred’s site.


As mentioned this process is simplified and the details will depend from the deployed firewalls and how they exactly handle NAT traffic.

Not all NATs are the same, below I will therefore show some different NAT types and technologies that will be used to finally realize UDP hole punching or get around if not possible.

If the router (firewall) will use symmetric NAT, you will not be able to realize UDP hole punching and you will need the help from Traversal Using Relays around NAT (TURN).



NAT Types

Network address translation is implemented via a number of different address and port mapping schemes, none of which is standardized.

I will focus here on four types which will be used by the Session Traversal Utilities for NAT (STUN) protocol, originally called Simple Traversal of User Datagram Protocol (UDP).


Full cone NAT

A full cone NAT is one where all requests from the same internal IP address and port, below 192.168.195.10:49555 are mapped to the same external IP address and port, below 240.155.140.50:50660.

Furthermore, any external host can send a packet to the internal host, by sending a packet to the mapped external address and port, here 240.155.140.50:50660.



Address restricted cone NAT

An address restricted cone NAT is one where all requests from the same internal IP address and port, below 192.168.195.10:49555 are mapped to the same external IP address and port, below 240.155.140.50:50660.

Unlike a full cone NAT, an external host (e.g. Computer 1) can send a packet to the internal host only if the internal host had previously sent a packet to the IP address from Computer 1. Because Computer 2 and Computer 3 had different IP addresses, they could not use the external NAT socket from the internal computer and connection requests would be dropped by the router.




Port restricted cone NAT

A port restricted cone NAT is like an address restricted cone NAT, but the restriction includes port numbers.

Specifically, an external host (e.g. webserver below) can send a packet, with source IP address 184.30.21.171 and source port 80, to the internal host (external NAT socket 240.155.140.50:50660) only if the internal host had previously sent a packet to IP address 184.30.21.171 and port 80. (e.g. request a website on the webserver)



Symmetric NAT

A symmetric NAT is one where all requests from the same internal IP address and port, to a specific destination IP address and port, are mapped to the same external IP address and port.

If the same host sends a packet with the same source address and port, but to a different destination, a different mapping is used.

Furthermore, only the external host that receives a packet can send a UDP packet back to the internal host.

Unlike port-restricted cone NAT that maps all requests from the same private IP address and port to the same public IP address and port, regardless of their destinations, symmetric NAT maps requests with the same source IP address and port number but different destinations to a different mapping. (different IP address and port or same IP address but at least different port)




STUN  (Session Traversal Utilities for NAT; originally Simple Traversal of User Datagram Protocol (UDP) through Network Address Translators)

STUN provides a tool for hosts to discover the presence of a network address translator, and to discover the mapped, usually public, Internet Protocol (IP) address and port number that the NAT has allocated for the application’s User Datagram Protocol (UDP) flows to remote hosts. The protocol requires assistance from a third-party network server (STUN server) located on the opposing (public) side of the NAT, usually the public Internet.

Source: https://en.wikipedia.org/wiki/STUN



TURN (Traversal Using Relays around NAT)

TURN is a protocol that assists in traversal of network address translators (NAT) or firewalls for multimedia applications. It may be used with the Transmission Control Protocol (TCP) and User Datagram Protocol (UDP). It is most useful for clients on networks masqueraded by symmetric NAT devices. TURN does not aid in running servers on well known ports in the private network through a NAT; it supports the connection of a user behind a NAT to only a single peer, as in telephony, for example.

Session Traversal Utilities for NAT (STUN) provides one way for an application to traverse a NAT. STUN allows a client to obtain a transport address (an IP address and port) which may be useful for receiving packets from a peer. However, addresses obtained by STUN may not be usable by all peers. Those addresses work depending on the topological conditions of the network. Therefore, STUN by itself cannot provide a complete solution for NAT traversal.

A complete solution requires a means by which a client can obtain a transport address from which it can receive media from any peer which can send packets to the public Internet. This can only be accomplished by relaying data through a server that resides on the public Internet. Traversal Using Relay NAT (TURN) is a protocol that allows a client to obtain IP addresses and ports from such a relay.

Although TURN almost always provides connectivity to a client, it is resource intensive for the provider of the TURN server. It is therefore desirable to use TURN as a last resort only, preferring other mechanisms (such as STUN or direct connectivity) when possible. To accomplish that, the Interactive Connectivity Establishment (ICE) methodology can be used to discover the optimal means of connectivity.

Source: https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT



ICE (Interactive Connectivity Establishment)

ICE is a protocol for Network Address Translator (NAT) Traversal that leverages both above protocols, STUN and TURN.



Determine the NAT Type

In order to determin the NAT type your router or firewall will utilize, you can use the following PowerShell script from Microsoft.

Troubleshoot RDP Shortpath for public networks
https://learn.microsoft.com/en-us/azure/virtual-desktop/troubleshoot-rdp-shortpath




Links

UDP hole punching 
https://en.wikipedia.org/wiki/UDP_hole_punching

TCP hole punching
https://en.wikipedia.org/wiki/TCP_hole_punching

Network address translation (NAT)
https://en.wikipedia.org/wiki/Network_address_translation

Network address translation
https://en.wikipedia.org/wiki/Network_address_translation#Symmetric_NAT

STUN
https://en.wikipedia.org/wiki/STUN