IP NAT is a very common configuration. One of the challenges that sometimes surfaces is the need for internal hosts to connect to the public address of a locally hosted server. Anyone who has tried to configure something like the following has likely faced this issue.
In this example, the top of the diagram represents the outside (Internet, ISP, or External Server), the left represents the DMZ area, and the bottom represents the inside. The goal is to enable dynamic port address translation for internal hosts and static port address translation for the host or hosts found in the DMZ area.
This configuration is fairly straightforward and typically covered in the CCNA curriculum. This includes identifying each interface as inside or outside and configuring the appropriate nat statements.
R1 Configuration
interface FastEthernet1/0 description To INSIDE ip address 192.168.1.1 255.255.255.0 ip nat inside ! interface FastEthernet1/1 description To ACME WWW ip address 192.168.2.1 255.255.255.0 ip nat inside ! interface FastEthernet1/2 description To OUTSIDE ip address 192.0.2.100 255.255.255.0 ip nat outside ! ip nat inside source list 1 interface FastEthernet1/2 overload ip nat inside source static tcp 192.168.2.2 80 192.0.2.100 80 extendable ! access-list 1 permit 192.168.1.0 0.0.0.255 ! ip host www.acme.com 192.0.2.100 ip dns server
H1 Configuration
interface FastEthernet0/0 ip address 192.168.1.2 255.255.255.0 ! ip route 0.0.0.0 0.0.0.0 192.168.1.1 ! ip name-server 192.168.1.1 ip domain-lookup
H2 Configuration
interface FastEthernet0/0 ip address 192.0.2.1 255.255.255.0 ! ip name-server 192.0.2.100 ip domain-lookup
WWW Server
interface FastEthernet0/0 ip address 192.168.2.2 255.255.255.0 ! ip route 0.0.0.0 0.0.0.0 192.168.2.1 ip http server
When we begin testing, we see that H2 can reach www.acme.com.
H2#telnet www.acme.com 80 Trying www.acme.com (192.0.2.100, 80)... Open GET / HTTP/1.1 HTTP/1.1 400 Bad Request Date: Fri, 01 Mar 2002 00:45:52 GMT Server: cisco-IOS Connection: close Accept-Ranges: none
We also see that H1 can reach the outside host(s)
H1#ping 192.0.2.1 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.0.2.1, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 16/23/32 ms
However, H1 cannot reach www.acme.com
H1#telnet www.acme.com 80 Translating "www.acme.com"...domain server (192.168.1.1) [OK] Trying www.acme.com (192.0.2.100, 80)... % Connection refused by remote host
Further testing reveals that H1 can reach port 80 on WWW, but the private address must be used.
H1#telnet 192.168.2.2 80 Trying 192.168.2.2, 80 ... Open GET / HTTP/1.1 HTTP/1.1 400 Bad Request Date: Fri, 01 Mar 2002 00:49:11 GMT Server: cisco-IOS Connection: close Accept-Ranges: none
So the problem we see here is that internal users cannot connect to the public address. The public address is being returned by the DNS server. In our case DNS is actually on R1, but it might be outside in a small environment. Larger enterprises typically have internal DNS servers. Since traffic destined to www.acme.com would be exchanged between two interfaces identified as “inside”, no translation would occur. In this case, the packets might actually land on the “outside” interface but not be transmitted. In any case, the NAT logic is not properly applied.
There are a few options that could resolve this issue.
- Use a separate DNS server and return internal addresses to the inside users
- Use static NAT and translate the DNS Replies to private addresses (requires static one to one translations)
- Use NAT Virtual Interface to make the NAT process interface agnostic
We will look at solving this challenge using the third option. To implement this, we will change the interface commands to ip nat enable and remove the inside keyword from the NAT statements.
R1 Changes
interface FastEthernet1/0 no ip nat inside ip nat enable ! interface FastEthernet1/1 no ip nat inside ip nat enable ! interface FastEthernet1/2 no ip nat outside ip nat enable ! no ip nat inside source list 1 interface FastEthernet1/2 overload no ip nat inside source static tcp 192.168.2.2 80 192.0.2.100 80 extendableå ! ip nat source list 1 interface FastEthernet1/2 overload ip nat source static tcp 192.168.2.2 80 192.0.2.100 80 extendable
As we can see, H2 can still reach www.acme.com.
H2#telnet www.acme.com 80 Translating "www.acme.com"...domain server (192.0.2.100) [OK] Trying www.acme.com (192.0.2.100, 80)... Open GET / HTTP/1.1 HTTP/1.1 400 Bad Request Date: Fri, 01 Mar 2002 01:03:04 GMT Server: cisco-IOS Connection: close Accept-Ranges: none
However H1 can now access both the outside host(s) and www.acme.com.
H1#ping 192.0.2.1 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.0.2.1, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 20/25/44 ms H1#telnet www.acme.com 80 Translating "www.acme.com"...domain server (192.168.1.1) [OK] Trying www.acme.com (192.0.2.100, 80)... Open GET / HTTP/1.1 HTTP/1.1 400 Bad Request Date: Fri, 01 Mar 2002 01:04:41 GMT Server: cisco-IOS Connection: close Accept-Ranges: none
One thing to note is that the NVI show commands are different. Using the show ip nat translations command no longer shows any translations. The command show ip nat nvi translations is now required.
R1#show ip nat translations Pro Inside global Inside local Outside local Outside global ! R1#show ip nat nvi translations Pro Source global Source local Destin local Destin global tcp 192.0.2.100:80 192.168.2.2:80 --- ---
Conclusion
IP NAT is a common configuration option for IOS devices. However, traditional NAT configuration is interface dependent. Using NAT Virtual Interface or NVI is a way to decouple the NAT process from the inside and outside interface designations. One thing to note in our configuration is that www.acme.com was on a separate interface. Had it been behind the inside interface, we would have needed to disable ICMP redirects by using the no ip redirects on the internal interface.
Disclaimer: This article includes the independent thoughts, opinions, commentary or technical detail of Paul Stewart. This may or may not reflect the position of past, present or future employers.
Hi Stewart,
thx for this nice write-up. It helped me solve my problem accessing internal server on FQDN.
I have a problem related to this, i have two VPN tunnels configured, one FULL tunnel and one SPLIT tunnel and in none of them i can’t use the FQDN but i can ofcourse use the internal IP, any way to resolve that ?
/mihai
Are you having trouble getting the two (one split and one full tunnel) configurations working together? Or is access to the internal address not working with one or both of the tunnel configs?
Hi Paul,
Thx for replying. Either the two tunnels work as intended separetly but i can’t access my server on my FQDN when i am using the tunnel, i have to type in the internal ip. When i am on WiFi on the internal network i can access my server with the FQDN after the changes you have suggested above.
Here is my config : https://gist.github.com/anonymous/2930d4cb82e073f1e7cc
/mihai
I’m not sure what may be going on there. I would start out by running Wireshark on the server and see if they packets are making it there. That will help determine if the packets are inbound from the client or outbound through the router. That should cut the possible problems by about half and make it easier to troubleshoot.
Hi Paul,
So i did what you suggested, here is the output of wireshark while i try to access the webserver on my Mac :
https://www.dropbox.com/s/6s7mjz0lfi4tm08/from_workstation.pcapng?dl=0
I used filter ip.addr == 2.108.123.138 and not tcp.port == 22 and i only exported stuff that fullfilled this filter.
on the webserver which is a Synology NAS i ran tcpdump and that can be opened in wireshark as well and the link to that is :
https://www.dropbox.com/s/7jk5m94b6pbb3wd/on_webserver.pcapng?dl=0
Here is used tcpdump -vv -i eth0 host 83.151.148.180 and dst port 5000
I don’t know the reason to this but i am suspect NVI for some weird manipulations with the packet.
Maybe you have an idea ?
Ok i have figured it out, it was the MTU on my ATM0.1 that was set wrong so i changed that to 1500 and it worked but i do have another question for you which is related to NVI.
Why is the extendable setting needed ? I tried without and the NAT won’t work then when i try to access my server from outside. I don’t like the fact that i can’t specify the interface and i need to specify the ip.
for example i can’t write this :
ip nat source static tcp 192.168.1.15 80 interface ATM0.1 80 extendable
but i can write this :
ip nat source static tcp 192.168.1.15 80 X.X.X.X 80 extendable
where x.x.x.x is my WAN ip.
At the moment i have a static WAN ip but unfortunately i won’t have that soon and then it’s a problem to have such ip in the config. Any ideas what to do about that ?
just to add few more details :
If i add ip nat source static tcp 192.168.1.15 80 X.X.X.X 80 extendable it works then i remove it with no ip nat source static tcp 192.168.1.15 80 X.X.X.X 80 extendable then i add ip nat source static tcp 192.168.1.15 80 interface ATM0.1 80 and now it still works.
I then did clear ip nat translations * and clear ip nat nvi translations and it still works but i think that after a reload this will stop to work. I find this weird behaviour but i guess there is some kind of explanation.
Extendable sort of makes dynamic NAT entries track on a per session basis. It creates entries that use both source and destination ports in the NAT table. So when there are advanced use cases, extendible is usually a good thing. Think of it as adding state to your NAT table. Sometimes it is necessary, sometimes it isn’t.