Written by Remco Kersten, 03/11/2022

Categories: ccna

What is NAT?

NAT stands for Network Address Translation: an IP address is converted to another IP address. This is done by adjusting the source or destination address (depending on the type of NAT) in the IP header of an IP packet. Don’t worry, I’ll try to explain in a little more detail 😁.

Most networks internally use a private IP range (eg 192.168.0.0/24). These private IP ranges are necessary because there are simply not enough IPv4 addresses available to give every device in the world a unique IP address. (However, with IPv6 this is possible.)

Due to the shortage of IPv4 addresses, we are often allocated only 1 IP address on a connection with an ISP. However, we often have more than 1 device at home that wants to connect to the internet. That is why we choose to assign internal devices a private IP address, and to translate IP packets to the ISP into an assigned public IP address.

In the example below, 192.168.0.1 tries to ping to 213.23.90.12. The internal router (R1) converts the internal IP address into an IP address obtained from the provider, in this case 140.90.21.1. The IP packet can now be sent to the ISP. The server replies to the ping and sends it back to R1. R1 receives the IP packet, looks in its NAT Table and recognizes that this packet is for 192.168.0.1. R1 changes the destination to 192.168.0.1 and sends it back to the internal host over the LAN network.

NAT example 1

NAT configureren op Cisco devices

NAT kan, afhankelijk van de eisen en het aantal toegewezen IP adressen, op 3 manieren worden ingesteld:

  • Static NAT (static mapping between external to internal IP addresses)
  • Dynamic NAT (mapping between external to internal IP addresses based on pools)
  • NAT overload (mapping between external to internal IP addresses based on portnumber)

Static NAT

NAT netwerk voorbeeld Static

Static NAT is the static setting of an internal IP address to a public IP address. An inside local IP address is always translated to a specific outside global IP address.

Suppose we have received the range 140.90.21.0/24 in the above network from the ISP. We could choose to always translate 192.168.0.1 to 140.90.21.100.
We set this with the command ip nat inside source static internal-ip-address external-ip-address

Before doing this, we need to tell the router which port is on the internal network, and which port is on the external network. We set this under interface config with the command ip nat inside|outside.

R1(config)#int g0/0
R1(config-if)#ip nat inside
R1(config-if)#int g0/1
R1(config-if)#ip nat outside
R1(config-if)#exit
R1(config)#ip nat inside source static 192.168.0.1 140.90.21.100
R1(config)#end
R1#show ip nat translations
Pro Inside global      Inside local       Outside local      Outside global
--- 140.90.21.100      192.168.0.1        ---                ---

show ip nat translations shows that 192.168.0.1 is translated to 140.90.21.100

A packet capture of a ping from 192.168.0.1 to 140.90.21.100 looks like this:

IP packet capture static NAT intern

IP packet capture static NAT extern

Dynamic NAT

Dynamic NAT works the same as static NAT. The only difference is that we do not configure an inside global IP address per inside local IP address, but we specify a range of inside local and inside global addresses.

The moment an inside local IP packet goes to the internet, it is temporarily translated by the router to an IP address from a pool of inside global IP addresses.

Configuration is done in the following way:

  1. Indicate per interface whether it is inside or outside

  2. Create a standard access list, with a permit statement for inside local IP addresses to be translated.
    access-list x permit network wildcard

  3. Create a pool indicating which inside global IP addresses may be used.
    ip nat pool name firstIP lastIP netmask subnetmask

  4. Configure inside NAT
    ip nat inside source list listnumber pool poolname

In the example below, IP addresses 140.90.21.0 through 140.90.21.10 are assigned by the ISP.

1490.90.21.1 is already in use by R1, so we’re going to use 140.90.21.2 through 140.90.21.10 for the pool.

R1(config)#int g0/0
R1(config-if)#ip nat inside
R1(config-if)#int g0/1
R1(config-if)#ip nat outside
R1(config-if)#access-list 1 permit 192.168.0.0 0.0.0.255
R1(config)#ip nat pool public 140.90.21.2 140.90.21.10 netmask 255.255.255.0
R1(config)#ip nat inside source list 1 pool public
R1(config)#end
R1#show ip nat translations
R1#

If we look after the configuration in the NAT Table, we see no entries. This is because there have been no internal hosts trying to access the internet yet. Note that unlike static NAT, here IP mappings are assigned dynamically.

Suppose we let host ping 192.168.0.1 and 192.168.0.2 to 213.23.90.12, then the NAT Table looks like this:

R1#show ip nat translations
Pro Inside global      Inside local       Outside local      Outside global
--- 140.90.21.2        192.168.0.1        ---                ---
icmp 140.90.21.3:1     192.168.0.2:1      213.23.90.12:1     213.23.90.12:1
--- 140.90.21.3        192.168.0.2        ---                ---

192.168.0.1 has been temporarily translated to 140.90.21.2, and 192.168.0.2 has been temporarily translated to 140.90.21.3.

NAT overload (PAT)

What if we only got 1 IP address? This is also the case for most home connections or small businesses.

In this case we can use Port Address Translation. The inside global address is then always given the assigned IP address (which is also in use by the router), and the source port number is adjusted to keep up with network address translations.

In the example below, 192.168.0.2 tries to go to the web server (port 80) of 213.23.90.12. As the source address, a random outgoing port is chosen by the host. This outgoing port is stored in the NAT table by the router (after possible adjustment if the same port is used by another host). The web server sends its response back to R1 with the host’s source port as destination port. This in turn tells the router that it is destined for host 192.168.0.2.

Configuration of NAT overload is done in the following way:

  1. Indicate per interface whether it is inside or outside
  2. Create a standard access list, containing a permit statement for IP addresses that need to be translated.

    access-list x permit network wildcard
  3. Configure inside NAT

    ip nat inside source list listnumber interface interface-outside-port overload
R1(config)#int g0/0
R1(config-if)#ip nat inside
R1(config-if)#int g0/1
R1(config-if)#ip nat outside
R1(config-if)#access-list 1 permit 192.168.0.0 0.0.0.255
R1(config)#ip nat inside source list 1 interface g0/1 overload
R1(config)#end
R1#show ip nat translations
R1#

Suppose host 192.168.0.2 sends an HTTP request to 213.23.90.12, then the NAT Table looks like this:

R1#show ip nat translations
Pro Inside global      Inside local       Outside local      Outside global
tcp 140.90.21.1:49682  192.168.0.2:49682  213.23.90.12:80    213.23.90.12:80

And to make it a bit clearer, another packet capture between the router and the ISP:

IP packet capture PAT extern