NAT Explained: SNAT, DNAT, PAT, and When Translation Is the Right Answer
Open the network settings on whatever device you are reading this on and you will almost certainly find an address like 192.168.1.37. Ask any website what address your traffic arrives from, and it will report something entirely different. The machinery between those two facts is NAT (Network Address Translation), a router rewriting the addresses on every packet that crosses it, and it runs so universally that most internet traffic now passes through at least one translator on the way to anywhere. The reason is arithmetic. IPv4 offers about 4.3 billion addresses for a planet with far more devices than that, so a standards document called RFC 1918 set aside three address ranges that anyone may reuse privately, ranges we toured in the 10 reserved IP ranges every engineer should know. Private addresses solve numbering inside your own walls, but the internet refuses to carry them, so at the boundary something has to swap them for public ones. That swap has accumulated a confusing pile of names, SNAT, DNAT, PAT, masquerade, overload, static, one-to-one, twice NAT, and this post sorts them out, then takes on the harder question: when translation is the right tool, and when it is a debt that quietly compounds.
The mechanics underneath every variant are the same. An IP packet carries two addresses in its header, a source and a destination, and a NAT device rewrites one or both as the packet passes through, noting what it changed in a translation table so it can reverse the edit on the reply. Suppose your laptop at 192.168.1.37 opens a connection to a web server at 203.0.113.80. The router replaces the source address with its own public address, say 198.51.100.7, records the mapping, and forwards the packet. When the server answers, the reply arrives addressed to 198.51.100.7, the router looks up the mapping, and the destination is rewritten back to 192.168.1.37. (If the slash notation in ranges like 10.0.0.0/8 is unfamiliar, our visual guide to CIDR notation covers it from scratch; the public addresses in these examples come from the blocks reserved for documentation, so they will never collide with anything real.) Two properties fall out of this design and explain most NAT behavior in the wild. Translation is stateful, meaning the reply only works because the router remembers the outbound packet, and it is directional, meaning someone has to send the first packet before a mapping exists at all.
Every term in the NAT vocabulary answers two questions: which of the two address fields gets rewritten, and whether port numbers are rewritten too so that many devices can share one address. Hold each name against those two questions and the fog lifts quickly.
| Term | What gets rewritten | First packet | Typical job |
|---|---|---|---|
| Static one-to-one NAT | One private address paired with one public, both directions | Either side | Permanent public identity for a private server |
| SNAT (source NAT) | Source address on the way out | Outbound | Fixed egress identity for allowlists and email |
| PAT (port address translation) | Source address and source port | Outbound | A whole network sharing one public address |
| DNAT (destination NAT) | Destination address, often the port too | Inbound | Port forwarding, publishing internal services |
| Twice NAT | Source and destination at once | Either side | Connecting networks with overlapping ranges |
SNAT rewrites the source. The simplest form is static one-to-one NAT, a permanent pairing between one private address and one public one: your mail server lives at 10.20.8.25 internally and appears to the world as 198.51.100.25, with every packet in either direction rewritten between the two. One-to-one mappings matter wherever the outside world cares about your exact address. SPF (Sender Policy Framework) records list the addresses allowed to send your email, banks and partners allowlist the addresses permitted to call their APIs (application programming interfaces), and both break the moment your server starts leaving through a different public address than the one on file. Because the pairing is fixed and involves no ports, it also works in reverse; an outside host can initiate a connection to 198.51.100.25 and reach the mail server, which makes one-to-one NAT a full public presence for a private machine, with the firewall deciding what actually gets through.
PAT (Port Address Translation) is what nearly everyone actually runs, including the router in your house. One-to-one translation spends a public address per private device, which does nothing for scarcity, and PAT breaks that limit by rewriting the source port along with the source address. TCP (Transmission Control Protocol) and UDP (User Datagram Protocol) connections are distinguished by port numbers, roughly 64,000 of them per address per protocol, so a single public address can carry tens of thousands of simultaneous connections as long as the translator assigns each one a unique port and remembers who owns it. Cisco documentation calls this NAT overload, Linux calls it masquerading when the public address is learned dynamically, and your ISP (Internet Service Provider) may run it at enormous scale under the name CGNAT (carrier-grade NAT), pooling thousands of customers behind a few public addresses drawn from the 100.64.0.0/10 block, the same range Kubernetes teams borrow for pod networks in our guide to IP planning for Kubernetes. The port trick has limits worth knowing: heavy users can exhaust the pool, and applications that open hundreds of connections apiece, which modern browsers and sync clients cheerfully do, make the math tighter than 64,000 sounds.
DNAT points the same machinery inward. Traffic arrives addressed to a public address, and the translator rewrites the destination so the packet lands on a private machine the outside world could never reach directly. The port forward on a home router is DNAT in its smallest form, sending everything that arrives on port 443 to the workstation running your side project. At work the same idea scales up: the address your customers connect to is a public front, and DNAT, often living inside a load balancer, rewrites arriving connections toward whichever private servers do the real work. Each DNAT rule is a deliberate hole through the boundary, so publish exactly what you intend and verify it from the outside rather than trusting the config; our free port scanner checks from a neutral vantage point which ports actually answer. DNAT also produces a classic surprise: an internal user browsing to the company's own public address may fail while outsiders connect fine, because the connection has to leave and re-enter through the same translator, a contortion called hairpin NAT that some equipment handles gracefully and some simply drops.
All three translations as Linux firewall rules
# Static SNAT: the mail server always leaves as 198.51.100.25
iptables -t nat -A POSTROUTING -s 10.20.8.25 -o eth0 \
-j SNAT --to-source 198.51.100.25
# PAT: everyone else shares the router's public address, ports multiplexed
iptables -t nat -A POSTROUTING -s 10.20.0.0/16 -o eth0 \
-j MASQUERADE
# DNAT: connections arriving on port 443 land on the internal web server
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 \
-j DNAT --to-destination 10.20.8.30
The last variant earns its keep in exactly one situation: two networks that must talk while using the same address ranges. Twice NAT rewrites both fields at once, so each side sees the other through a borrowed, non-overlapping range while keeping its own real addresses. This is the "NAT at the seam" that carries the first weeks of a merger, and our survival guide to merging networks after an acquisition walks through the full playbook, including why the seam needs a written expiration date. One vocabulary trap to defuse: engineers also say "double NAT" for something unrelated, two ordinary PAT layers stacked on top of each other, as when your own router masquerades behind an ISP box that masquerades again. Stacked PAT mostly works, but inbound publishing, peer-to-peer traffic, and anything latency-sensitive degrades a little at each layer.
Now the honest accounting, because every one of these tricks bills you later. State is the first cost: the translation table lives in one box, so that box becomes a single point of failure, and any topology change that lets replies come back along a different path, called asymmetric routing, breaks connections in ways that are miserable to diagnose. Protocol breakage is the second: some protocols write IP addresses inside the data they carry, and FTP (File Transfer Protocol) in active mode, SIP (Session Initiation Protocol) telephony, and IPsec (Internet Protocol Security) VPN (Virtual Private Network) tunnels all needed special helpers or entire companion standards to survive translation. The third cost lands on your team: every translated flow has two names, and every troubleshooting session, firewall review, and packet capture now requires knowing which name you are looking at. The fourth is bookkeeping. Each translation rule is an address mapping that exists only in a device config until someone documents it, the exact trap we flagged for cloud NAT gateways in our guide to multi-cloud and hybrid IPAM: the day a partner asks which addresses to allowlist is a bad day to start reverse-engineering your own edge.
The most persistent myth about NAT deserves its own paragraph: the idea that translation is itself a security feature. The protective effect people notice comes from the statefulness underneath, since unsolicited inbound packets die for lack of a mapping, which is precisely what any stateful firewall does with or without address rewriting. A firewall that denies inbound by default protects an untranslated network just as well, and IPv6 networks run safely on exactly that model every day. Treat the security value of NAT as a side effect you happen to receive, never as the reason to deploy it and never as a substitute for real filtering rules.
So when is translation the right answer? At the IPv4 internet edge, always and permanently: sharing scarce public addresses is the job NAT was built for, and no alternative exists as long as you speak IPv4 to the world. For publishing a handful of services inbound, DNAT is clean and can run indefinitely, since the mapping count stays small and every rule is deliberate. For a fixed egress identity that partners can allowlist, a one-to-one mapping or a small SNAT pool is exactly right. And at the seam between overlapping networks, twice NAT is right precisely because it is temporary, bought at the price of a written end date and a renumbering plan. Translation is the wrong answer when it substitutes for an address plan. Reaching for NAT between two internal networks that could simply route to each other adds permanent state and permanent confusion to avoid a one-time planning conversation. Keeping overlapping ranges alive indefinitely inside one organization is a job for VRFs (Virtual Routing and Forwarding instances), which hold overlapping plans cleanly apart without rewriting a single packet, as we covered in VLANs vs VRFs. And in IPv6 translation is the wrong answer almost everywhere, because the scarcity that justified the whole apparatus is gone; our guide to IPv6 address planning explains why global addresses behind a firewall are the intended design.
Whatever mix you land on, NAT doubles your documentation surface, because every translated range is a real allocation with a real owner even though no device will ever hold those addresses directly. The public pool behind your PAT egress, the borrowed 100.64.0.0/10 slice at a merger seam, the one-to-one publics pinned to specific servers: all of it belongs in the same address plan as your ordinary subnets, or the next engineer will allocate on top of it. In IPCraft the translated ranges are simply subnets, so the seam block and the public pool sit in the tree alongside everything else, and custom fields carry each mapping's other half, a nat_public field on the private address and a nat_private field on the public one, so either side of a translation can answer what it maps to. When overlap itself is the problem, VRF support lets the same CIDR exist twice without one copy living in a spreadsheet, and the IPCraft API can hand migration scripts the next free address on whichever side of the seam they are working.
The rule of thumb that falls out of all this is short. Every NAT rule you write is a promise to keep a mapping alive, and documented, for as long as anything depends on it, so translation earns its place where the boundary is real and permanent, like the IPv4 internet edge, or real and temporary with a date attached, like a merger seam. Where the boundary is imaginary, where two networks could route, a VRF could isolate, or a weekend of renumbering could make the conflict disappear, the honest move is to fix the addresses and skip the promise. NAT is a superb tool and a terrible habit, and the entire skill is knowing which one you are holding.