The IPv4 address space has roughly 4.3 billion addresses — nowhere near enough for every device on Earth to have a unique public one. NAT (Network Address Translation) solves this by allowing many internal, private devices to share a small number of public IP addresses when communicating with the outside world. This article focuses specifically on Inside Source NAT — the most common NAT scenario, translating addresses of internal (“inside”) hosts as they source traffic toward the “outside” network — covering both static (one-to-one) and pool-based (dynamic) implementations.
The Problem NAT Solves
Private IP address ranges (defined in RFC 1918) — 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 — are free for anyone to use internally, but they are not routable on the public Internet. If an internal host with a private IP tries to communicate directly with a public server, the return traffic has no way to route back correctly, since private addresses are not globally unique.
NAT solves this by translating the private “inside” address into a public “outside” address at the network’s edge — usually on a router or firewall — allowing outbound communication to work while keeping the internal addressing scheme private and reusable across different, unrelated organizations.
NAT Terminology (Critical to Understand First)
| Term | Meaning |
|---|---|
| Inside Local | The private IP address of an internal host, as seen from inside the network |
| Inside Global | The translated, public IP address representing that internal host, as seen from outside |
| Outside Local | The IP address of an external host, as seen from inside the network (usually unchanged) |
| Outside Global | The actual public IP address of the external host, as seen from outside |
For most Inside Source NAT scenarios, only the Inside Local ↔ Inside Global translation matters — the outside address typically stays the same on both sides.
flowchart LR
A[PC: 192.168.1.10<br/>Inside Local] -- Traffic Sent --> B[Router NAT Translation]
B -- Translated to --> C[203.0.113.5<br/>Inside Global]
C -- Internet --> D[Web Server: 8.8.8.8<br/>Outside Global]Types of Inside Source NAT
| Type | Description | Use Case |
|---|---|---|
| Static NAT | One-to-one, permanent mapping between a specific inside local and inside global address | Servers that need a consistent, predictable public address (e.g., a web server) |
| Dynamic NAT (Pool-based) | Maps inside local addresses to an available address from a defined pool, on a first-come basis | Environments with multiple public IPs but not enough for a 1:1 static mapping per host |
| PAT (Port Address Translation / NAT Overload) | Many inside local addresses share a single inside global address, differentiated by port number | Most common in small/home networks — hundreds of internal devices sharing one public IP |
How Static NAT Works
Static NAT creates a permanent, unchanging mapping. If host 192.168.1.10 is statically mapped to 203.0.113.10, every single packet from that host will always translate to that exact public address, and anyone on the Internet trying to reach 203.0.113.10 will always be routed to 192.168.1.10 inside.
Configuring Static NAT on Cisco IOS
Router(config)# interface GigabitEthernet0/0
Router(config-if)# ip address 192.168.1.1 255.255.255.0
Router(config-if)# ip nat inside
Router(config)# interface GigabitEthernet0/1
Router(config-if)# ip address 203.0.113.1 255.255.255.252
Router(config-if)# ip nat outside
Router(config)# ip nat inside source static 192.168.1.10 203.0.113.10Every interface must be explicitly marked ip nat inside or ip nat outside — NAT will not function without this, since the router needs to know which direction traffic is flowing to apply the correct translation.
How Dynamic NAT (Pool-Based) Works
Dynamic NAT maps inside local addresses to any available address from a defined pool — useful when you have, say, a /28 block of 14 usable public addresses and want any of your internal hosts to be able to use one when needed, without dedicating a specific address to a specific host.
Configuring Dynamic NAT with a Pool
Router(config)# ip nat pool PUBLIC-POOL 203.0.113.10 203.0.113.20 netmask 255.255.255.240
Router(config)# access-list 1 permit 192.168.1.0 0.0.0.255
Router(config)# ip nat inside source list 1 pool PUBLIC-POOLHere:
ip nat pooldefines the range of public addresses available for translation.- The ACL identifies which inside traffic is eligible for translation (this is NOT a security ACL — it is simply defining “interesting traffic” for NAT).
ip nat inside source list 1 pool PUBLIC-POOLties the two together.
Important limitation: with pure dynamic NAT, once all addresses in the pool are in use, additional hosts trying to communicate outward will fail until an existing translation times out or is cleared. This is why most real deployments combine pooling with PAT (overload) to allow many more simultaneous hosts than there are public addresses.
Configuring PAT (NAT Overload) — The Most Common Real-World NAT
PAT allows hundreds or thousands of internal hosts to share a single public IP address by using different source port numbers to distinguish between simultaneous sessions.
Using a Single Interface’s Address (Most Common Home/Small Office Setup)
Router(config)# access-list 1 permit 192.168.1.0 0.0.0.255
Router(config)# ip nat inside source list 1 interface GigabitEthernet0/1 overloadUsing a Pool with Overload (Common Enterprise Setup)
Router(config)# ip nat pool PUBLIC-POOL 203.0.113.10 203.0.113.20 netmask 255.255.255.240
Router(config)# access-list 1 permit 192.168.1.0 0.0.0.255
Router(config)# ip nat inside source list 1 pool PUBLIC-POOL overload
Adding the overload keyword changes the behavior from “each inside host gets its own public address from the pool” to “many inside hosts share the pool’s addresses, distinguished by port numbers” — dramatically increasing the number of simultaneous sessions supportable with a limited number of public addresses.
flowchart TD
A[192.168.1.10:5001] -- PAT --> D[203.0.113.10:40001]
B[192.168.1.11:5002] -- PAT --> D2[203.0.113.10:40002]
C[192.168.1.12:5003] -- PAT --> D3[203.0.113.10:40003]
D --> E[Internet]
D2 --> E
D3 --> EVerifying NAT Configuration
Router# show ip nat translationsSample output showing an active PAT session:
Pro Inside global Inside local Outside local Outside global
tcp 203.0.113.10:40001 192.168.1.10:5001 8.8.8.8:443 8.8.8.8:443
tcp 203.0.113.10:40002 192.168.1.11:5002 93.184.216.34:80 93.184.216.34:80Router# show ip nat statisticsTotal translations: 2 (0 static, 2 dynamic; 2 extended)
Outside interfaces: GigabitEthernet0/1
Inside interfaces: GigabitEthernet0/0
Hits: 145 Misses: 2- Hits — packets successfully matched an existing translation.
- Misses — packets that required a new translation to be created.
Clear translations for testing purposes:
Router# clear ip nat translation *Debug NAT activity in real time (use sparingly on production devices, as debug output can be heavy):
Router# debug ip natComparison Table: Static NAT vs Dynamic NAT vs PAT
| Feature | Static NAT | Dynamic NAT (Pool) | PAT (Overload) |
|---|---|---|---|
| Mapping | Fixed, 1:1, permanent | 1:1, but chosen dynamically from a pool | Many:1, distinguished by port |
| Public IPs needed | One per mapped host | One per simultaneous host (up to pool size) | As few as one for the entire network |
| Inbound connections from Internet | Supported (predictable address) | Not practical (address changes) | Not supported without extra config (port forwarding) |
| Common Use Case | Public-facing servers | Mid-size networks with several public IPs | Small offices, home networks, most Internet-edge routers |
Configuring and Verifying NAT on Linux (iptables)
Linux systems (often acting as routers/gateways themselves) implement NAT using iptables’ nat table.
PAT/Masquerade (Equivalent to Cisco’s “overload”)
sudo iptables -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j MASQUERADEMASQUERADE is Linux’s version of PAT — it dynamically uses whatever address is currently assigned to the outbound interface (eth1), which is especially useful when that address might change (e.g., DHCP-assigned).
Static NAT Equivalent on Linux
sudo iptables -t nat -A PREROUTING -d 203.0.113.10 -j DNAT --to-destination 192.168.1.10
sudo iptables -t nat -A POSTROUTING -s 192.168.1.10 -j SNAT --to-source 203.0.113.10Verifying on Linux
sudo iptables -t nat -L -v -nAutomating NAT Translation Table Analysis with Python
import re
sample_output = """
Pro Inside global Inside local Outside local Outside global
tcp 203.0.113.10:40001 192.168.1.10:5001 8.8.8.8:443 8.8.8.8:443
tcp 203.0.113.10:40002 192.168.1.11:5002 93.184.216.34:80 93.184.216.34:80
"""
def parse_nat_translations(output):
lines = output.strip().split("\n")[1:] # skip header
translations = []
for line in lines:
parts = line.split()
if len(parts) == 5:
translations.append({
"protocol": parts[0],
"inside_global": parts[1],
"inside_local": parts[2],
})
return translations
for t in parse_nat_translations(sample_output):
print(f"{t['inside_local']} is translated to {t['inside_global']} ({t['protocol']})")
Output:
192.168.1.10:5001 is translated to 203.0.113.10:40001 (tcp)
192.168.1.11:5002 is translated to 203.0.113.10:40002 (tcp)This kind of parsing script is useful for automated network health reports, showing how many active NAT sessions exist and identifying any single host consuming an unusually large number of translations (a possible sign of malware or a misbehaving application).
Best Practices
- Use static NAT only for hosts that genuinely need a consistent, predictable public address (servers accepting inbound connections).
- Use PAT (overload) for general outbound Internet access from internal networks — it is the most address-efficient option.
- Keep the NAT-defining ACL as specific as possible — avoid using
permit anyin the NAT ACL, as this can unintentionally translate traffic you didn’t intend to (e.g., traffic between two internal NAT-enabled interfaces). - Monitor
show ip nat statisticsregularly for translation table growth — an unexpectedly large number of translations can indicate a misconfiguration or malicious activity. - Document your inside global address ranges clearly, especially in environments using both static NAT and PAT together, to avoid overlapping address usage.
- Clear stale NAT translations if troubleshooting connectivity that “used to work” after configuration changes (
clear ip nat translation *).
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
No translations appear in show ip nat translations | Interfaces not marked ip nat inside/ip nat outside, or ACL doesn’t match traffic | Verify interface NAT roles and ACL content |
| Internal hosts can’t reach the Internet at all | Missing or incorrect ip nat inside source statement | Verify NAT statement matches ACL and pool/interface correctly |
| Static NAT host unreachable from outside | Missing return route, or the address isn’t in the outside routing table (needs advertisement or a static route) | Verify routing for inside global address, check upstream ISP awareness of the address |
| PAT pool exhausted, connections failing during high usage | Insufficient use of port-based overload (not using overload keyword) | Add overload keyword to allow full port-based sharing |
| Translations exist but return traffic is dropped | Missing “outside” or “inside” marking on an interface, asymmetric routing | Verify all relevant interfaces have consistent NAT role configuration |
Real-World Example: Branch Office Internet Access
A branch office has one public IP (203.0.113.1) on its WAN interface and needs all internal hosts (192.168.5.0/24) to access the Internet, while a single internal web server (192.168.5.100) must also be reachable from the outside on a dedicated address (203.0.113.5).
interface GigabitEthernet0/0
ip address 192.168.5.1 255.255.255.0
ip nat inside
interface GigabitEthernet0/1
ip address 203.0.113.1 255.255.255.252
ip nat outside
! General Internet access for all internal hosts via PAT
access-list 1 permit 192.168.5.0 0.0.0.255
ip nat inside source list 1 interface GigabitEthernet0/1 overload
! Dedicated static NAT for the web server
ip nat inside source static 192.168.5.100 203.0.113.5This combination — PAT for general outbound traffic, static NAT for a server needing inbound access — is one of the most common NAT designs seen in real branch office and small business networks.
Conclusion
Inside Source NAT is the mechanism that allows private, non-routable internal networks to communicate with the public Internet, and it comes in three practical flavors: Static NAT for predictable one-to-one mappings, Dynamic NAT (pool-based) for sharing a block of public addresses, and PAT (overload) for maximizing address efficiency by sharing a single address across many simultaneous sessions using port numbers. Mastering the terminology (inside/outside, local/global), configuration syntax, and verification commands (show ip nat translations, show ip nat statistics) is essential for connecting any private network to the outside world correctly.
References
- RFC 1918 – Address Allocation for Private Internets — https://datatracker.ietf.org/doc/html/rfc1918
- RFC 3022 – Traditional IP Network Address Translator — https://datatracker.ietf.org/doc/html/rfc3022
- Cisco NAT Configuration Guide — https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ipaddr_nat/configuration/xe-16/nat-xe-16-book.html
- Cisco NAT Order of Operation — https://www.cisco.com/c/en/us/support/docs/ip/network-address-translation-nat/6209-5.html
- iptables NAT HOWTO — https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO.html