How NAT Traversal Works
The backbone of peer-to-peer traffic explained
Open inbound ports are a major security risk. That’s why Twingate’s platform is architected so it never requires inbound ports to be open anywhere. However, end users still need to be able to reach Connectors to gain access to your private resources. So, how does that happen if there aren’t any open ports?
There are two ways to do this under our security model:
- Using an intermediary in a public cloud that Clients and Connectors can connect to and transfer packets to and from (this is the secondary role that our Relays play and the reason why we have Relays deployed across the globe).
- Using something called network address translation (NAT) traversal to establish peer-to-peer tunnels between Clients and Connectors.
We’ll cover Relays later in this article, but because they are far more intuitive to understand than NAT traversal, we’ll focus on what it takes to establish a secure channel of communication (also called a peer-to-peer or P2P tunnel) between a Client and Connector without opening any public inbound ports.
Let’s peek behind the curtain and review what makes NAT traversal possible and how it works. First, we need to define a few things, including what NAT is, what ports are, and how firewalls work, at a high level.
What NAT is and how you use it every day at home
When Charlie connects to her Wi-Fi network in Seattle, her laptop gets assigned an IP address, say 192.168.1.4
. When Linus is connected to his own Wi-Fi network in New York, his laptop is, coincidentally, also assigned 192.168.1.4
on that network.
Now, if both Charlie and Linus simultaneously connect from their devices to lego.com, the lego.com server needs to have a way to respond to both separately even though both devices have the same IP address.
The reason this works just fine and doesn’t break the internet constantly is because the IP address they both use (192.168.1.4
) is not a public IP address. In fact, it’s part of a range of IP addresses that is reserved for private networks - they can be (and are) reused across many unrelated private networks. They cannot be used as public IP addresses.
Public IP addresses, on the other hand, are globally unique and are the reason why lego.com can respond to Charlie’s device without responding to Linus’ computer instead, even though they have the same private IP address.
From the perspective of the lego.com server, Charlie’s laptop sent a request from a unique public IP address assigned to her by her internet service provider (ISP) (say, 174.21.179.34
), while Linus’s device is assigned a different public IP address by his ISP (say, 121.56.6.12
). That’s why there is no ambiguity for lego.com and it can respond to everyone without internet wires getting crossed.
The process of getting traffic originating from a non-unique private IP address like 192.168.1.4
to becoming a request from a unique public IP address at 174.21.179.34
is NAT at work. As the “T” in NAT implies, NAT translates Charlie’s private network address (the “NA” in NAT) into a public IP address so that lego.com can respond to her without accidentally sending those packets to another device (and without knowing anything about Charlie’s private network).
NAT also works in the other direction. It translates packets sent to Charlie’s public IP address (from lego.com) back to her device’s private IP address on her private network. This is essential because, as we saw, when lego.com talks to Charlie at 174.21.179.34
, it cannot know which device on that private network actually made the request (since lego.com knows nothing about Charlie’s private network. From lego.com’s perspective, all the devices in Charlie’s network making requests to lego.com look like they come from the same public IP address).
How then does the request come back to Charlie’s device at 192.168.1.4
and not to, say, her brother Moose who, from another device connected to the same private network, is also browsing lego.com at the same time (e.g. from 192.168.1.3
)?
You guessed it, it’s also NAT. The NAT device (most likely a router for users at home) keeps track of what private IP addresses have sent packets to which public IP addresses, so when packets come back from that public address, the NAT device knows which private IP address they should go to, even though lego.com sends everything to the public IP address.
Now, before we get into how that process works, we need to explain what ports are.
Introducing ports
How does a router keep track of sessions initiated by different devices on its private network, in practice? It uses ports.
You can think of an IP address as a postal address to an apartment building with many units. If you want to visit your friend and know the address to their building, you’ll also need to know your friend’s apartment number. That’s what ports are: individual units you can visit (connect to) that are attached to a single (IP) address.
Each IP address comes with a staggering 65,535 ports. Quite the massive apartment complex.
In practice, ports are always used when your computer connects to another device: your laptop doesn’t just connect to another device’s IP address, it actually connects to a specific port + IP address combination.
You can observe this in your browser when you visit any website. Pick any URL you go to regularly and add “:443” right after the website’s domain name. Doing so will tell your browser that you want to connect port 443 on the server hosting the website. For instance, connect to https://lego.com:443
instead of https://lego.com
.
See any difference when adding the port number? No? That’s because when you connect to https://lego.com, you automatically get connected to port 443. Your browser knows that https connections, by convention, occur over port 443, but hides that information because the majority of people do not need to know what port is being used.
How NAT uses ports
Back to our scenario. Charlie and Moose now both connect to lego.com from different devices on the same Wi-Fi network at home. Both devices have different private IP addresses, but from the perspective of lego.com, they both appear to have the same public IP address.
The reason it doesn’t create any ambiguity is because lego.com isn’t just responding to our unique public IP address, it’s actually responding to our unique public IP address on two different ports (one assigned to Charlie’s device, the other one to Moose’s). Since the public IP address + port combination is unique, it allows the router to determine which connection is meant for which device.
Practically speaking, the browser on Charlie’s device is assigned an arbitrary port (say 6789) and the browser on Moose’s device is assigned another one (say 6543). When they both connect to lego.com (or anything else on the internet), the NAT device replaces the source IP address (which is the private IP address in this case) and the source port with its public IP address (common to both Charlie and Moose) and a newly assigned port number (which is different for Charlie and Moose).
Now the lego.com server sees two incoming connections from the same public IP address, but one is from port 6789 and the other is from port 6543. All the server needs to do is to respond to the same public IP address on the appropriate port. In other words, the lego.com web server makes two separate connections: one on the port assigned to Moose’s device and one on the port assigned to Charlie’s device.
The NAT device at home performs the reverse translation when those packets flow back - that’s how it knows which packets are intended for which device.
(In reality it’s a bit more complex, but this is a good enough approximation for our purposes here.)
How firewalls typically work
Firewalls protect you from all the wild stuff on the internet and can also act as NAT devices that do roughly two things:
- they let things out: that is, they allow network packets to flow from your private network out to the internet
- they keep things out: that is, they block network packets from entering from the internet from connections initiated from outside the network to your public IP address
When it comes to NAT traversal, the most important thing to understand about firewalls is that they can let packets flow in from a public IP address and port combination if and only if packets first flowed out through that combination from a connection initiated from within the private network. That’s why the lego.com server is able to send its webpages to your browser - because your browser first connected and sent some packets to it.
It makes logical sense: if your computer on your private network tries to connect somewhere public (like a website), it is likely deliberate and safe, so it’s allowed through (and responses are allowed to come back). However, if something on the internet tries to connect into your private network (without any prior connection to it from within)… that probably isn’t safe at all.
Note that it is possible to configure your NAT device to allow incoming connections from the public internet. For example, if you wanted to connect to a device in your private home network when you are not at home.
This is often referred to as port forwarding in consumer grade routers and firewalls, where you can designate a port that accepts incoming connections from the internet (this is called an “open” port). But, before you open any port, let’s make something crystal clear: opening a port to the internet is generally a terrible idea and is asking for trouble.
As soon as you open a port, random things out on the internet will see it and try to connect to it. Bots continually scan public IP addresses for open ports and nefarious actors attempt to probe them for vulnerabilities. It doesn’t matter who you are - if you have a port open, it will get connection attempts dozens of times a day and nothing good will comes from that.
How VPN gateways work
If you want to remotely access your own private network, you already know what a VPN is - VPNs are designed to allow remote devices to securely connect to private networks, over the internet.
They are usually built based on a client-server architecture: a VPN client on a user’s device connects to a VPN server (or gateway) sitting behind the firewall; the VPN server verifies the user’s credentials and then grants their device access to the private network and assigns it a private IP address on it. From that point on, the device is considered to be “on” the private network even though it’s not physically connected to it in any way.
The server component of VPNs – the gateways – are not inherently bad, except for one critical aspect: for a VPN client to connect to a gateway, the gateway typically listens for inbound connections from clients on the internet via an open port which is, as we mentioned before, a bad idea. For example, if the VPN server has a vulnerability, that vulnerability could be exploited by anyone on the internet (there are numerous examples) of this occurring).
It matters little how robust server side security is - if a port is open and there exists some obscure technical method to circumvent its security and gain access, someone will figure it out and you will be in trouble.
Seriously, don’t open inbound ports to the internet.
Now, back to the central question: How can you securely allow a remote connection to a private network without opening any ports on your network devices?
Letting things in without opening a port
Solution 1: Relays
Since firewalls are basically one-way doors, why not allow the clients and servers to connect to some public third party that can facilitate connectivity between the two sides?
The way this works is that both the client and server initiate outbound connections to this intermediary, and the intermediary (which now has the ability to send packets back to both the client and the server) can facilitate two-way communications between both sides. This way, all parties behind a NAT device only need to make an outbound connection.
While this method can work well (and is one method Twingate uses), there are some considerations to keep in mind:
- introducing an intermediary means more hops and therefore potentially more latency
- the connection between the client and server should be encrypted in a manner that is outside of view of the intermediary so that it cannot decrypt the communications flowing through it (this is often referred to as end-to-end encryption)
Both of those considerations are the reason why Twingate maintains Relays worldwide and why Clients and Connectors encrypt their traffic without any involvement from Relays: it makes it impossible for the Relay to decrypt that traffic (short of breaking the encryption algorithm that was used).
Solution 2: NAT traversal
Introducing an intermediary can work, but what if we can remove the extra hop, cut out the intermediary, and establish peer-to-peer connection instead? That is where NAT traversal comes in.
How NAT traversal works
We have now established a couple of very important things about firewalls:
- they allow network packets to flow from your private network to anywhere on the internet
- they block network packets initiated from the internet and sent to your private network
- network packets from a public IP address are allowed to flow back in if they first flowed out to the same address & port
To explain what happens when NAT traversal is at work, let’s abstract away the nuances of IP addresses, ports and firewalls and pretend that the Client and Connector are two unacquainted guests (Charlie and Linus) staying at the same hotel. Charlie and Linus want to securely send each other written notes.
Let’s also establish some rules:
- Charlie and Linus can both send notes to any other hotel room but they need a hotel room number and the last name of the guest occupying the room to do so (Charlie is the Client and Linus is the Connector. They can both connect and send packets to anything public if they have an IP address and port)
- Charlie and Linus can only receive a note from another hotel guest if they sent that guest a note first (the Client can only receive packets from the public IP and port of the Connector if the Client has previously sent packets to the Connector)
- Charlie and Linus start with no knowledge of each other’s last name or hotel room number (the Client and Connector have no prior knowledge of each other’s public IP addresses or ports)
- Charlie and Linus want to send each other notes without an intermediary (Client and Connector want to establish peer-to-peer communications)
- Charlie and Linus can both call and rely on the hotel manager (the Relay acts as a trusted intermediary)
How Charlie and Linus establish a peer-to-peer connection
- Charlie and Linus both call the hotel manager to report their own room number and last name (the Relay, in this case, acts as a STUN server, and is also a broker of information between both parties)
- The manager responds to Charlie by sharing with her Linus’s last name and room number (and responds to Linus by sending him Charlie’s information)
- Charlie then sends a note to Linus’s room while Linus simultaneously sends a note to Charlie (the Relay coordinates timing of the Client and Connector initiating outbound connections to one another at the same time)
- Since Linus can receive a note from Charlie only if he already sent one to her, and since he sent a note to Charlie already, he is allowed to receive Charlie’s note (and vice versa)
- Now Linus and Charlie can send notes to each other’s room back and forth without restriction!
How the Client and Connector establish a peer-to-peer connection
- The Relay facilitiates the creation of a Relay-based end-to-end encrypted tunnel between the Client and Connector to be used as a messaging channel
- The Client and Connector exchange their public IP address and port combination via the messaging channel
- The Client sends packets to the Connector’s public IP address and port (and the Connector sends packets to the Client’s public IP address and port)
- Because the Client sent packets to the Connector, it lets in packets sent from the Connector and vice versa
- Now we have a peer-to-peer connection without having any open inbound ports!
This is basically how NAT traversal manages to allow a peer-to-peer tunnel without any inbound open port!
Note that certain network conditions may prevent a peer-to-peer connection from being established. For troubleshooting tips on peer-to-peer and NAT traversal, head over to our troubleshooting guide.
Last updated 5 months ago