How to Configure Static NAT on Cisco (One-to-One + Port Forwarding)
Static NAT solves one specific problem: making an internal server reachable from the outside at a fixed, predictable public address. Unlike PAT (overload), which hides many hosts behind one address for outbound sessions, static NAT is a permanent one-to-one binding that works in both directions — outside clients hit the inside-global address and the router forwards them to the inside-local host, and traffic the host originates is sourced from that same public address. This guide walks the full configuration on Cisco IOS: tagging the interfaces, building the one-to-one map, adding port forwarding with static PAT, verifying, and correcting the mistakes that keep translations from working. If you want to practice without production risk, build the same topology in Cisco Modeling Labs — the virtual appliance you run in a hypervisor such as VMware — where you also control the upstream "ISP" router.
Part of the NAT & PAT learning hub
Step 1 — Learn the four address types and plan the mapping
NAT terminology trips up more CCNA candidates than the commands do. The router sits on the boundary between your network and the outside world, and it names each address by two axes: 'inside' vs 'outside' (whose network the host belongs to) and 'local' vs 'global' (the pre-translation private view vs the post-translation public view).
For a static NAT server the two that matter are: the inside-local address — the real private IP configured on the server (here 192.168.1.10) — and the inside-global address — the public IP that outside clients use to reach it (here 203.0.113.10). The outside-local and outside-global fields describe the far-end client; static NAT does not touch them, so they show up as '---' in the translation table.
A useful memory hook: 'local' = the address as seen inside your private network, 'global' = the address as seen on the public internet. Static NAT permanently welds one inside-local to one inside-global. Plan which private server needs a public identity and which public address you own (or, in a lab, which address your upstream router will route back to you) before you type a single command.
This guide uses RFC 1918 space 192.168.1.0/24 on the LAN and TEST-NET-3 203.0.113.0/24 on the WAN so the examples are safe to copy into a lab and never collide with a real public prefix.
Step 2 — Flag the inside and outside interfaces
NAT is interface-driven. The router only translates a packet when it crosses from an interface marked 'ip nat inside' to one marked 'ip nat outside' (or the reverse). If you skip this step, the mapping in Step 3 is configured but inert — nothing is translated, and this is the single most common reason a working config still fails.
Tag the LAN-facing interface (toward the server) as inside and the WAN-facing interface (toward the internet/upstream) as outside. The IP addressing shown here is illustrative; use whatever your topology dictates.
R1(config)# interface GigabitEthernet0/0
R1(config-if)# description LAN toward inside server
R1(config-if)# ip address 192.168.1.1 255.255.255.0
R1(config-if)# ip nat inside
R1(config-if)# exit
R1(config)# interface GigabitEthernet0/1
R1(config-if)# description WAN toward ISP
R1(config-if)# ip address 203.0.113.1 255.255.255.0
R1(config-if)# ip nat outside
R1(config-if)# exitStep 3 — Create the static one-to-one mapping
Now bind the private server to its public address. The command order is inside-local first, then inside-global — read it as 'translate the inside source 192.168.1.10 so it appears as 203.0.113.10'. Reversing the two addresses is a classic, silent mistake (covered in Common Problems).
Unlike dynamic NAT, a static entry is installed the instant you enter the command — it appears in 'show ip nat translations' with no traffic required, and it never ages out. That permanence is exactly what an inbound-reachable server needs: the public-to-private path is always ready before the first client connects.
R1(config)# ip nat inside source static 192.168.1.10 203.0.113.10
R1(config)# end
R1# show running-config | include ip natStep 4 — Expose a single port with static PAT (port forwarding)
A full one-to-one map dedicates an entire public IP to one host. Often you only want to publish one service — say a web server on TCP 80 — while keeping the public address free for other uses. That is static PAT, better known as port forwarding: you add a protocol and port to the static command so only that port is redirected.
The syntax is 'ip nat inside source static tcp <inside-local> <local-port> <inside-global> <global-port>'. You can translate the port too — for example expose an internal 8080 service on public 80 by using different port numbers on each side. Use 'udp' instead of 'tcp' for UDP services. You may add several port-specific entries that share the same inside-global address, each publishing a different service.
! Publish the inside web server on the public IP, TCP 80 only
R1(config)# ip nat inside source static tcp 192.168.1.10 80 203.0.113.10 80
! Optional: present an internal 8080 app as public port 80 (port translation)
R1(config)# ip nat inside source static tcp 192.168.1.20 8080 203.0.113.10 80
! Optional: forward a UDP service (e.g. DNS)
R1(config)# ip nat inside source static udp 192.168.1.30 53 203.0.113.10 53Step 5 — Verify the translation and counters
Confirm the mapping exists and that packets are actually hitting it. 'show ip nat translations' lists every active entry; a full one-to-one static map shows the inside-global paired with the inside-local and dashes for the outside columns, while a static PAT entry shows the protocol and :port on both global and local sides.
'show ip nat statistics' is the fastest diagnostic on the box: it reports how many total and static translations exist, the hit/miss counters, and — critically — which interfaces are tagged inside and which are outside. If that interface list is empty or wrong, you have found your problem immediately (see Step 2).
Because static entries are permanent, 'clear ip nat translation *' clears only dynamic sessions; the static rows repopulate instantly. Use 'debug ip nat' sparingly and only in a lab to watch translations happen in real time — it is verbose and can overwhelm a busy router.
R1# show ip nat translations
Pro Inside global Inside local Outside local Outside global
--- 203.0.113.10 192.168.1.10 --- ---
tcp 203.0.113.10:80 192.168.1.10:80 --- ---
R1# show ip nat statistics
Total active translations: 2 (2 static, 0 dynamic; 1 extended)
Outside interfaces:
GigabitEthernet0/1
Inside interfaces:
GigabitEthernet0/0
Hits: 128 Misses: 0
! Clears dynamic entries only; static rows come right back
R1# clear ip nat translation *How static NAT differs from PAT / overload
PAT (also called NAT overload) maps many inside hosts to one public address by multiplexing on source port numbers. It is built for outbound traffic: an inside host initiates a session, the router creates a dynamic entry, and only return traffic that matches that entry is allowed back in. Entries are created on demand and age out when idle. Nothing on the outside can start a new connection inbound, because there is no pre-existing mapping to match.
Static NAT is the opposite trade-off: one inside host, one dedicated public address, a permanent entry, and full bidirectionality. Outside clients can initiate connections to the inside-global address at any time, and the host's own outbound traffic is consistently sourced from that same public IP. That is why static NAT (or static PAT) is the tool for publishing servers, and PAT/overload is the tool for giving a crowd of clients shared outbound internet access. They coexist happily on the same router.
For contrast, a typical overload configuration looks like the block below — note it references an ACL of source networks and the outside interface, with no fixed one-to-one binding.
! PAT / overload for outbound client traffic (contrast, not part of static NAT)
R1(config)# access-list 1 permit 192.168.1.0 0.0.0.255
R1(config)# ip nat inside source list 1 interface GigabitEthernet0/1 overloadCommon problems (and the fix)
1) Interfaces not flagged inside/outside — nothing translates. The mapping is present in the running-config but no packet ever gets rewritten. Fix: run 'show ip nat statistics' and confirm both an inside and an outside interface are listed; add the missing 'ip nat inside' / 'ip nat outside' to the correct interfaces. Remember NAT acts only on traffic that crosses the inside-to-outside boundary.
2) inside-local and inside-global reversed. 'ip nat inside source static 192.168.1.10 203.0.113.10' means local first, global second. Swap them and the router advertises the wrong direction, translations look backwards, and reachability breaks. Fix: 'show run | include ip nat' and confirm the private (192.168.x) address is first, the public address second; remove and re-enter the line with 'no ip nat inside source static ...' if needed.
3) The inside-global address is not routed back to the router. Static NAT can rewrite the packet, but the outside world still has to deliver traffic for 203.0.113.10 to this router. Fix: ensure the upstream/ISP router has a route for the inside-global address (or subnet) pointing at your WAN interface. If the global address sits in the WAN interface's own connected subnet, the router answers ARP for it automatically; if it is a routed block, add the static/BGP route upstream. In a CML lab this means configuring the neighboring 'ISP' router to route the public prefix to you.
4) Expecting outbound-only behavior. Static NAT is bidirectional by design — the moment you configure it, the inside server is reachable from the outside on every port (a full one-to-one map) or on the published port (static PAT). That surprises people who assume NAT hides the host. Fix: this is not a bug; if you do not want the whole world reaching that server, apply an inbound ACL or a zone-based firewall on the outside interface to permit only the intended sources and ports. Static PAT already narrows exposure to a single port, which is usually preferable to mapping an entire public IP.
5) Duplicate or conflicting mapping. Trying to reuse an inside-global address that is already bound to another host, or re-entering an existing static line, yields a '%' error or unpredictable results, and mixing a full static map with a static PAT entry on the same public IP can conflict. Fix: pick one model per public address — a single full one-to-one map, or one-or-more port-specific static PAT entries — and use 'show ip nat translations' to confirm you do not have overlapping inside-global assignments.
Frequently asked questions
Does the public (inside-global) address have to be assigned to the router's outside interface?
No. The inside-global address only needs to be reachable by the router; you configure it in the 'ip nat inside source static' command, not with a second 'ip address' on the interface. The router answers ARP for that mapped address on the outside segment on the host's behalf, so it can live in the outside interface's subnet without being bound to the interface. If it belongs to a different subnet, the upstream/ISP router must have a route pointing that address back to you.
My server can reach the Internet outbound, but inbound connections from outside still fail. Why?
On outside-to-inside traffic the router checks an inbound ACL on the outside interface BEFORE it does the global-to-local NAT translation, so the ACL sees the destination as the inside-global (public) address, not the inside-local one. If your ACL permits the private inside address it will silently drop the return-path or new inbound sessions. Permit the inside-global address (and the right port for static PAT), and confirm the outside router actually routes that public address to you.
If I add static NAT for one server, do my other inside hosts still get Internet access?
No. A static NAT entry translates only the one host you mapped; every other inside host has no translation and its traffic is dropped or unroutable. Add a separate PAT/overload rule (an ACL plus 'ip nat inside source list ... interface ... overload') for general outbound access. Static NAT and PAT coexist on the same router, and the static one-to-one binding takes precedence for its mapped host.
How do I change or clear a static NAT mapping that seems stuck?
Static mappings live in the running config and never age out, so to edit one you negate the line with 'no ip nat inside source static ...' and re-add the corrected version. Active entries can stay cached in the translation table after a change, so flush them with 'clear ip nat translation *' (or a targeted form) to force the new mapping to take effect. Only dynamic and PAT entries have timeouts; static ones persist until you remove them.
Can I practice static NAT in Packet Tracer instead of Cisco Modeling Labs?
Yes for the fundamentals — Packet Tracer simulates IOS well enough for one-to-one static NAT and static PAT, and pre-authored .pka activities can even auto-grade your work. CML runs real IOS/IOS-XE images as a virtual appliance inside a hypervisor (VMware Workstation/Fusion is the supported host and is currently free for personal use; VirtualBox is not a supported CML host), so it reflects production behavior more faithfully for edge cases like ACL-order and ISP routing. Use Packet Tracer for quick reps and CML when you need real-image fidelity; verify current pricing and version support before you commit.
Practice this on graded Cisco labs
Reading is step one — build NAT & PAT on real Cisco IOS and grade your own config, or try a free sample lab first.