What is NAT?

NAT is short for “Network Address Translation”. The basic purpose of NAT is to translate private IP addresses which are used inside the company into public (global) IP addresses.

NAT is primarily used to conserve global IP addresses because it allows many IP-enabled devices to use a few public IP addresses. It’s really easy to see NAT at work. For instance, at your workplace, you and your colleagues are probably represented by a single IP address and NAT allows you all to access the Internet at the same time.

To verify all this simply go on some What’s my IP? service from yours and your friend’s computer, and you’ll see that you and your friend have the same IP address. In reality the address you see is the address of a router that runs NAT.

Even at your home, you can see the effects of NAT. Go to Start->Run and type CMD. When the prompt opens type: ipconfig /all to see the IP addresses of all your devices. It will probably be something like: 192.168.1.X.

On a Mac, you can use ifconfig en0, for example.

Then go on the What’s my IP? service and you’ll see that your IP address you use to access the Internet is different. That’s NAT at work.

How NAT works?

In order to better explain how NAT works, we need to know types of addresses that exist in NAT:

Address Types in NAT
  1. Inside local – This is the source address before the NAT translation, assigned to a host on a private network, from a private address range.
  2. Inside global – Source address after translation. This is the address the destination sees. This is the public IP address assigned by the ISP.
  3. Outside global – Destination address known by the source. This is a public IP address.
  4. Outside local – Destination private address. This is known to the hosts on their private network.

So, how does NAT work? First, HOST1 sends a packet to the R1 router that’s configured with NAT. R1 then sees that HOST1 source IP address is a inside local, translates it to the Inside global address and forward it with new new (translated) source address as a packet source. R1 makes note of translation in the NAT table.

So, basically NAT modifies the IP packet with a new source address. Router forwards the packet with a new address. The packet then normally continues to it’s destination.

When replying the external HOST2 forwards the packet to it’s default gateway, R2. R2 is directly connected to R1, whose address is now a destination address, because it was used as a source. When packet arrives at the R1, R1 translates address back to the inside local address using the NAT table. When the translation is done, R1 forwards the packet to the HOST1.

NAT types

There are three types of NAT:

  1. Static NAT
    Static NAT allows us to translate IP addresses in one-to-one ratio, which means we need one public Internet address for every host in the network.
  2. Dynamic NAT
    Dynamic NAT allows us to have a “pool” of public addresses, which are translated into the same number of host addresses. Same thing, we need one public Internet address for every host in the network. However, unlike static NAT with dynamic NAT the translation doesn’t really take place until one is needed.
  3. NAT Overload (PAT – Port Address Translation)
    Now we’re talking! This is the most useful type of NAT available. NAT Overload enables us to map multiple private IP addresses to single public IP address (N:1)! How? Router uses port numbers to identify which host’s address is translated and that means we could theoretically have ~ 65000 hosts on a single public IP address.

All types of NAT are basically simple to configure, as you will see in the next configuration example. Funny thing is, most problems that, you think come from using NAT aren’t related to NAT at all, but to routing.

Configuration examples

Once again, we’ll use Routers to play the part of Hosts. We’ll make a network design like the one in the image:

Source translation – Overload

NOTE: As NAT Overload is most useful type of NAT, we’ll use it here. We’ll get to static later.

We’ll make NAT router translate the HOST1’s private address to public address so that HOST1 can communicate with HOST2. Simple, really. So, let’s get to it.

The IP addresses used are:

  • HOST1 F0/0 ->
  • NAT F1/0 ->
  • NAT S0/0 ->
  • R2 S0/0 ->
  • R2 F1/0 ->
  • HOST2 F0/0 ->

So, let,s get to it. First, let’s configure R2 and both HOSTS:

R2#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R2(config)#int s0/0
R2(config-if)#ip add
R2(config-if)#no shut

R2(config-if)#int f1/0
R2(config-if)#ip add
R2(config-if)#no shut

Now for HOST1:

HOST1#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
HOST1(config)#int f0/0
HOST1(config-if)#ip add
HOST1(config-if)#no shut

We’ll use NAT router as the default gateway for HOST1:

HOST1(config-if)#ip route

We’ll configure HOST2 in the same manner:

HOST2#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
HOST2(config)#int fast
HOST2(config)#int fastEthernet 0/0
HOST2(config-if)#ip address
HOST2(config-if)#no shut
*Mar  1 00:02:23.671: %LINK-3-UPDOWN: Interface FastEthernet0/0, changed state to up
*Mar  1 00:02:24.671: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/0, changed state to up
HOST2(config-if)#ip route

OK, we configured HOSTS and R2, now to configure NAT router for inside translation so that HOST1 can communicate to HOST2. Of course, we first need to configure NAT router’s interfaces. When configuring interfaces we have to configure NAT on them as well. First, let’s configure the Serial interface:

NAT#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
NAT(config)#int ser 0/0
NAT(config-if)#ip add
NAT(config-if)#ip nat outside

*Mar  1 00:01:53.991: %LINEPROTO-5-UPDOWN: Line protocol on Interface NVI0, changed state to up
NAT(config-if)#no shutdown

Now for Fast Ethernet:

NAT(config-if)#int f1/0
NAT(config-if)#ip nat inside
NAT(config-if)#ip address
NAT(config-if)#no shutdown

Now the interfaces are configured properly. In our NAT configuration we first need to determine which addresses that NAT router will translate. In this case it’ll translate all the addresses in the network. We’ll create an access list to permit translations of addresses in that subnet. Creating an access list is easy, remember you can always use inline-help:

NAT(config)#access-list 1 ?
deny    Specify packets to reject
permit  Specify packets to forward
remark  Access list entry comment

NAT(config)#access-list 1 permit ?
Hostname or A.B.C.D  Address to match
any                  Any source host
host                 A single host address

NAT(config)#access-list 1 permit ?
A.B.C.D  Wildcard bits
log      Log matches against this entry

NAT(config)#access-list 1 permit

We only need that one entry, because we want to permit only that one network and because of the implicite deny at the end of an access list all other addresses are denied. We can view the access list by using show command:

NAT#show ip access-lists 1
Standard IP access list 1
10 permit, wildcard bits

After we created our access-list we need to create a NAT pool of global addresses. Remember, we’re doing NAT overload, so only one address is really needed:

NAT(config)#ip nat pool ?
WORD  Pool name

NAT(config)#ip nat pool global ?
A.B.C.D        Start IP address
netmask        Specify the network mask
prefix-length  Specify the prefix length

NAT(config)#ip nat pool ?
WORD  Pool name

NAT(config)#ip nat pool global ?
A.B.C.D        Start IP address
netmask        Specify the network mask
prefix-length  Specify the prefix length

NAT(config)#ip nat pool global netmask

So, we create NAT pool named “global” with only one address. Now to configure NAT itself:

NAT(config)#ip nat inside ?
destination  Destination address translation
source       Source address translation

NAT(config)#ip nat inside source ?
list       Specify access list describing local addresses
route-map  Specify route-map
static     Specify static local->global mapping

NAT(config)#ip nat inside source list 1 ?
interface  Specify interface for global address
pool       Name pool of global addresses

NAT(config)#ip nat inside source list 1 pool global overload

So, we configured inside source translation, described it with access list we created earlier and used our address pool for global addresses. We also added overload keyword. So, now everything should work, right? Because we’re translating the private addresses, we should be able to reach HOST2, from HOST1, right? Observe:


Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to, timeout is 2 seconds:
Success rate is 0 percent (0/5)

What’s happening? It’s simple, really. NAT router doesn’t have a route to the network, so it can’t forward the packets. Remember, we’re translating addresses. The routers need to have new addresses in their routing tables. Let’s fix this:

NAT(config)#ip route

Now let’s try it:


Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to, timeout is 2 seconds:
Success rate is 80 percent (4/5), round-trip min/avg/max = 828/972/1104 ms

See? R2 doesn’t have a route to the network, but the packet returns anyway. That’s because packet’s source address gets translated to and R2 knows about that network. Let’s see what happens on NAT router:

NAT#show ip nat translations
Pro Inside global      Inside local       Outside local      Outside global

NAT#debug ip nat
IP NAT debugging is on
*Mar  1 00:33:54.859: NAT*: s=>, d= [20]
*Mar  1 00:33:56.075: NAT*: s=, d=> [20]
*Mar  1 00:33:56.619: NAT*: s=>, d= [21]
*Mar  1 00:33:57.275: NAT*: s=, d=> [21]
*Mar  1 00:33:57.651: NAT*: s=>, d= [22]
*Mar  1 00:33:58.339: NAT*: s=, d=> [22]
*Mar  1 00:33:58.699: NAT*: s=>, d= [23]
*Mar  1 00:33:59.351: NAT*: s=, d=> [23]
*Mar  1 00:33:59.511: NAT*: s=>, d= [24]
*Mar  1 00:34:00.295: NAT*: s=, d=> [24]

The IP address of HOST1 gets translated to Once the packet returns router knows via NAT table that it’s destined for host, so it translates the to and forwards the packet there.

Static translation

That is all good an well, you say, but what about the situation when a host from the Internet needs to contact a server on our private LAN? (For example, e-mail needs to be delivered to our company server)

As you can see, there’s a new router which represents the server to which people need to connect. SERVER’s IP address is: This is a private address, which means we need to use NAT router to translate it.

But, first, let’s configure the server. Nothing complicated here, we just need to add IP address to the interface, and a default route to

SERVER#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
SERVER(config)#int f0/0
SERVER(config-if)#ip add
SERVER(config-if)#no shut
*Mar  1 00:05:52.635: %LINK-3-UPDOWN: Interface FastEthernet0/0, changed state to up
*Mar  1 00:05:53.635: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/0, changed state to up
SERVER(config-if)#ip route

OK, server’s configuration is complete, now back to NAT router.

We’ll configure static NAT, meaning we’ll translate one private address to one public address, in this case to

NAT(config)#ip nat inside source static

So, we just need to tell R2 how to reach

R2(config)#ip route

Note that we haven’t even configured this address on an interface, but we don’t have to. gets translated to this address on NAT router, so NAT router will know that the destination for is really, meaning we can reach host on a private network:

Trying ... Open

User Access Verification


[Connection to closed by foreign host]

So, that’s basically it. We can get from the private network to the Internet and users from outside our network can reach our server via a public address.

OK, we have definitely scratched the surface of NAT. There’s more to learn and to configure, but we’ll do that in some future blog post. Until then, happy networking or exam preparation! 🙂