CCNA: NAT and PAT — Network Address Translation in Depth
Network Address Translation is one of those topics that looks straightforward in a diagram and becomes genuinely confusing the moment you sit down with a real router and a packet capture. The terminology alone — inside local, inside global, outside local, outside global — trips up a significant number of CCNA candidates who have studied the concept but never internalized why those four terms exist and what problem each one solves. This post works through NAT and PAT from first principles: why they exist, how they actually work at the packet level, how to configure every variant in Cisco IOS, how to read the translation table, and how to diagnose failures systematically using the tools Cisco provides.
If you can finish this post and explain to someone else why a packet’s source address is called the “inside global” when it leaves the router, and what that has to do with the perspective of the observer, you are ready for the NAT questions on the CCNA exam.
Why NAT Exists
IPv4 uses 32-bit addresses, which gives a theoretical address space of approximately 4.3 billion unique addresses. This seemed enormous in 1983. By the early 1990s, with the internet expanding far faster than anyone had anticipated, the IETF recognized that 4.3 billion addresses would not be enough to assign a unique public IP to every device that would eventually need internet connectivity.
The short-term solution was published in RFC 1918 in 1996. RFC 1918 designates three address ranges as private address space — addresses that any organization may use internally, that are not routable on the public internet, and that internet service providers will not forward:
| RFC 1918 Range | CIDR Notation | Address Count |
|---|---|---|
| 10.0.0.0 — 10.255.255.255 | 10.0.0.0/8 | 16,777,216 |
| 172.16.0.0 — 172.31.255.255 | 172.16.0.0/12 | 1,048,576 |
| 192.168.0.0 — 192.168.255.255 | 192.168.0.0/16 | 65,536 |
Every home router, every enterprise network, and most cloud VPCs use addresses from these ranges internally. The key point is that two different organizations can both use 192.168.1.0/24 internally without conflict, precisely because that address space is never advertised to or routed by the public internet.
The problem this creates is immediately apparent: a host at 192.168.1.10 needs to reach Google’s DNS server at 8.8.8.8. If the packet leaves the enterprise with a source address of 192.168.1.10, Google’s DNS server has no way to send a reply. The reply would need to be routed back to 192.168.1.10, but since RFC 1918 addresses are not globally routable, no ISP router in the path would have a route for 192.168.1.10. The packet would be dropped.
NAT solves this by having the border router — the device sitting at the edge between the private network and the internet — rewrite the source IP address of outgoing packets from the private RFC 1918 address to a public IP address that the ISP has assigned. Return traffic comes back to the public IP, the NAT router rewrites the destination back to the original private address, and forwards the packet inward. To the outside world, the entire private network appears to be communicating from a single (or small number of) public IP addresses.
This mechanism has had a secondary effect that was not part of the original design intent: it has substantially delayed IPv6 adoption. The logic is circular but persistent. Organizations that have NAT working reasonably well have no immediate operational pressure to deploy IPv6. As long as private hosts can reach the internet through NAT, the address exhaustion problem appears solved at the individual organization level, even though the global pool of unallocated IPv4 addresses is effectively exhausted (IANA distributed its last /8 blocks in 2011; RIPE NCC, the European RIR, exhausted its pool in 2019).
NAT also functions as an unintentional security boundary. Because NAT devices only forward return traffic for connections that were initiated from the inside, unsolicited inbound connections from the internet simply do not reach inside hosts — there is no translation table entry for them, so the NAT router drops the packet. This is not a firewall. NAT provides no inspection, no policy enforcement, and no protection against malicious outbound connections. But the side effect of blocking unsolicited inbound traffic means that many networks treat NAT as a substitute for proper stateful firewall configuration, which is technically incorrect but pragmatically common.
The Four NAT Address Types
This is the section most CCNA students skim and later regret. The four address type names encode a logical framework for describing where a packet is observed from and whether the address has been translated. Getting this right is not just an exam exercise — it is the mental model you need to interpret show ip nat translations output correctly.
The key insight is that every address type has two attributes: a location (inside or outside) and a perspective (local or global).
- “Inside” means the host lives on the private side of the NAT boundary.
- “Outside” means the host lives on the public side of the NAT boundary.
- “Local” means the address as it appears to devices on the inside network.
- “Global” means the address as it appears to devices on the outside (internet) network.
Combining these attributes gives four terms:
Inside local: The private IP address assigned to an inside host. This is the address the inside host thinks it has, the address other inside hosts use to reach it, and the address that appears in the source field of packets before NAT translates them. Example: 192.168.1.10.
Inside global: The public IP address that represents an inside host after NAT translation. This is what outside hosts see as the source address of packets from the inside host. Example: 203.0.113.1. The inside host does not know this address exists; it is assigned by the ISP and used only by the NAT router.
Outside global: The actual public IP address of an outside host. This is the real address of the destination server on the internet. Example: 8.8.8.8. This address appears in the destination field of packets going outbound.
Outside local: The IP address of an outside host as it appears to inside hosts. In the vast majority of NAT deployments, the outside local and outside global are identical, because most organizations do not translate destination addresses. Outside local differs from outside global only in hairpin NAT or destination NAT scenarios, discussed later.
The following ASCII diagram shows a packet walking through a standard PAT scenario. PC at 192.168.1.10 sends a DNS query to 8.8.8.8. The NAT router has a public interface address of 203.0.113.1.
INSIDE NETWORK NAT ROUTER INTERNET
Gi0/1 Gi0/0
+-------------+ +------+------+ +-------------+
| PC | | | | | 8.8.8.8 |
| 192.168.1.10|------------>|inside|outsd |------------>| Google DNS |
+-------------+ +------+------+ +-------------+
PACKET BEFORE NAT (on Gi0/1, inside interface):
Source IP: 192.168.1.10 (inside local)
Source Port: 52341
Dest IP: 8.8.8.8 (outside global = outside local in this case)
Dest Port: 53
PACKET AFTER NAT (on Gi0/0, outside interface):
Source IP: 203.0.113.1 (inside global)
Source Port: 50001 (PAT-assigned port)
Dest IP: 8.8.8.8 (outside global)
Dest Port: 53
RETURN PACKET BEFORE NAT (arriving on Gi0/0):
Source IP: 8.8.8.8 (outside global = outside local)
Source Port: 53
Dest IP: 203.0.113.1 (inside global — this is what the reply was sent to)
Dest Port: 50001
RETURN PACKET AFTER NAT (forwarded out Gi0/1):
Source IP: 8.8.8.8 (outside global)
Source Port: 53
Dest IP: 192.168.1.10 (inside local — restored by NAT)
Dest Port: 52341
The four addresses at play in this single transaction:
| Term | Address | Meaning |
|---|---|---|
| Inside local | 192.168.1.10 | PC’s actual private IP |
| Inside global | 203.0.113.1 | Public IP representing the PC (router’s outside interface) |
| Outside local | 8.8.8.8 | What inside sees as the destination (unchanged here) |
| Outside global | 8.8.8.8 | Google DNS’s real public IP |
The reason outside local equals outside global in this example: the NAT router is not doing any destination translation. The destination address passes through unchanged. Only the source address is modified. In a scenario where destination NAT is configured (for example, a port forward to a server inside the network), the outside local and outside global would differ — but that scenario is less common and most CCNA exam questions assume standard source NAT where outside local equals outside global.
A useful memory trick: “local” always means “on the inside network’s perspective” and “global” always means “on the internet’s perspective.” The first word (inside/outside) tells you which host you are describing.
NAT Interface Designation: Inside and Outside
NAT in Cisco IOS is directional. The router needs to know which interfaces face the private network (inside) and which face the public network (outside). This designation is configured per interface and controls when NAT translation logic is applied to a packet.
interface GigabitEthernet0/1
description LAN Interface
ip address 192.168.1.1 255.255.255.0
ip nat inside
interface GigabitEthernet0/0
description Internet / WAN Interface
ip address 203.0.113.1 255.255.255.252
ip nat outside
When a packet arrives on an interface marked ip nat inside and is destined to leave through an interface marked ip nat outside, the router applies source NAT translation — it looks up the source address in the NAT configuration and rewrites it. When a packet arrives on an interface marked ip nat outside and is destined for an interface marked ip nat inside, the router applies destination NAT translation — it looks up the destination address in the translation table and rewrites it back to the inside local address.
This directionality is the root cause of one of the most common NAT configuration mistakes: forgetting to apply ip nat inside or ip nat outside to the interfaces. If the interfaces are not designated, no translation occurs regardless of what ip nat inside source commands are configured. The translation engine is never triggered.
The NAT table lookup process works as follows for an outbound packet:
- Packet arrives on inside interface.
- Router performs a routing lookup to determine the exit interface.
- If the exit interface is an outside NAT interface, the router checks for a matching NAT translation.
- For static NAT: the router checks if the source IP matches a static NAT entry. If yes, it rewrites the source IP and forwards the packet.
- For dynamic NAT or PAT: the router checks if the source IP matches an ACL referenced in an
ip nat inside source listcommand. If yes, it either finds an existing translation in the table (for an ongoing flow) or creates a new one, rewrites the source, and forwards. - If no NAT rule matches, the packet is forwarded untranslated (which usually means it will be dropped by the ISP because the source is a private address).
For inbound packets (arriving on outside interface, destined for inside):
- Packet arrives on outside interface.
- Router checks the destination IP (and port, for PAT) against the NAT translation table.
- If a match exists, the destination is rewritten to the inside local address.
- The packet is then routed to the inside network.
This asymmetry — source translation outbound, destination translation inbound — is why NAT is described as stateful in the sense that the outbound translation creates a table entry that the return traffic relies on. The return traffic does not need a separate configuration rule; it just needs a matching entry in the translation table that was created by the original outbound packet.
Static NAT
Static NAT creates a permanent, one-to-one mapping between an inside local address and an inside global address. The mapping exists regardless of whether any traffic is flowing and does not time out. This is the appropriate NAT type when you need to host a service — a web server, mail server, or SSH endpoint — that must always be reachable at a predictable public IP address.
Use Case
You have a web server at 192.168.1.100 that needs to be reachable from the internet. Your ISP has given you a public IP block including 203.0.113.100. You create a static NAT entry mapping 192.168.1.100 to 203.0.113.100. Anyone on the internet who connects to 203.0.113.100 will be translated to 192.168.1.100 and reach the server. The server can also initiate outbound connections, and its source address will appear as 203.0.113.100 on the internet.
Configuration
! Define NAT interfaces first
interface GigabitEthernet0/0
ip address 203.0.113.1 255.255.255.248
ip nat outside
interface GigabitEthernet0/1
ip address 192.168.1.1 255.255.255.0
ip nat inside
! Static NAT: map inside local to inside global permanently
ip nat inside source static 192.168.1.100 203.0.113.100
The command syntax is:
ip nat inside source static [inside-local-ip] [inside-global-ip]
“inside source” means we are translating the source of packets coming from inside. “static” means this is a permanent entry.
Verification
Router# show ip nat translations
Pro Inside global Inside local Outside local Outside global
--- 203.0.113.100 192.168.1.100 --- ---
tcp 203.0.113.100:80 192.168.1.100:80 8.8.8.8:12345 8.8.8.8:12345
tcp 203.0.113.100:443 192.168.1.100:443 1.2.3.4:54321 1.2.3.4:54321
The first entry (with dashes in the outside columns) is the static entry itself — it exists before any traffic flows. The subsequent entries appear when active connections exist and show the port-level detail of those connections.
The return traffic handling is automatic. When a packet arrives on the outside interface destined for 203.0.113.100, the router checks the NAT table, finds the static entry mapping 203.0.113.100 to 192.168.1.100, rewrites the destination, and forwards the packet to the inside host. The server at 192.168.1.100 receives the packet with its private IP as the destination, as if the connection came in directly.
Static NAT with Port Translation
When you have only one public IP but need to host multiple services, or when you want to expose a specific port to a specific inside host, static NAT supports port-level mapping:
! Map external port 80 to internal web server
ip nat inside source static tcp 192.168.1.100 80 203.0.113.1 80
! Map external port 443 to same web server
ip nat inside source static tcp 192.168.1.100 443 203.0.113.1 443
! Map external port 8022 to SSH on a different internal host
ip nat inside source static tcp 192.168.1.50 22 203.0.113.1 8022
The syntax: ip nat inside source static [tcp|udp] [inside-local-ip] [inside-local-port] [inside-global-ip] [inside-global-port]
This allows a single public IP (203.0.113.1) to front multiple internal services. A connection to 203.0.113.1:80 goes to the web server at 192.168.1.100:80. A connection to 203.0.113.1:8022 goes to 192.168.1.50:22. The NAT router performs both IP and port translation in both directions.
Dynamic NAT
Dynamic NAT maps inside local addresses to a pool of inside global addresses on a first-come, first-served basis. When an inside host initiates a connection, the NAT router allocates an unused public IP from the pool and creates a translation entry. When the translation expires (due to inactivity), the public IP is returned to the pool for reuse.
Dynamic NAT differs from PAT in that it is still a one-to-one mapping — one inside host gets one inside global IP at a time, not sharing with other hosts. This means dynamic NAT requires as many public IPs in the pool as the maximum number of simultaneous inside hosts that will use NAT. In practice, this makes dynamic NAT relatively rare compared to PAT, but it is important to understand for the CCNA exam and for scenarios where application compatibility requires a dedicated IP per session.
Configuration
! Define the pool of public IP addresses available for translation
ip nat pool MYPOOL 203.0.113.10 203.0.113.20 netmask 255.255.255.0
! Define which inside hosts are eligible for NAT using an ACL
access-list 1 permit 192.168.1.0 0.0.0.255
! Bind the ACL to the pool — translate sources matching ACL using pool addresses
ip nat inside source list 1 pool MYPOOL
! Interface configuration
interface GigabitEthernet0/0
ip address 203.0.113.1 255.255.255.252
ip nat outside
interface GigabitEthernet0/1
ip address 192.168.1.1 255.255.255.0
ip nat inside
The ip nat pool command defines the range of public IPs available. The format is:
ip nat pool [pool-name] [start-ip] [end-ip] netmask [mask]
Alternatively, you can use prefix-length instead of netmask:
ip nat pool MYPOOL 203.0.113.10 203.0.113.20 prefix-length 24
The ACL (access-list 1) permits the source addresses eligible for translation. This is a standard ACL in this example. Only packets from 192.168.1.0/24 will trigger NAT. Any other inside source address passes through untranslated (which is almost certainly wrong if those are also RFC 1918 addresses, but the configuration is technically valid).
Dynamic NAT Translation Table
When a host at 192.168.1.15 initiates a connection:
Router# show ip nat translations
Pro Inside global Inside local Outside local Outside global
--- 203.0.113.10 192.168.1.15 --- ---
tcp 203.0.113.10:1024 192.168.1.15:54231 8.8.8.8:80 8.8.8.8:80
The first entry is the base IP-level mapping (inside local to inside global), and the second shows the active TCP connection with ports.
When a second host at 192.168.1.22 initiates a connection, it receives the next available pool IP:
Router# show ip nat translations
Pro Inside global Inside local Outside local Outside global
--- 203.0.113.10 192.168.1.15 --- ---
tcp 203.0.113.10:1024 192.168.1.15:54231 8.8.8.8:80 8.8.8.8:80
--- 203.0.113.11 192.168.1.22 --- ---
tcp 203.0.113.11:2048 192.168.1.22:49001 1.1.1.1:443 1.1.1.1:443
Translation Timeouts
Dynamic NAT entries expire after inactivity. The default timeouts are:
| Translation Type | Default Timeout |
|---|---|
| TCP established (full three-way handshake) | 86400 seconds (24 hours) |
| TCP half-open (SYN sent, no SYN-ACK) | 60 seconds |
| UDP | 300 seconds (5 minutes) |
| ICMP | 60 seconds |
| DNS | 60 seconds |
You can adjust these with:
ip nat translation timeout 3600
ip nat translation tcp-timeout 3600
ip nat translation udp-timeout 120
ip nat translation icmp-timeout 30
ip nat translation dns-timeout 15
ip nat translation tcp-syn-timeout 30
Pool Exhaustion
The critical limitation of dynamic NAT: if all pool IPs are in use and a new inside host tries to initiate a connection, the NAT router has no IP to assign and the translation fails. The new connection is dropped. The original hosts whose translations hold those pool IPs continue working. This is a resource exhaustion problem that PAT (overload) solves by allowing many inside hosts to share a single public IP using port number differentiation.
PAT: Port Address Translation (NAT Overload)
PAT is the form of NAT that powers virtually every home router and most enterprise internet edges. It allows thousands of inside hosts to share a single public IP address simultaneously by using port numbers to distinguish individual flows. The Cisco IOS keyword for PAT is overload, appended to the ip nat inside source command.
How PAT Works
When an inside host initiates a connection, it sends a packet with a source IP (the inside local address) and a source port chosen by the operating system (typically in the ephemeral port range above 1024, up to 65535). PAT records not just the IP address mapping but also the port mapping. The inside global address is the single public IP, but each flow gets a unique [inside-global-IP:inside-global-port] tuple, which serves as the identifier for that specific flow in the translation table.
Consider two inside hosts both initiating connections to the same destination:
- Host A: 192.168.1.10:52001 -> 8.8.8.8:53 (DNS query)
- Host B: 192.168.1.20:52001 -> 8.8.8.8:53 (also a DNS query, same ephemeral port by coincidence)
Without PAT, if both were mapped to the same public IP, the router would have no way to determine which return packet should go to Host A and which to Host B — both would appear to come from 203.0.113.1:someport to 8.8.8.8:53.
With PAT, the router assigns unique outside ports:
- Host A: 203.0.113.1:1024 -> 8.8.8.8:53 (inside global port 1024)
- Host B: 203.0.113.1:1025 -> 8.8.8.8:53 (inside global port 1025)
When Google DNS replies to 203.0.113.1:1024, the router looks up port 1024, finds the mapping to Host A (192.168.1.10:52001), and delivers the packet. When the reply arrives for port 1025, it goes to Host B. The port number is the disambiguation key.
Port Collision Handling
What happens when two inside hosts happen to choose the same source port, as in the example above? The PAT router detects the collision — the new translation would create a duplicate [inside-global-IP:port] pair — and assigns a different port number for the second host. The inside host is never aware of this reassignment because the return traffic arrives with the correct inside local port restored from the translation table.
The pool of available PAT ports is nominally 1024-65535 for TCP and UDP (64,511 ports per public IP). Ports below 1024 are the well-known/privileged port range; PAT will use them for inside hosts that use them as source ports (rare in practice), but dynamic PAT assignments stay in the higher range. This gives a theoretical ceiling of about 64,000 simultaneous PAT sessions per public IP, though real-world capacity depends on session tables, memory, and CPU.
PAT Configuration Using Interface Address
The most common PAT configuration uses the outside interface’s IP address as the single inside global address. This is ideal when the ISP assigns a single IP via DHCP or when the outside interface IP is the only public address available.
! ACL to define which inside hosts get NATted
access-list 1 permit 192.168.1.0 0.0.0.255
! PAT using the outside interface's IP address
ip nat inside source list 1 interface GigabitEthernet0/0 overload
interface GigabitEthernet0/0
ip address 203.0.113.1 255.255.255.252
ip nat outside
interface GigabitEthernet0/1
ip address 192.168.1.1 255.255.255.0
ip nat inside
The interface GigabitEthernet0/0 keyword in the NAT command tells the router to use whatever IP is currently configured on that interface as the inside global address. This handles dynamic WAN IPs automatically — if the DHCP lease changes the WAN IP, PAT continues working because the command references the interface, not a static address.
PAT Configuration Using a Pool with Overload
If you have multiple public IPs but more than one-to-one mapping would exhaust them, you can combine a pool with overload:
ip nat pool PATPOOL 203.0.113.10 203.0.113.12 netmask 255.255.255.0
access-list 1 permit 192.168.0.0 0.0.255.255
ip nat inside source list 1 pool PATPOOL overload
This allows up to three public IPs (203.0.113.10, .11, .12) to be used for PAT, distributing the port space across those IPs. Each IP has its own pool of 64,000 ports, effectively tripling the simultaneous session capacity compared to a single-IP PAT configuration. The router fills ports on the first pool IP before moving to the second.
The NAT Translation Table in Detail
The show ip nat translations command is the primary operational window into NAT state. Understanding every field in the output is essential for both exam questions and real-world troubleshooting.
Standard Output
Router# show ip nat translations
Pro Inside global Inside local Outside local Outside global
--- 203.0.113.100 192.168.1.100 --- ---
tcp 203.0.113.100:80 192.168.1.100:80 1.2.3.4:62001 1.2.3.4:62001
tcp 203.0.113.100:443 192.168.1.100:443 5.6.7.8:49321 5.6.7.8:49321
tcp 203.0.113.1:1024 192.168.1.10:52341 8.8.8.8:80 8.8.8.8:80
tcp 203.0.113.1:1025 192.168.1.20:44123 8.8.8.8:80 8.8.8.8:80
udp 203.0.113.1:1026 192.168.1.15:53201 1.1.1.1:53 1.1.1.1:53
icmp 203.0.113.1:1027 192.168.1.30:1027 8.8.4.4 8.8.4.4
Column breakdown:
Pro (Protocol): The Layer 4 protocol: tcp, udp, icmp, or — (for base IP-level entries with no port detail, typical of static NAT entries before traffic flows or dynamic NAT base entries).
Inside global: The public IP and port (if applicable) that represents the inside host to the outside world. For static NAT without port translation, this is just an IP. For PAT entries, it includes the translated port.
Inside local: The private IP and port of the inside host as it actually exists on the inside network. This is the original address before translation.
Outside local: The IP and port of the outside host as seen from inside. In most configurations this equals outside global. Only differs when destination NAT or hairpin NAT is configured.
Outside global: The actual public IP and port of the remote host on the internet.
Reading Specific Entry Types
Static NAT base entry (first row): The --- protocol indicates a static IP-level mapping with no port translation. This entry is created when ip nat inside source static 192.168.1.100 203.0.113.100 is configured and persists permanently.
Static NAT with active connection (rows 2-3): When traffic flows through the static NAT mapping, per-connection entries appear below the base entry. These show the actual ports in use for active connections and time out when the connection closes.
PAT entries (rows 4-5): These show the full four-tuple: inside global with translated port, inside local with original port, and the remote endpoint. Both hosts are mapped to the same inside global IP (203.0.113.1) but to different ports (1024, 1025).
UDP PAT entry (row 6): UDP is stateless at Layer 4, but NAT tracks UDP flows and creates entries when UDP packets pass through. The timeout is 300 seconds (5 minutes) by default, shorter than TCP.
ICMP entry (row 7): ICMP does not use port numbers. Instead, PAT uses the ICMP Identifier field (the two-byte echo request identifier that allows the sending host to match replies to requests) as a pseudo-port. This is what allows multiple inside hosts to ping simultaneously through PAT. The ICMP identifier 1027 serves the same disambiguation function as a port number.
Verbose Output
Router# show ip nat translations verbose
Pro Inside global Inside local Outside local Outside global
tcp 203.0.113.1:1024 192.168.1.10:52341 8.8.8.8:80 8.8.8.8:80
create 00:00:15, use 00:00:02, timeout 86400
Map-Id(In): 1, portlist in lookup
Flags: extended, timing-out, src-port, outside, src-ip
tcp 203.0.113.100:80 192.168.1.100:80 1.2.3.4:62001 1.2.3.4:62001
create 00:02:33, use 00:00:08, timeout 86400
Map-Id(In): 2
Flags: extended, static
The verbose output adds:
- create: Time since this entry was created (hh:mm:ss).
- use: Time since this entry was last used by a packet. If this is close to the timeout value, the entry may expire soon.
- timeout: Seconds remaining before expiration. For active connections, this resets with each packet. For static entries, it is often shown as indefinite or a very large number.
- Flags: Internal state flags including
static(created by static NAT command),extended(has port information),timing-out(in the process of timing out), and others.
NAT Statistics
Router# show ip nat statistics
Total active translations: 47 (3 static, 44 dynamic; 44 extended)
Outside interfaces:
GigabitEthernet0/0
Inside interfaces:
GigabitEthernet0/1
Hits: 284901 Misses: 12
CEF Translated packets: 284899, CEF Punted packets: 14
Expired translations: 193
Dynamic mappings:
-- Inside Source
[Id: 1] access-list 1 interface GigabitEthernet0/0 refcount 44
extended: 44
Pool stats drop: 0 Mapping stats drop: 0
Port block alloc fail: 0
IP alias add fail: 0
Limit entry add fail: 0
Key fields in show ip nat statistics:
Total active translations: Total entries currently in the translation table, broken down by static, dynamic, and extended (those with port information).
Outside/Inside interfaces: Confirms which interfaces have been designated for NAT. If your expected interfaces are not listed here, the ip nat inside / ip nat outside command is missing from those interfaces.
Hits: Number of packets that matched an existing translation entry and were forwarded. High hit counts indicate heavy NAT usage.
Misses: Number of packets that did not match any existing entry and triggered a new translation lookup (or failed translation). A high or growing miss count relative to hits may indicate configuration problems, pool exhaustion, or mismatched ACLs.
Expired translations: Cumulative count of translations that have timed out since the last statistics reset. Normal in a working system; very low counts in a system that should be active suggests traffic is not flowing.
Pool stats drop: Packets dropped because the NAT pool was exhausted. Non-zero values here indicate pool exhaustion — inside hosts are failing to establish new connections because no public IPs remain.
NAT and ICMP
ICMP (the protocol underlying the ping command) does not use port numbers. Port numbers are a TCP and UDP concept. So how does PAT handle multiple inside hosts pinging simultaneously?
The answer lies in the ICMP Echo Request message format. An ICMP Echo Request contains an Identifier field (two bytes) that the sender uses to match echo replies to their corresponding requests. The OS increments this identifier with each new ping session (each time you run the ping command). This Identifier field acts as a pseudo-port for PAT purposes.
When two inside hosts ping simultaneously:
- Host A: 192.168.1.10 sends ICMP echo requests with Identifier 100
- Host B: 192.168.1.20 sends ICMP echo requests with Identifier 100 (coincidentally the same)
PAT creates entries using these identifiers:
icmp 203.0.113.1:100 192.168.1.10:100 8.8.8.8 8.8.8.8
icmp 203.0.113.1:101 192.168.1.20:100 8.8.8.8 8.8.8.8
Host B’s identifier was remapped from 100 to 101 on the inside global side to avoid collision, exactly as PAT handles TCP/UDP port collisions. When the ICMP Echo Reply arrives from 8.8.8.8 with Identifier 101, the PAT router looks it up, finds it belongs to Host B, rewrites the destination IP to 192.168.1.20, and restores the Identifier to 100 before delivery.
This is why ping works as a NAT test tool. An ICMP ping through PAT exercises the full translation mechanism — entry creation, outbound translation, inbound reverse translation — and demonstrates that basic NAT is functional. If ping works but TCP connections fail, the NAT mechanism itself is likely fine and the problem is elsewhere (firewall, ACL, routing).
debug ip nat: The Essential Troubleshooting Tool
The debug ip nat command is the most powerful NAT diagnostic tool available in IOS. It produces real-time log output for every packet that triggers a NAT translation decision. Used correctly, it tells you exactly what the router is doing with each packet: what it sees before translation, what it changes, and in which direction.
Enabling and Reading the Output
Router# debug ip nat
NAT: debugging is on
A ping from inside host 192.168.1.10 to 8.8.8.8 produces:
*May 26 10:23:01.441: NAT*: s=192.168.1.10->203.0.113.1, d=8.8.8.8 [12345]
*May 26 10:23:01.445: NAT*: s=8.8.8.8, d=203.0.113.1->192.168.1.10 [12345]
*May 26 10:23:01.941: NAT*: s=192.168.1.10->203.0.113.1, d=8.8.8.8 [12346]
*May 26 10:23:01.945: NAT*: s=8.8.8.8, d=203.0.113.1->192.168.1.10 [12346]
Dissecting the first line:
*May 26 10:23:01.441: NAT*: s=192.168.1.10->203.0.113.1, d=8.8.8.8 [12345]
-
The asterisk (
*) before the timestamp indicates the packet was processed by CEF (Cisco Express Forwarding), the fast-path forwarding engine. Without the asterisk, the packet was process-switched (slow-path). CEF is normal for almost all production traffic. The translation still occurred correctly; CEF simply means the forwarding decision was made in hardware/fast path rather than by the main CPU. -
NAT*:is the debug tag. The asterisk after NAT here again refers to CEF processing. -
s=192.168.1.10->203.0.113.1means: source address was 192.168.1.10 (inside local) and was translated to 203.0.113.1 (inside global). The arrow shows the before->after transformation. -
d=8.8.8.8means the destination address was 8.8.8.8 and was NOT translated (no arrow, no before->after). In this outbound packet, only the source is translated. -
[12345]is the IP packet identification number (a field in the IP header). This allows you to correlate the outbound and return packets for the same flow.
The second line is the return packet:
*May 26 10:23:01.445: NAT*: s=8.8.8.8, d=203.0.113.1->192.168.1.10 [12345]
s=8.8.8.8— source address is 8.8.8.8 (outside global), not translated in this direction.d=203.0.113.1->192.168.1.10— destination was 203.0.113.1 (inside global, what Google sent the reply to) and was translated back to 192.168.1.10 (inside local, the actual host).[12345]— same packet ID, confirming this is the return packet for the same flow.
debug ip nat detailed
For more verbose output, including information about pool lookups, ACL matches, and translation creation events:
Router# debug ip nat detailed
Example output for a new connection (translation being created for the first time):
*May 26 10:25:14.112: NAT: i: icmp (192.168.1.10, 200) -> (8.8.8.8, 200) [10001]
*May 26 10:25:14.112: NAT: ipnat_allocate_port: proto=1, paddr=203.0.113.1,
port=200 -> alloc_port=1028
*May 26 10:25:14.112: NAT: translation created 192.168.1.10 -> 203.0.113.1
*May 26 10:25:14.113: NAT*: s=192.168.1.10->203.0.113.1, d=8.8.8.8 [10001]
This shows the port allocation event (ipnat_allocate_port) where the router chose port 1028 for the inside global side, and the explicit “translation created” log line confirming a new entry was added to the table.
Safety Warning
Never run debug ip nat on a production router without preparation. On a busy internet edge router, this command can generate thousands of debug lines per second, overwhelming the console and potentially causing the router to drop packets while trying to log. Before enabling NAT debug on a production device:
-
Use
debug conditionto limit debugging to specific hosts:debug condition interface GigabitEthernet0/1 debug condition host 192.168.1.10 -
Have
undebug all(or its aliasu all) ready to type immediately. -
Consider redirecting debug output to a buffer rather than the console:
no logging console logging buffered 65536 debug debug ip nat ! Reproduce the issue undebug all show logging -
On high-traffic routers, prefer
debug ip nattodebug ip nat detailed. The detailed version is significantly more verbose.
Complete Worked Scenario
This section builds a complete, realistic NAT configuration and walks through verification from start to finish.
Topology
INTERNET
|
+--------------+
| ISP Router |
| 203.0.113.2 |
+--------------+
|
203.0.113.1/30
+--------------+
| BORDER RTR | Gi0/0: 203.0.113.1/30 (ip nat outside)
| | Gi0/1: 192.168.1.1/24 (ip nat inside)
+--------------+
|
192.168.1.0/24
+------------------+
| |
192.168.1.10 192.168.1.100
[PC / Workstation] [Web Server]
Requirements:
- All workstations (192.168.1.0/24) get internet access via PAT using the Gi0/0 address.
- Web server (192.168.1.100) has static NAT for ports 80 and 443 to a second public IP (203.0.113.2 is the ISP router; assume the ISP has given us 203.0.113.1 as our WAN IP and 203.0.113.2/30 is the ISP side — we will use 203.0.113.1 for PAT and a port-based static for the web server on the same IP).
Full IOS Configuration
! ============================================================
! INTERFACE CONFIGURATION
! ============================================================
interface GigabitEthernet0/0
description WAN - Internet Uplink to ISP
ip address 203.0.113.1 255.255.255.252
ip nat outside
no shutdown
interface GigabitEthernet0/1
description LAN - Internal Network
ip address 192.168.1.1 255.255.255.0
ip nat inside
no shutdown
! ============================================================
! DEFAULT ROUTE TO ISP
! ============================================================
ip route 0.0.0.0 0.0.0.0 203.0.113.2
! ============================================================
! ACL: DEFINE WHICH INSIDE HOSTS GET NAT'D
! A standard ACL matching the entire 192.168.1.0/24 range.
! Note: this is a standard ACL — only matches source IP.
! ============================================================
ip access-list standard LAN_FOR_NAT
permit 192.168.1.0 0.0.0.255
! ============================================================
! STATIC NAT: PORT-BASED FORWARDING FOR WEB SERVER
! External connections to 203.0.113.1:80 and :443 are
! forwarded to the internal web server at 192.168.1.100.
! ============================================================
ip nat inside source static tcp 192.168.1.100 80 203.0.113.1 80
ip nat inside source static tcp 192.168.1.100 443 203.0.113.1 443
! ============================================================
! PAT: ALL OTHER INSIDE HOSTS USE OVERLOAD ON WAN INTERFACE
! The "overload" keyword enables PAT.
! ACL LAN_FOR_NAT defines eligible sources.
! The web server (192.168.1.100) matches the ACL too, but
! PAT will only apply if the connection is NOT matched by
! a static NAT rule first. Static takes precedence.
! ============================================================
ip nat inside source list LAN_FOR_NAT interface GigabitEthernet0/0 overload
Verification: show ip nat translations
From a state after several inside hosts have made connections and the web server has received inbound connections:
Router# show ip nat translations
Pro Inside global Inside local Outside local Outside global
tcp 203.0.113.1:80 192.168.1.100:80 --- ---
tcp 203.0.113.1:443 192.168.1.100:443 --- ---
tcp 203.0.113.1:80 192.168.1.100:80 1.2.3.4:55001 1.2.3.4:55001
tcp 203.0.113.1:80 192.168.1.100:80 5.6.7.8:48902 5.6.7.8:48902
tcp 203.0.113.1:443 192.168.1.100:443 9.10.11.12:61234 9.10.11.12:61234
tcp 203.0.113.1:1024 192.168.1.10:52341 8.8.8.8:443 8.8.8.8:443
tcp 203.0.113.1:1025 192.168.1.10:44891 1.1.1.1:80 1.1.1.1:80
tcp 203.0.113.1:1026 192.168.1.15:38201 172.217.3.4:443 172.217.3.4:443
udp 203.0.113.1:1027 192.168.1.10:53204 8.8.8.8:53 8.8.8.8:53
icmp 203.0.113.1:1028 192.168.1.20:512 8.8.8.8 8.8.8.8
Reading this table:
Rows 1-2: Static NAT base entries for ports 80 and 443. The --- in the outside columns means no active connection is currently using the exact base entry (active connections create separate extended entries). These base entries exist permanently due to the static NAT configuration.
Rows 3-5: Active inbound connections to the web server. Three external clients (1.2.3.4, 5.6.7.8, 9.10.11.12) are connected to the web server. The inside global and inside local addresses here reflect the static NAT port mapping. Note that inside local shows port 80 and 443 because those are the ports the web server is actually listening on.
Rows 6-8: PAT entries for inside hosts making outbound connections. Each uses a different inside global port (1024, 1025, 1026). All share the same inside global IP (203.0.113.1), the router’s WAN IP.
Row 9: A UDP DNS query from 192.168.1.10. Translated to port 1027 on the outside.
Row 10: ICMP echo from 192.168.1.20. Uses ICMP identifier 512 (shown in the port field).
Verification: show ip nat statistics
Router# show ip nat statistics
Total active translations: 10 (2 static, 8 dynamic; 8 extended)
Outside interfaces:
GigabitEthernet0/0
Inside interfaces:
GigabitEthernet0/1
Hits: 4821 Misses: 2
CEF Translated packets: 4820, CEF Punted packets: 1
Expired translations: 47
Dynamic mappings:
-- Inside Source
[Id: 1] access-list LAN_FOR_NAT interface GigabitEthernet0/0 refcount 8
extended: 8
-- Inside Source
[Id: 2] access-list LAN_FOR_NAT interface GigabitEthernet0/0 refcount 0
(static nat entries)
Pool stats drop: 0 Mapping stats drop: 0
Port block alloc fail: 0
IP alias add fail: 0
Limit entry add fail: 0
Statistics look healthy: 2 misses out of 4821 hits (normal; misses occur when new translations are created and a table lookup finds no existing entry). Pool stats drop is 0 (no pool exhaustion). Both interfaces correctly listed as inside and outside.
Ping Test with debug ip nat
Enable debug on the router, then ping from 192.168.1.20:
Router# debug ip nat
From 192.168.1.20, run ping 8.8.8.8:
*May 26 10:41:22.331: NAT*: s=192.168.1.20->203.0.113.1, d=8.8.8.8 [1001]
*May 26 10:41:22.335: NAT*: s=8.8.8.8, d=203.0.113.1->192.168.1.20 [1001]
*May 26 10:41:22.831: NAT*: s=192.168.1.20->203.0.113.1, d=8.8.8.8 [1002]
*May 26 10:41:22.835: NAT*: s=8.8.8.8, d=203.0.113.1->192.168.1.20 [1002]
*May 26 10:41:23.331: NAT*: s=192.168.1.20->203.0.113.1, d=8.8.8.8 [1003]
*May 26 10:41:23.335: NAT*: s=8.8.8.8, d=203.0.113.1->192.168.1.20 [1003]
*May 26 10:41:23.831: NAT*: s=192.168.1.20->203.0.113.1, d=8.8.8.8 [1004]
*May 26 10:41:23.835: NAT*: s=8.8.8.8, d=203.0.113.1->192.168.1.20 [1004]
*May 26 10:41:24.331: NAT*: s=192.168.1.20->203.0.113.1, d=8.8.8.8 [1005]
*May 26 10:41:24.335: NAT*: s=8.8.8.8, d=203.0.113.1->192.168.1.20 [1005]
Five echo/reply pairs visible, corresponding to a 5-packet ping. Each pair has matching packet IDs. Source translation outbound (192.168.1.20 -> 203.0.113.1) and destination reverse translation inbound (203.0.113.1 -> 192.168.1.20) are both visible. This confirms NAT is functioning end-to-end for ICMP.
Disable debug:
Router# undebug all
All possible debugging has been turned off
NAT Hairpin / NAT Reflection
A situation that surprises engineers the first time they encounter it: an inside host tries to reach an internal server using the server’s public IP address. This happens when internal DNS is configured to return the public IP for a hostname (because that hostname was set up for external access), and an inside host resolves that hostname and sends packets to the public IP.
SCENARIO:
- Web server: 192.168.1.100 (private), 203.0.113.1:80 (public via static NAT)
- DNS entry: www.example.com -> 203.0.113.1
- Inside host 192.168.1.10 resolves www.example.com -> 203.0.113.1
WHAT HAPPENS:
- 192.168.1.10 sends packet: src=192.168.1.10 dst=203.0.113.1
- Packet arrives at NAT router on inside interface (Gi0/1)
- Router performs routing lookup: 203.0.113.1 is the router's own Gi0/0 address
(or it's routed out Gi0/0 toward the ISP in some configurations)
- If the router routes the packet out Gi0/0 (outside), NAT would translate
the source to the inside global, but the destination (203.0.113.1) matches
the static NAT entry... different behavior depending on IOS version and config
PROBLEM:
In many configurations, the packet gets routed to the ISP or loops,
instead of being reflected back to 192.168.1.100.
The inside host cannot reach the inside server via its public IP.
Hairpin NAT Configuration
Hairpin NAT (also called NAT loopback or NAT reflection) requires the router to accept the packet from inside, translate both the source (to the inside global) and the destination (using the static NAT entry), and route the translated packet back into the inside network. The response from the server comes back to the router, which reverses both translations and returns the packet to the originating inside host.
! This configuration alone often does NOT solve hairpin automatically.
! Hairpin behavior depends on IOS version. On some versions it works
! automatically if the static NAT is configured. On others, you need:
ip nat inside source static 192.168.1.100 203.0.113.1
! The router must apply NAT when both source and destination
! interfaces are inside. IOS 12.4(T) and later support this with
! the standard static NAT command, but behavior varies.
! Verify by checking translations after an inside-to-public-IP connection:
show ip nat translations
! You should see an entry where both inside local and outside local
! are in the private address space.
The cleaner, more reliable solution to the hairpin problem is split-horizon DNS (also called split-brain DNS or split DNS). In this model, the internal DNS server returns the private IP (192.168.1.100) for www.example.com when queried by inside hosts, while the public DNS server returns the public IP (203.0.113.1) for external queries. Inside hosts connect directly to 192.168.1.100 — no NAT traversal required, no hairpin complexity, lower latency. This is the architectural recommendation for any environment where inside hosts need to reach inside servers by their public hostnames.
NAT and Application Layer Issues
NAT operates at Layer 3 (IP addresses) and Layer 4 (ports). This causes fundamental problems with application-layer protocols that embed IP addresses in their payload — because NAT rewrites addresses in the IP header but does not touch the application payload, the embedded addresses become stale and incorrect after translation.
FTP Active Mode
In FTP active mode, the client opens a control connection to the server on port 21. When the client wants to transfer data, it sends a PORT command in the application payload: PORT 192,168,1,10,20,45 (telling the server to connect back to 192.168.1.10 on port (20*256)+45 = 5165 for the data channel).
When this packet transits a NAT router, the source IP in the IP header is translated from 192.168.1.10 to 203.0.113.1. But the PORT command in the FTP payload still says 192.168.1.10. The FTP server dutifully tries to connect to 192.168.1.10 — a private address that is unreachable from the internet. The data transfer fails.
Cisco IOS includes an Application Layer Gateway (ALG) for FTP that specifically handles this: the FTP ALG parses FTP control connections, detects PORT commands, rewrites the embedded IP address to the translated (inside global) address, and updates any length fields in the payload. This happens transparently as part of the NAT process.
! FTP ALG is enabled by default in most IOS versions.
! To verify:
show ip nat translations verbose
! Look for FTP-related translations with port 21 as the outside local port.
! If FTP passive mode is used (PASV command), the server provides the
! address/port. Since the server is on the outside, and NAT does not
! translate outside addresses in standard source NAT, FTP passive mode
! generally works better through NAT than active mode.
SIP and H.323
VoIP protocols SIP (Session Initiation Protocol) and H.323 embed IP addresses and ports in their signaling messages for media negotiation. A SIP INVITE message contains SDP (Session Description Protocol) body with the client’s private IP address for the media stream:
v=0
o=- 12345 1 IN IP4 192.168.1.10
c=IN IP4 192.168.1.10
m=audio 49170 RTP/AVP 0
After NAT translates the IP header, the SDP still references 192.168.1.10. The remote endpoint tries to send audio to 192.168.1.10, which is unreachable. The call connects (signaling works) but there is no audio.
IOS includes SIP and H.323 ALGs, but they are not always reliable, particularly with encrypted SIP (SIPS/TLS), where the ALG cannot read the payload to rewrite addresses. The practical solution for VoIP through NAT is STUN, TURN, or ICE (discussed below), or ensuring SIP is not encrypted at the NAT boundary, or using a SBC (Session Border Controller) that is NAT-aware.
PPTP
PPTP (Point-to-Point Tunneling Protocol) uses TCP port 1723 for control but encapsulates data using GRE (Generic Routing Encapsulation, IP protocol 47), which is not TCP or UDP and has no port numbers. Early NAT implementations could not handle GRE properly because they had no ports to use for disambiguation. Cisco IOS includes a PPTP ALG that tracks GRE sessions using the PPTP call ID embedded in GRE packets.
STUN, TURN, and ICE for WebRTC
Modern applications — particularly WebRTC for browser-to-browser audio/video — have developed a standard suite for NAT traversal:
STUN (Session Traversal Utilities for NAT): A protocol that allows a client behind NAT to discover its own public IP address and the type of NAT it is behind. The client contacts a STUN server on the public internet; the server reflects the source IP and port back to the client, which learns its inside global address. This allows the client to advertise its public address in signaling.
TURN (Traversal Using Relays around NAT): When STUN is insufficient (for example, with symmetric NAT, where the outside port changes for each new destination), TURN provides a relay server on the public internet. Both endpoints send media to the TURN server, which relays it between them. This always works but introduces latency and server cost.
ICE (Interactive Connectivity Establishment): A framework that combines STUN and TURN. ICE gathers multiple candidate addresses for each endpoint (local IPs, STUN-discovered public IPs, TURN relay addresses) and systematically tests connectivity between all pairs to find the best working path. WebRTC uses ICE internally; the NAT traversal happens automatically without the application needing to implement NAT-specific logic.
Troubleshooting NAT: Systematic Approach
When NAT is not working, the failure is almost always one of a small set of root causes. The following methodology works through them in a logical order.
Step 1: Confirm Interface Designation
Router# show ip nat statistics
Outside interfaces:
GigabitEthernet0/0
Inside interfaces:
GigabitEthernet0/1
If either the inside or outside interface is missing from this output, ip nat inside or ip nat outside is not configured on that interface. NAT will never trigger for traffic on an undesignated interface. Fix:
interface GigabitEthernet0/1
ip nat inside
interface GigabitEthernet0/0
ip nat outside
Step 2: Confirm the ACL is Matching
For dynamic NAT and PAT, the ACL determines which inside sources are eligible for translation. If the ACL does not match, NAT never triggers.
Router# show access-lists
Standard IP access list LAN_FOR_NAT
10 permit 192.168.1.0, wildcard bits 0.0.0.255 (match count 142)
The match count (142) increases as traffic matches the ACL. If the match count is zero or not increasing while inside hosts are attempting connections, the ACL is not matching. Common causes:
- Wrong subnet or wrong wildcard mask in the ACL (e.g., using 0.0.0.0 instead of 0.0.0.255 accidentally restricts to a single host).
- ACL references a named ACL but the
ip nat inside source listcommand references a numbered ACL, or vice versa (name must match exactly). - Inside host’s IP is outside the range permitted by the ACL.
Also check the show ip nat statistics miss count. If Misses is high and growing while Hits is low, translations are failing to be created. This often indicates an ACL mismatch.
Step 3: Check Translation Table
Router# show ip nat translations
If inside hosts are connecting but the table is empty (no entries), translations are not being created. This points to:
- Interface designation missing (already covered).
- ACL not matching (already covered).
- Both interfaces are designated but as the same direction (both inside, or both outside). Traffic must cross from an inside interface to an outside interface to trigger NAT.
If the translation table shows entries but traffic is not flowing, the issue is not NAT creation but forwarding. Check routing and firewall rules.
Step 4: Verify Routing
NAT translates addresses but does not route packets. For PAT to work:
- The inside hosts must have a default gateway pointing to the NAT router’s inside interface (192.168.1.1).
- The NAT router must have a route to the internet (typically a default route to the ISP).
- The ISP must be routing traffic back to the NAT router’s public IP.
Router# show ip route 8.8.8.8
Routing entry for 0.0.0.0/0 (default route)
Known via "static", distance 1, metric 0
Routing Descriptor Blocks:
* 203.0.113.2
Route metric is 0, traffic share count is 1
If no default route exists, the router has no way to forward translated packets to the internet.
Step 5: Check Pool Exhaustion (Dynamic NAT)
For dynamic NAT (without overload), pool exhaustion causes new connections to fail while existing ones continue:
Router# show ip nat statistics
Pool stats drop: 47 Mapping stats drop: 0
A non-zero Pool stats drop value means packets were dropped because no pool address was available. Solutions: expand the pool, reduce NAT timeouts to free entries faster, or convert to PAT (overload).
Router# show ip nat translations | count 192
! Count lines in the translation table
If the number of translations equals the pool size, the pool is exhausted.
Step 6: Use debug ip nat to Trace Packets
If the above checks do not identify the problem, enable NAT debug and reproduce the failure:
Router# debug ip nat
! Generate traffic from inside host
! Look for translation attempts
Router# undebug all
If you see NAT debug output at all, the packet is reaching the router and NAT is triggering. If you see only outbound translations (s=inside->outside) but no return translations (d=outside->inside), return traffic is not reaching the router. This suggests:
- A routing problem between the internet destination and the NAT router.
- A firewall or security group blocking return traffic.
- The inside host’s source port / IP is being translated but the return packets are arriving on a different path (asymmetric routing).
If you see no debug output whatsoever for traffic from an inside host, the packet is not triggering NAT:
- The interface is not designated.
- The ACL is not matching the source.
- The packet is arriving on the correct interface but leaving on another inside interface (inside-to-inside traffic does not trigger NAT).
Step 7: Clear Stale Translations
Sometimes a stale translation entry prevents a new correct entry from being created, or a wrong entry causes traffic to be translated incorrectly. Clearing the translation table forces new entries to be created from scratch:
! Clear all dynamic translations (static entries are not cleared)
Router# clear ip nat translation *
! Clear a specific translation by inside local and outside addresses
Router# clear ip nat translation inside 192.168.1.10 outside 8.8.8.8
! Clear translations for a specific protocol and ports
Router# clear ip nat translation tcp inside 192.168.1.10 52341 outside 8.8.8.8 80
Note: clear ip nat translation * only clears dynamic entries. Static NAT entries (created with ip nat inside source static) are not deleted by this command. To remove a static entry, remove the configuration line:
Router(config)# no ip nat inside source static 192.168.1.100 203.0.113.100
Common Mistake Reference Table
| Mistake | Symptom | Diagnosis | Fix |
|---|---|---|---|
Missing ip nat inside on LAN interface |
No translations created | Interface missing from “Inside interfaces” in show ip nat statistics |
Add ip nat inside to LAN interface |
Missing ip nat outside on WAN interface |
No translations created | Interface missing from “Outside interfaces” in show ip nat statistics |
Add ip nat outside to WAN interface |
| ACL too restrictive | Only some hosts work | ACL match count low; specific hosts show no translations | Widen ACL to cover all inside subnets |
| ACL name mismatch | No translations for any host | No ACL match counts incrementing despite traffic | Ensure ACL name in ip nat inside source list matches ACL definition exactly |
| Pool subnet mask wrong | Translations fail | Pool entry in show ip nat statistics shows “invalid pool” |
Verify pool start/end IPs are within the declared netmask range |
| Missing default route | NAT creates translation but packets do not reach internet | show ip route 0.0.0.0 shows no default route |
Add ip route 0.0.0.0 0.0.0.0 [next-hop] |
| Dynamic NAT pool exhausted | New connections fail, existing work | Non-zero Pool stats drop in show ip nat statistics |
Add overload to enable PAT, or expand pool |
| Static NAT port conflict | Port-forwarded service unreachable | Entry missing from translation table or duplicate entry error | Verify no two static entries map the same inside global port |
Forgot overload on PAT |
Only one inside host can use NAT at a time (first-come-first-served pool) | Only one host’s translation visible; others’ packets dropped | Add overload to the ip nat inside source list ... pool command |
NAT and IPv6
IPv6 was designed with the explicit goal of eliminating NAT. With 128-bit addresses providing 340 undecillion unique addresses (3.4 x 10^38), there is no practical address exhaustion problem. Every device on earth could have billions of unique IPv6 addresses. In an IPv6-only world, every host gets a globally unique address and communicates directly with any other host — the original end-to-end principle of IP networking, without the middlebox that NAT requires.
IPv6 has been in standardized form since 1998. Widespread adoption has been slower than anticipated, partly because of the chicken-and-egg problem (content providers did not prioritize IPv6 because clients did not use it; clients did not prioritize IPv6 because content was not available), but significantly also because NAT made the IPv4 address exhaustion problem tolerable enough at the organizational level that there was no immediate operational crisis pushing organizations to migrate.
Despite this, NAT does appear in IPv6 contexts, for two reasons:
NAT64
NAT64 translates between IPv6 and IPv4. As more networks become IPv6-only (particularly mobile networks), they need to reach IPv4-only services on the internet. NAT64 routers maintain a pool of IPv4 addresses and translate IPv6 packets destined for IPv4 hosts by:
- Using a well-known IPv6 prefix (64:ff9b::/96 or a locally-configured prefix) to represent IPv4 addresses in IPv6 space. The last 32 bits of the IPv6 address encode the IPv4 destination.
- When an IPv6 client sends a packet to an address in the NAT64 prefix (e.g., 64:ff9b::8.8.8.8), the NAT64 router translates the packet to IPv4, substituting a pool IPv4 address as the source and 8.8.8.8 as the destination.
- Return IPv4 traffic is translated back to IPv6.
NAT64 typically pairs with DNS64, a DNS resolver that synthesizes AAAA records (IPv6) for IPv4-only hostnames by prepending the NAT64 prefix to the IPv4 address.
Cisco IOS supports NAT64 with:
! Enable NAT64
ipv6 unicast-routing
interface GigabitEthernet0/0
ipv6 address 2001:db8:1::1/64
nat64 enable
interface GigabitEthernet0/1
ip address 203.0.113.1 255.255.255.252
nat64 enable
nat64 v6v4 source list ACL6 pool POOL4 overload
NPTv6 (Network Prefix Translation for IPv6)
NPTv6 (RFC 6296) is a stateless, one-to-one address translation between two IPv6 prefixes. Unlike NAT44, NPTv6 does not use a translation table — it modifies the prefix portion of IPv6 addresses using an algorithmic mapping that preserves the interface identifier portion. The checksum is adjusted to compensate for the prefix change.
NPTv6 use cases:
- Multihoming: an organization has two ISP prefixes and wants to use either prefix for outbound traffic while maintaining stable internal addressing.
- Provider independence: using an internal ULA (Unique Local Address) prefix internally while mapping to the public prefix assigned by the ISP.
! NPTv6 example (translates internal prefix to external prefix)
interface GigabitEthernet0/1
description LAN
ipv6 address fd00:192:168:1::1/64
ipv6 nat
interface GigabitEthernet0/0
description WAN
ipv6 address 2001:db8:1:2::1/64
ipv6 nat
ipv6 nat prefix 2001:db8:1:2::/64 v6v6 map fd00:192:168:1::/64
NPTv6 is technically not “NAT” in the address-sharing sense — it does not conserve address space and does not hide topology. It is a prefix translation mechanism. It preserves the end-to-end reachability property (each host still has a unique global address) while allowing flexible prefix management.
The IPv6 Security Question
A persistent concern among network architects considering IPv6: without NAT, inside hosts are directly addressable from the internet. The NAT “firewall effect” disappears.
The IETF’s position is that this is actually correct behavior. Security should be enforced by stateful firewalls, access control lists, and proper security policies — not by NAT as a side effect. An IPv6 border router should have stateful firewall rules that block unsolicited inbound connections, just as an IPv4 NAT device implicitly does, but explicitly and under controlled policy rather than as an accident of address translation.
In practice, most enterprise IPv6 deployments do implement firewall rules that replicate the “block unsolicited inbound” behavior at the perimeter. The difference from NAT is that the firewall policy is explicit and auditable, and inside hosts can be explicitly permitted inbound access where needed without requiring complex port-forwarding rules.
Exam Quick Reference
The CCNA exam frequently tests NAT through scenario-based questions. The most commonly tested points:
Address type identification: Given a diagram showing private networks, a NAT router, and a public destination, identify which address is the inside local, inside global, outside local, and outside global. Remember: local = inside network’s perspective, global = internet’s perspective. Inside = the host is on the private side, outside = the host is on the public side.
Static vs dynamic vs PAT: Static = permanent one-to-one, used for servers. Dynamic = pool-based one-to-one, first-come-first-served. PAT = many-to-one using ports, most common.
Required configuration elements for PAT: (1) Interface designation (ip nat inside / ip nat outside), (2) ACL defining inside sources, (3) ip nat inside source list [ACL] interface [outside-int] overload.
show ip nat translations columns: Pro, Inside global, Inside local, Outside local, Outside global — in that order, in that exact column sequence.
Troubleshooting hierarchy: Check interface designation -> check ACL match -> check translation table -> check routing -> use debug ip nat -> clear stale entries.
Translation timeout commands: ip nat translation timeout for general; ip nat translation tcp-timeout, udp-timeout, icmp-timeout for protocol-specific.
Clearing translations: clear ip nat translation * clears dynamic entries only. Static entries require removing the configuration with no ip nat inside source static ....
PAT port range: Dynamic PAT assignments use ports 1024-65535. Well-known ports (below 1024) are avoided for dynamic assignment to prevent conflicts with incoming connections to well-known services.
NAT and PAT sit at the intersection of Layer 3 addressing, Layer 4 transport, and stateful session tracking. The four address types encode a precise description of where a packet is observed and whether it has been translated. The Cisco IOS toolset — show ip nat translations, show ip nat statistics, and debug ip nat — gives complete visibility into what the translation engine is doing at every step. Master the address terminology, understand which configuration element does what (interface designation, ACL, pool/interface, overload keyword), and work through the troubleshooting methodology systematically, and NAT questions on the CCNA become straightforward.
Comments