NAT: How Ten Thousand Devices Share One Address

Here is a small mystery hiding in plain sight on your desk. You have a laptop, a phone, a TV, a couple of smart plugs and a games console — a dozen devices, easily — and every one of them is on the internet right now. Yet your ISP handed you exactly one public address. Stranger still: the world officially ran out of fresh IPv4 addresses years ago, and yet here we all are, adding gadgets by the day. Both of those facts survive because of one gloriously pragmatic hack sitting in your router: Network Address Translation, or NAT — the duct tape holding IPv4 together.

The addresses nobody owns

Back in the subnets post I promised to come back to a special set of addresses, and this is where they earn their keep. Three ranges are set aside as private — free for anyone to use on their own network, precisely because they are barred from ever appearing on the public internet:

Tidbit: the private ranges (RFC 1918)

10.0.0.0/8 — 16.7 million addresses, the choice of big corporate networks. 172.16.0.0/12 — about a million, the awkward middle child nobody quite remembers. 192.168.0.0/16 — 65 thousand, the one printed on the sticker on the back of every home router. They are the internet’s equivalent of internal extension numbers: every office can have an extension 101, because it means nothing outside the building.

Your home network almost certainly lives somewhere in 192.168.x.x. Every device gets one of these private addresses, and none of them means a thing to the wider internet. Which raises the obvious question: if the internet has never heard of 192.168.1.20, how does the reply to your web request ever find its way back to you?

The trick: rewrite the envelope, keep a ledger

This is where the router on the edge of your network does its quiet magic. It has a foot in both worlds — a private address facing your devices, and the single public address facing the internet. When a packet from your laptop heads out, the router rewrites the source address: it scribbles out “from 192.168.1.20” and writes “from 203.0.113.5” — its own public address — instead, and, crucially, notes down in a table that it did so. When the reply comes back addressed to 203.0.113.5, the router consults that table, sees the reply belongs to your laptop, rewrites the destination back to 192.168.1.20, and hands it over. The internet only ever talks to the router; your laptop never knew it was being spoken for.

It is exactly a company switchboard. The outside world dials one main number and has no idea how many people work there. A call comes in; the receptionist, who wrote down that you were expecting it, puts it through to your desk. Everyone inside shares one public identity, and a ledger keeps the conversations from getting crossed.

One address, many conversations

Here is the part that makes it genuinely clever rather than merely tidy. If ten of your devices all talk to the same website at once, and the router rewrites every one of their source addresses to the same public address, how on earth does it tell the ten replies apart when they come back? The answer is port numbers. The router does not just track addresses; it tracks the full pairing of address and port, and hands each outbound conversation its own unique public port. A ledger row really reads “192.168.1.20:51000 is currently 203.0.113.5:40000”, and every simultaneous conversation gets its own row.

flowchart LR
  A["Laptop 192.168.1.20:51000"] -->|"out"| B["Router / NAT table"]
  B -->|"source now 203.0.113.5:40000"| C["Web server"]
  C -->|"reply to 203.0.113.5:40000"| B
  B -->|"back to 192.168.1.20:51000"| A

This flavour — many private hosts multiplexed behind one public address using ports — is the one virtually every home runs. You will see it called PAT (Port Address Translation), NAT overload, or just “masquerading”, depending on whose manual you are reading. Same idea under every name: one address, thousands of conversations, kept straight by port.

Which way did it rewrite? SNAT vs DNAT

Everything so far rewrites the source of an outbound packet, and that has a proper name: SNAT, source NAT — the “let my private devices out” direction. But you can just as well rewrite the destination of an inbound packet, and that is DNAT, destination NAT — the “let the outside reach a specific box inside” direction. Port forwarding is DNAT: traffic hitting your public address on port 443 has its destination rewritten to an internal web server. Load balancers lean on DNAT too, spreading incoming connections across a pool of backends.

TypeRewritesDirectionEveryday example
SNATSource addressOutbound (inside → out)Your devices sharing one public IP
DNATDestination addressInbound (out → inside)Port-forwarding to a home server
CGNATSource, againOutbound, at carrier scaleYour ISP NATing thousands of customers

The mnemonic that sticks: SNAT is for getting out, DNAT is for getting in. Nearly all the NAT you meet is SNAT quietly doing its job; DNAT is the deliberate exception you configure when something inside genuinely needs to be reachable from outside.

Turtles all the way down: CGNAT

Now for the uncomfortable twist. That “public” address your ISP gave you? It might not actually be yours. Because IPv4 addresses ran dry, many ISPs no longer have one to spare per customer — so they do the very same trick to you that you do to your devices. Carrier-Grade NAT (CGNAT) rewrites your traffic a second time, sharing one genuinely-public address across hundreds or thousands of subscribers. You are NATed behind your own router, which is NATed behind the carrier. Turtles all the way down.

It works fine for the ordinary case — browsing, streaming, anything you start — because that is all outbound, and outbound is what NAT is best at. Where it bites is anything that needs the outside world to reach in: hosting a server, certain peer-to-peer connections, the occasional game or video call that wants a direct path. Port forwarding cannot save you, because the hole you would need to punch is on a router you do not own — the carrier’s. It is also why an IP address is such a blunt instrument for identifying anyone: behind a single CGNAT address sits an entire neighbourhood.

The internal U-turn: hairpin NAT, loopback, reflection

Here is a puzzle that catches people out with grim reliability. Say you host a little server at home and reach it from outside via your public address — works perfectly. Now try to reach it from a laptop inside your own network, using that same public address, and it mysteriously fails. Why?

Follow the packet. Your laptop sends it to the public address, so up it goes to the router’s outside interface — except the destination is the router’s own public address, so the packet needs to spin around and come straight back down to a server three feet away. Plenty of routers simply do not expect traffic to arrive and depart through the same door, get confused, and drop it. The fix has three names for one idea: hairpin NAT (the packet makes a hairpin U-turn at the router), NAT loopback, or NAT reflection — pick your vendor’s spelling.

When it works, the router quietly does two rewrites at once: DNAT to aim the packet at the internal server, and SNAT so that server sees the request as coming from the router rather than directly from the laptop. That second rewrite is the subtle one. Without it, the server would reply straight to the laptop — but the laptop is expecting an answer from the public address, not from some unfamiliar box on the LAN, so it rejects the mismatched reply and the connection dies half-open. Hairpinning handles both halves so the round trip actually closes. The field-tech takeaway: when “it works from outside but not from inside”, hairpin NAT is your first suspect, and the cleaner fix is usually to reach internal services by their internal address — or to have your DNS hand internal clients the internal address in the first place (split-horizon DNS), which is a story for another day.

A firewall it is not (though it plays one on TV)

Warning

NAT gets casually credited as a security feature, and it is worth being precise about why that is only half true. It is the case that, by default, nothing outside can reach a device inside your network: there is simply no ledger entry for an unsolicited inbound connection, so the router has nowhere to send it and drops it. A genuine, useful side effect — but it is an accident of how NAT works, not a policy you chose, and it says nothing about traffic your devices invited in, or about anything nasty riding home on a connection you opened yourself. Treat NAT’s inbound-blocking as a happy bonus, never as your firewall. Run an actual firewall for that.

The footnote that outlives all of this: IPv6

Every word above exists because IPv4 is scarce — roughly four billion addresses for a planet wanting many times that number. IPv6 simply ends the scarcity: its address space is large enough to hand every grain of sand on Earth its own address and barely notice, so every device can hold a real, globally-routable address and NAT-for-conservation quietly retires. The one thing you keep is that accidental-firewall benefit — which on IPv6 you get deliberately, from a proper firewall, exactly as you should have all along. NAT was always the workaround; IPv6 is the fix that removes the need for it. The internet is just taking an extraordinarily long time to finish moving house.

The one-sentence version

NAT lets a whole network share one public address by having the border router rewrite addresses and remember what it rewrote — source rewriting (SNAT) to get your devices out, destination rewriting (DNAT) to let the outside reach something in, port numbers to keep thousands of conversations apart, and the same trick stacked again at the ISP (CGNAT) when even public addresses run short; it looks a little like a firewall from outside, it is not one, and IPv6 is the thing that eventually makes most of it unnecessary.

That more or less closes the loop the networking series opened: from a single web request in the very first post, down through frames and switches and VLANs and subnets, and now back out through the one address the whole lot hides behind. There is always more — NAT traversal, IPv6 in earnest, the first time you plug a cable into a bare switch — but that is quite enough envelope-rewriting for one sitting.