Why NAT Still Matters
Network Address Translation was designed in 1994 as a stopgap until IPv6 caught on. Three decades later, NAT is still everywhere, IPv6 deployment is half-done, and every Cisco router that connects a private LAN to the public Internet is doing some flavor of NAT. Understanding the four flavors — static, dynamic pool, PAT with a single IP, PAT with a pool — and the inside/outside terminology that confuses everyone the first time, is core CCNA territory.
This article covers all four NAT modes on Cisco IOS, the inside-local/inside-global address vocabulary, the verification commands, and the operational pitfalls.
Inside, Outside, Local, Global
Cisco’s NAT vocabulary has four address terms that combine a viewpoint (inside vs outside) with a context (local vs global). Memorize these on day one:
| Term | Meaning | Typical example |
|---|---|---|
| Inside Local | Address of an internal host as seen from inside | 192.168.1.10 (private RFC1918) |
| Inside Global | Address of an internal host as seen from outside (after translation) | 203.0.113.5 (public) |
| Outside Global | Address of an external host as seen from outside | 198.51.100.20 (public) |
| Outside Local | Address of an external host as seen from inside (rare; outside-source NAT) | 198.51.100.20 (usually unchanged) |
The two interfaces of the NAT router get marked:
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.5 255.255.255.252
Router(config-if)# ip nat outside
Without these ip nat inside / ip nat outside markings, no NAT happens regardless of what else you configure. This is the most common “NAT isn’t working” troubleshooting find.
Static NAT — One-to-One, Permanent
Static NAT permanently maps one inside-local to one inside-global. Use it when an internal server needs to be reachable from the Internet on a fixed public IP — a published web/mail/DNS server with its own IP, not behind a port forward.
Router(config)# ip nat inside source static 192.168.1.50 203.0.113.10
Now any packet from 192.168.1.50 to the outside is rewritten to source 203.0.113.10, and any packet to 203.0.113.10 from the outside is rewritten to destination 192.168.1.50. The mapping is bidirectional and never times out.
For port-specific static NAT (publishing a single TCP/UDP port instead of the whole IP):
Router(config)# ip nat inside source static tcp 192.168.1.50 443 203.0.113.5 443
That’s a static port forward (sometimes called PAT-static): public 203.0.113.5:443 routes to internal 192.168.1.50:443. Use this to put many internal services behind one public IP without a full pool.
Dynamic NAT — Many-to-Many from a Pool
Dynamic NAT allocates a public IP from a pool to an internal host on first outbound packet, then releases it after a timeout. Used when you have multiple public IPs but fewer than internal hosts, and want each session to use a unique public IP.
! Define the public pool:
Router(config)# ip nat pool PUBPOOL 203.0.113.10 203.0.113.20 netmask 255.255.255.0
! ACL identifying which inside hosts are eligible:
Router(config)# access-list 1 permit 192.168.1.0 0.0.0.255
! Translate from the ACL into the pool:
Router(config)# ip nat inside source list 1 pool PUBPOOL
Dynamic NAT (without overload) is rare in practice — you almost always want PAT instead, because PAT lets one public IP serve many internal hosts.
PAT (NAT Overload) — Many-to-One Using Ports
PAT (also called NAT Overload) is what 99% of small-office and home routers do. It maps every internal host to the same public IP but multiplexes by Layer 4 port number. The router maintains a translation table: every outbound session gets a unique outside source port, and inbound replies are demultiplexed back to the right inside host by port.
PAT with the WAN interface IP
The most common config — one public IP, the router’s own outside interface address:
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 overload
Every device on 192.168.1.0/24 now exits the WAN with source IP 203.0.113.5 (whatever’s on Gi0/1) and a unique source port.
PAT with a pool
If you have a small block of public IPs, you can PAT across all of them — useful when one public IP’s ~64,000 ports aren’t enough or you want to bind certain traffic to specific IPs:
Router(config)# ip nat pool PUBPOOL 203.0.113.10 203.0.113.15 netmask 255.255.255.248
Router(config)# access-list 1 permit 192.168.1.0 0.0.0.255
Router(config)# ip nat inside source list 1 pool PUBPOOL overload
Verifying NAT
The two commands you run constantly:
Router# show ip nat translations
Router# show ip nat statistics
Sample output of show ip nat translations:
Pro Inside global Inside local Outside local Outside global
tcp 203.0.113.5:5234 192.168.1.10:5234 198.51.100.20:443 198.51.100.20:443
tcp 203.0.113.5:6128 192.168.1.11:6128 93.184.216.34:443 93.184.216.34:443
udp 203.0.113.5:53 192.168.1.50:53 1.1.1.1:53 1.1.1.1:53
Each row is one active translation. show ip nat statistics tells you how many translations are active, hit rate, miss rate, and which interfaces are inside/outside. If Total active translations is 0 and you expect traffic, NAT isn’t firing — check the ip nat inside/outside markings and the ACL match.
Clearing Translations
NAT entries time out automatically (1 hour for TCP idle, 5 minutes for UDP). If you need to flush them immediately — usually when you’ve changed the NAT config and stale entries are misrouting traffic:
Router# clear ip nat translation *
Router# clear ip nat translation inside 192.168.1.10 outside 198.51.100.20
The first form wipes everything — uninvolved sessions get torn down too. Use the second form to clear one entry surgically.
Common Pitfalls
- Missing
ip nat inside/outside. The translations show up in the config but never trigger. Verify withshow ip interface briefand look for the NAT marker on each interface. - ACL too tight or too loose. A
permit 192.168.1.0 0.0.0.255only NATs that subnet. If you have multiple internal subnets behind the router, expand the ACL or add more lines. A bad ACL silently fails to translate. - Overlap with NAT and routing. If you’re using static NAT to publish 203.0.113.10, the router must also route 203.0.113.10 to itself or accept packets to that IP. Usually the public block is on the WAN interface; if not, you’ll need a static route.
- PAT port exhaustion. One public IP has ~64,000 ports. A few thousand internal hosts each opening a few connections each can blow through that.
show ip nat statisticsshows the count; expand to a pool when you approach the ceiling. - Stale translations after config changes. Translations created under the old config live until they time out. After any meaningful NAT change,
clear ip nat translation *to be sure. - NAT and IPsec interaction. If you NAT VPN traffic, the IPsec hash check fails — the source/destination IPs in the inner packet don’t match what the encryption peer expects. Use NAT-T (NAT Traversal) to wrap IPsec in UDP, or exempt VPN traffic from NAT with a route-map.
Conclusion
Four NAT modes, four use cases:
- Static — one inside host needs a fixed public IP (published servers).
- Dynamic Pool — many internal hosts share a small block of public IPs, one-at-a-time. Rare in modern designs.
- PAT (overload) with WAN IP — the home/branch default. Many internal hosts, one public IP, multiplexed by port.
- PAT with pool — PAT across a block of public IPs when you need more than ~64K concurrent sessions or want to bind groups to specific IPs.
Two habits that pay off: always verify the ip nat inside/outside markings before debugging anything else (they’re the root cause of half of all NAT outages), and keep an explicit show ip nat translations open in a second window when you’re changing things — the translation table tells you instantly whether traffic is flowing through NAT or bypassing it.