LUNAROPS · OPERATIONAL UPLINK 100% UPTIME 1,247d POSTS 893 JEFF.MOON@LUNAROPS.DEV UTC --:--:--

CCNA: NAT and PAT — Network Address Translation in Depth

ccnanetworkingnatpatciscoiosipv4

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:

  1. Packet arrives on inside interface.
  2. Router performs a routing lookup to determine the exit interface.
  3. If the exit interface is an outside NAT interface, the router checks for a matching NAT translation.
  4. 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.
  5. For dynamic NAT or PAT: the router checks if the source IP matches an ACL referenced in an ip nat inside source list command. 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.
  6. 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):

  1. Packet arrives on outside interface.
  2. Router checks the destination IP (and port, for PAT) against the NAT translation table.
  3. If a match exists, the destination is rewritten to the inside local address.
  4. 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.1 means: 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.8 means 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:

  1. Use debug condition to limit debugging to specific hosts:

    debug condition interface GigabitEthernet0/1
    debug condition host 192.168.1.10
    
  2. Have undebug all (or its alias u all) ready to type immediately.

  3. 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
    
  4. On high-traffic routers, prefer debug ip nat to debug 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 list command 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:

  1. 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.
  2. 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.
  3. 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