NAT (Network Address Translation) translates IP addresses on the network layer (L3) and port numbers on the transport layer (L4). This works well for most applications but it can cause issues for applications that include IP addresses or port numbers on the application layer.
Here are some example applications:
To make NAT work with these applications, we also need to translate address information in the application layer. An ALG (Application Level Gateway) is an application that translates this information in the payload of the application layer. NAT ALG performs the translation while translating the IP addresses and/or port numbers.
In this lesson, we will take a look at an application (DNS) that requires NAT ALG. I chose DNS since the name requests/replies are easy to understand and we can test everything on Cisco IOS routers.
We use the following topology:
Want to take a look for yourself? Here you will find the startup configuration of each device.
hostname DNS1 ! no ip routing ! ip host H1.NETWORKLESSONS.LOCAL 192.168.1.101 no ip cef ! interface GigabitEthernet0/1 ip address 192.168.1.150 255.255.255.0 ! ip default-gateway 192.168.1.254 ! ip dns server ! end
hostname H1 ! no ip routing ! ip name-server 192.168.1.150 no ip cef ! interface GigabitEthernet0/1 ip address 192.168.1.101 255.255.255.0 ! ip default-gateway 192.168.1.254 ! end
hostname H2 ! no ip routing ! ip name-server 192.168.2.150 no ip cef ! interface GigabitEthernet0/1 ip address 192.168.2.102 255.255.255.0 ! ip default-gateway 192.168.2.254 ! end
hostname R1 ! ip cef ! interface GigabitEthernet0/1 ip address 192.168.1.254 255.255.255.0 ip nat inside ip virtual-reassembly in ! interface GigabitEthernet0/2 ip address 192.168.2.254 255.255.255.0 ip nat outside ip virtual-reassembly in ! ip nat inside source static 192.168.1.101 192.168.2.101 ip nat inside source static 192.168.1.150 192.168.2.150 ! end
We have the following devices:
- R1 is our NAT router.
- H1 is a host on our LAN.
- DNS1 is our DNS server.
- H2 is a host somewhere outside of our network.
We have two static NAT rules:
- H1 is reachable from the outside through 192.168.2.101.
- DNS1 is reachable from the outside through 192.168.2.150.
The DNS server has one entry for H1, that’s it.
Let’s start with a simple lookup from H1:
H1#ping h1.networklessons.local Translating "h1.networklessons.local"...domain server (192.168.1.150) [OK] Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.168.1.101, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 2/3/8 ms
H1 resolves the hostname through the DNS server and pings its own IP address. We can see the address that it resolved with the
show hosts command:
H1#show hosts Default domain is not set Name/address lookup uses domain service Name servers are 192.168.1.150 Codes: UN - unknown, EX - expired, OK - OK, ?? - revalidate temp - temporary, perm - permanent NA - Not Applicable None - Not defined Host Port Flags Age Type Address(es) h1.networklessons.local None (temp, OK) 0 IP 192.168.1.101
I captured the answer of the DNS server, you can see it below:
As you can see above, the answer shows IP address 192.168.1.01 in the application layer of this packet.
The DNS server is reachable from the outside with IP address 192.168.2.150. Let’s see what happens when H2 does a DNS request. Let’s enable a debug on R1 to see NAT in action:
R1#debug ip nat IP NAT debugging is on
Now we try a ping from H2 to the hostname of H1:
H2#ping h1.networklessons.local Translating "h1.networklessons.local"...domain server (192.168.2.150) [OK] Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.168.2.101, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 6/9/16 ms
H2 gets an answer from the DNS server and pings IP address 192.168.2.101. This is the outside IP address of H1, not its real IP address. Take a look at the NAT debug on R1:
R1# NAT: s=192.168.2.102, d=192.168.2.150->192.168.1.150  NAT: DNS resource record 192.168.1.101 -> 192.168.2.101 NAT: s=192.168.1.150->192.168.2.150, d=192.168.2.102  NAT*: s=192.168.2.102, d=192.168.2.101->192.168.1.101  NAT*: s=192.168.1.101->192.168.2.101, d=192.168.2.102 
In the output above, we see that the IP addresses of the DNS server and H1 got translated, but it also shows us that the DNS resource record is translated from 192.168.1.01 to 192.168.2.101. That’s our NAT ALG in action.
Here is a capture of the DNS answer from H2 captured on the DNS server:
Above, you can see that it is sourced from 192.168.1.150 and the answer shows 192.168.1.101.
Below, we have the DNS answer captures on H2, after NAT:
Above, we see that the source IP address got translated and the answer on the application layer got translated to 192.168.2.101. We can also confirm this by looking at the DNS records that H2 knows about:
H2#show hosts Default domain is not set Name/address lookup uses domain service Name servers are 192.168.2.150 Codes: UN - unknown, EX - expired, OK - OK, ?? - revalidate temp - temporary, perm - permanent NA - Not Applicable None - Not defined Host Port Flags Age Type Address(es) h1.networklessons.local None (temp, EX) 0 IP 192.168.2.101
H2 has stored the outside IP address 192.168.2.101 for the hostname of H1.
You have now learned how NAT ALG translates address information on the application layer to make certain applications work through NAT. I hope you enjoyed this lesson. If you have any questions feel free to leave a comment.