A brief introduction to setting up NAT on Cisco devices
Written on Nov 03, 2022 by Remco Kersten in Networking
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 184.108.40.206. The internal router (R1) converts the internal IP address into an IP address obtained from the provider, in this case 220.127.116.11. 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 can be configured in 3 ways, depending on the requirements and the number of assigned IP addresses:
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 18.104.22.168/24 in the above network from the ISP. We could choose to always translate 192.168.0.1 to 22.214.171.124. 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 126.96.36.199 R1(config)#end R1#show ip nat translations Pro Inside global Inside local Outside local Outside global --- 188.8.131.52 192.168.0.1 --- ---
show ip nat translations shows that 192.168.0.1 is translated to 184.108.40.206
A packet capture of a ping from 192.168.0.1 to 220.127.116.11 looks like this:
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:
access-list x permit network wildcard
ip nat pool name firstIP lastIP netmask subnetmask
ip nat inside source list listnumber pool poolname
In the example below, IP addresses 18.104.22.168 through 22.214.171.124 are assigned by the ISP. 126.96.36.199 is already in use by R1, so we’re going to use 188.8.131.52 through 184.108.40.206 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 220.127.116.11 18.104.22.168 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 22.214.171.124, then the NAT Table looks like this:
R1#show ip nat translations Pro Inside global Inside local Outside local Outside global --- 126.96.36.199 192.168.0.1 --- --- icmp 188.8.131.52:1 192.168.0.2:1 184.108.40.206:1 220.127.116.11:1 --- 18.104.22.168 192.168.0.2 --- ---
192.168.0.1 has been temporarily translated to 22.214.171.124, and 192.168.0.2 has been temporarily translated to 126.96.36.199.
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 188.8.131.52. 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:
access-list x permit network wildcard
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 184.108.40.206, then the NAT Table looks like this:
R1#show ip nat translations Pro Inside global Inside local Outside local Outside global tcp 220.127.116.11:49682 192.168.0.2:49682 18.104.22.168:80 22.214.171.124:80
And to make it a bit clearer, another packet capture between the router and the ISP: