blueSheep[dev];
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 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 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 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:
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 140.90.21.0 through 140.90.21.10 are assigned by the ISP. 149.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.
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:
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 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: