Skip to content
Log in Sign up My account

3.3.b NAT and PAT

Blueprint 3.3.b: Configure NAT/PAT

  • Inside local, inside global, outside local and outside global addresses
  • Static NAT and static PAT (port forwarding)
  • Dynamic NAT with a pool
  • PAT (overload) to an interface or a pool
  • NAT order of operations and its effect on ACLs and routing
  • Verification and common failure modes

The verb is configure, and NAT is one of the most likely simulation items on ENCOR (see Sim 07). You need to type static, dynamic and PAT configurations without help, read show ip nat translations fluently, and know what breaks when one line is missing.

The four addresses

NAT terms combine two ideas:

  • Inside or outside says which host the address belongs to: a host on the inside network or a host on the outside network.
  • Local or global says where the address is seen: local is how it looks on the inside network, global is how it looks on the outside network.
Term Whose address Seen from Example
Inside local Inside host Inside 10.10.10.10, the PC's real private address
Inside global Inside host Outside 203.0.113.2, what the internet sees for that PC
Outside local Outside host Inside Usually the same as outside global, unless outside NAT is configured
Outside global Outside host Outside 198.51.100.80, the web server's real address
graph LR
  PC["PC<br/>inside local 10.10.10.10"] -->|"src 10.10.10.10<br/>dst 198.51.100.80"| R1["R1<br/>Gi0/1 inside, Gi0/0 outside"]
  R1 -->|"src 203.0.113.2 inside global<br/>dst 198.51.100.80 outside global"| WEB["Web server<br/>198.51.100.80"]

In ordinary source NAT only the inside host's address changes, so outside local equals outside global. The two outside terms differ only when you also translate the destination with ip nat outside source.

Interface roles

NAT only acts on traffic that crosses from an ip nat inside interface to an ip nat outside interface, or the reverse. Traffic between two inside interfaces is never translated.

interface GigabitEthernet0/1
 description LAN
 ip address 10.10.10.1 255.255.255.0
 ip nat inside
!
interface GigabitEthernet0/0
 description ISP
 ip address 203.0.113.2 255.255.255.252
 ip nat outside

The NAT types

Static NAT

A permanent one-to-one mapping. It works in both directions, so outside hosts can start sessions to the inside host using its inside global address. Use it for servers.

ip nat inside source static 10.10.20.10 203.0.113.10

The inside global address (203.0.113.10) does not need to be configured on any interface, but the ISP must route it to R1. If it is on the same subnet as R1's outside interface, R1 answers ARP for it automatically (IOS creates an alias for static NAT addresses).

Static PAT (port forwarding)

Maps one inside address and port to an outside address and port. Only that port is reachable from outside.

ip nat inside source static tcp 10.10.20.20 80 203.0.113.2 8080
! or, when the outside address is DHCP-learned:
ip nat inside source static tcp 10.10.20.20 80 interface GigabitEthernet0/0 8080

An internet user browsing to http://203.0.113.2:8080 reaches 10.10.20.20 on port 80. When the same inside global address is used in several static entries (port forwards plus a PAT rule), add extendable to the static entries; IOS often adds it automatically.

Dynamic NAT

A pool of public addresses mapped one-to-one on demand. The first inside host gets the first free address, and so on. When the pool is empty, new hosts fail until a translation times out.

ip access-list standard NAT-USERS
 permit 10.10.10.0 0.0.0.255
!
ip nat pool PUBLIC 203.0.113.33 203.0.113.38 netmask 255.255.255.248
! or: ip nat pool PUBLIC 203.0.113.33 203.0.113.38 prefix-length 29
ip nat inside source list NAT-USERS pool PUBLIC

The ACL selects which inside local addresses are eligible. It is matched against the source address before translation. A deny in the ACL means "do not translate", not "drop".

PAT (NAT overload)

Many inside hosts share one inside global address. The router tells sessions apart by Layer 4 port (or ICMP query ID). It tries to keep the original source port and picks another free port if that one is already in use for that global address.

ip nat inside source list NAT-USERS interface GigabitEthernet0/0 overload

Uses whatever address is on the outside interface, so it works with DHCP from the ISP.

ip nat pool PUBLIC 203.0.113.33 203.0.113.38 prefix-length 29
ip nat inside source list NAT-USERS pool PUBLIC overload

Uses the first pool address until its ports run out, then the next.

route-map NAT-ISP1 permit 10
 match ip address NAT-USERS
 match interface GigabitEthernet0/0
route-map NAT-ISP2 permit 10
 match ip address NAT-USERS
 match interface GigabitEthernet0/2
!
ip nat inside source route-map NAT-ISP1 interface GigabitEthernet0/0 overload
ip nat inside source route-map NAT-ISP2 interface GigabitEthernet0/2 overload

match interface checks the egress interface chosen by routing, so each session is translated to the address of whichever ISP it leaves through.

Type Mapping Direction sessions can start Typical use
Static NAT 1 inside local to 1 inside global Both Public servers
Static PAT 1 local IP:port to 1 global IP:port Both, for that port Port forwarding
Dynamic NAT Many locals to a pool, 1 to 1 at a time Inside to outside only Rare today; when apps break with PAT
PAT (overload) Many locals to 1 (or a few) globals using ports Inside to outside only Internet access for users

Exam trap

Dynamic NAT without overload and a pool of n addresses lets exactly n inside hosts out at once. The symptom in a question is "the first few users work, the rest do not". The fix is overload, not a bigger netmask on the pool.

Outside source NAT

ip nat outside source translates the address of an outside host as it appears on the inside. It is used for overlapping address spaces, for example after a merger when both companies use 10.1.0.0/16.

ip nat outside source static 10.1.5.20 172.31.5.20 add-route

Inside hosts send to 172.31.5.20 (outside local). R1 rewrites the destination to 10.1.5.20 (outside global) on the way out. add-route installs a host route for the outside local address so routing can find the path, because, as the next section shows, inside-to-outside traffic is routed before it is translated.

NAT order of operations

This is the part of NAT the exam likes to test with ACLs and routing. Cisco's documented order, simplified to what matters:

Inside to outside (packet arrives on an inside interface) Outside to inside (packet arrives on an outside interface)
1. Inbound ACL on the inside interface 1. Inbound ACL on the outside interface
2. Policy routing 2. NAT outside to inside
3. Routing 3. Policy routing
4. NAT inside to outside 4. Routing
5. Outbound ACL on the outside interface 5. Outbound ACL on the inside interface
graph LR
  subgraph IO ["Inside to outside"]
    A1["ACL in"] --> A2["Route"] --> A3["NAT"] --> A4["ACL out"]
  end
  subgraph OI ["Outside to inside"]
    B1["ACL in"] --> B2["NAT"] --> B3["Route"] --> B4["ACL out"]
  end

Consequences you must be able to reason about:

  • Inside to outside, route then translate. The routing lookup uses the original destination. That is why outside source NAT needs add-route or a static route to the outside local address.
  • Outside to inside, translate then route. The router un-translates the inside global destination back to the inside local address first, then routes to the inside local address. The router therefore needs a route to the inside network, which it normally has as a connected route.
  • An inbound ACL on the outside interface sees pre-translation addresses, so it must permit the inside global address (for example, permit traffic to 203.0.113.10, not to 10.10.20.10).
  • An outbound ACL on the outside interface sees post-translation addresses, so it also sees the inside global address as source.
  • An inbound ACL on the inside interface sees the inside local address.

Exam trap

An ACL applied inbound on the outside interface that permits host 10.10.20.10 eq 80 does nothing useful for a static NAT server. Traffic from the internet is destined for the inside global address when the ACL runs, because NAT happens after the inbound ACL. Write the ACL for 203.0.113.10.

Verification

R1# show ip nat translations
Pro  Inside global         Inside local          Outside local         Outside global
---  203.0.113.10          10.10.20.10           ---                   ---
tcp  203.0.113.2:8080      10.10.20.20:80        ---                   ---
tcp  203.0.113.2:51514     10.10.10.10:51514     198.51.100.80:443     198.51.100.80:443
tcp  203.0.113.2:1024      10.10.10.11:51514     198.51.100.80:443     198.51.100.80:443
icmp 203.0.113.2:3         10.10.10.10:3         198.51.100.80:3       198.51.100.80:3
Total number of translations: 5

Reading it:

  • Lines with --- in the outside columns are static entries. They are always present, even with no traffic.
  • The two TCP sessions from .10 and .11 used the same source port 51514. The first kept its port; the second was moved to 1024 so the global socket stays unique. That is PAT at work.
  • ICMP translations use the ICMP query identifier in place of a port.
R1# show ip nat statistics
Total active translations: 5 (2 static, 3 dynamic; 3 extended)
Outside interfaces:
  GigabitEthernet0/0
Inside interfaces:
  GigabitEthernet0/1, GigabitEthernet0/2
Hits: 1840  Misses: 22
Expired translations: 19
Dynamic mappings:
-- Inside Source
[Id: 1] access-list NAT-USERS interface GigabitEthernet0/0 refcount 3

Check Outside interfaces and Inside interfaces first: a missing interface here is the most common fault. Hits are packets that matched an existing translation. Misses are packets that needed a new one. If misses climb but translations do not appear, the ACL or pool is the problem.

Other useful commands:

clear ip nat translation *           ! clears dynamic entries; static entries stay
debug ip nat                         ! shows each translation, use with care
show ip nat translations verbose     ! adds timers and flags per entry

Default translation timeouts on IOS: dynamic NAT entries 24 hours (86,400 s), TCP PAT entries 24 hours, UDP 5 minutes, DNS 1 minute, ICMP 1 minute, and TCP sessions that saw FIN or RST 1 minute. Tune with ip nat translation timeout, tcp-timeout, udp-timeout and so on.

Exam trap

You cannot change or remove a dynamic NAT rule or pool while it has active translations. IOS answers with a "pool in use" or "dynamic mapping in use" message. Run clear ip nat translation * first. Expect a sim to hide this behind a task like "change the pool range".

Common failure modes

Symptom Likely cause
No translations at all Missing ip nat inside or ip nat outside; ACL does not match the inside subnet; traffic never routed out the outside interface
Only some subnets work ACL in the NAT rule covers only one subnet; wrong wildcard mask
First n users work, rest fail Dynamic NAT pool without overload
Server reachable from inside but not outside Static entry missing, ISP has no route to the inside global, or inbound ACL written for the inside local address
Port forward works to one port only Correct: static PAT only forwards the listed port. A second service needs a second entry.
NAT works, return traffic dropped Asymmetric path: return traffic arrives on a router that has no translation state
Cannot edit the pool Active translations; clear them first

Lab: PAT for users, static NAT for a server, a port forward

Topology: a cut-down version of the base topology: R1 edge router, ISP router, a user host and a server.

graph LR
  H1["Host1<br/>10.10.10.10"] -- "Gi0/1 10.10.10.1/24 inside" --- R1
  S1["Srv1<br/>10.10.20.10"] -- "Gi0/2 10.10.20.1/24 inside" --- R1
  R1 -- "Gi0/0 203.0.113.2/30 outside" --- ISP["ISP<br/>Gi0/0 203.0.113.1<br/>Lo1 198.51.100.80/24"]

The ISP owns 203.0.113.0/24 and has routed 203.0.113.32/29 to R1 for servers (ip route 203.0.113.32 255.255.255.248 203.0.113.2 on ISP).

  1. Address the interfaces and set roles.

    interface GigabitEthernet0/0
     ip address 203.0.113.2 255.255.255.252
     ip nat outside
    interface GigabitEthernet0/1
     ip address 10.10.10.1 255.255.255.0
     ip nat inside
    interface GigabitEthernet0/2
     ip address 10.10.20.1 255.255.255.0
     ip nat inside
    ip route 0.0.0.0 0.0.0.0 203.0.113.1
    
  2. PAT for both inside subnets to the outside interface.

    ip access-list standard NAT-USERS
     permit 10.10.10.0 0.0.0.255
     permit 10.10.20.0 0.0.0.255
    ip nat inside source list NAT-USERS interface GigabitEthernet0/0 overload
    
  3. Static NAT for the server to 203.0.113.33 and a port forward of SSH on the outside interface address, port 2222, to the server's port 22.

    ip nat inside source static 10.10.20.10 203.0.113.33
    ip nat inside source static tcp 10.10.20.10 22 203.0.113.2 2222 extendable
    
  4. Generate traffic: from Host1 ping 198.51.100.80 and telnet 198.51.100.80 80 (enable ip http server on ISP if you want it to connect). From ISP ping 203.0.113.33 source 198.51.100.80 and ssh -l admin -p 2222 203.0.113.2 (Srv1 needs SSH configured for this one).

  5. Verify:

    R1# show ip nat translations
    Pro  Inside global         Inside local          Outside local         Outside global
    ---  203.0.113.33          10.10.20.10           ---                   ---
    tcp  203.0.113.2:2222      10.10.20.10:22        ---                   ---
    icmp 203.0.113.2:1         10.10.10.10:1         198.51.100.80:1       198.51.100.80:1
    icmp 203.0.113.33:2        10.10.20.10:2         198.51.100.80:2       198.51.100.80:2
    

    Notice that traffic the server starts uses its static inside global (203.0.113.33), not the PAT address. Static entries take priority over the dynamic rule for the same inside local address.

  6. Break it. Remove ip nat inside from Gi0/2. Server traffic is no longer translated, and the ISP drops replies because it has no route to 10.10.20.0/24. Check show ip nat statistics to see the interface missing from the list. Restore it.

  7. Break it differently. On R1 create ip access-list extended FROM-ISP with the single entry permit icmp any host 10.10.20.10, and apply ip access-group FROM-ISP in on Gi0/0. From ISP, ping 203.0.113.33. It fails, because the inbound ACL runs before NAT and sees the destination 203.0.113.33, which only the implicit deny matches. Change the entry to permit icmp any host 203.0.113.33 and the pings succeed. Remove the ACL afterwards, because it also blocks return traffic for the PAT users.

Quick check

A router has ip nat inside source static 10.1.1.5 203.0.113.5 and also PAT for 10.1.1.0/24 to the outside interface. Which inside global address does 10.1.1.5 use when it browses the internet?

203.0.113.5. A static translation for an inside local address takes priority over a dynamic rule, so the host always uses its static global address in both directions.

Traffic from inside to outside: does the router make the routing decision on the original destination or the translated one?

The original one. Inside to outside, routing happens before NAT. Outside to inside, NAT happens first and the router routes on the translated (inside local) destination.

show ip nat translations shows only lines with --- in the outside columns. What does that tell you?

Only static entries exist. No dynamic or PAT translation has been created, so either no traffic has crossed inside to outside or the dynamic rule (ACL, interface roles, routing) is not matching.

References