Using NVI to Allow Internal Hosts to Connect to Public Addresses of Hosted Servers

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.

IP NAT ExampleIn 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.

  1. Use a separate DNS server and return internal addresses to the inside users
  2. Use static NAT and translate the DNS Replies to private addresses (requires static one to one translations)
  3. 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.

About Paul Stewart, CCIE 26009 (Security)

Paul is a Network and Security Engineer, Trainer and Blogger who enjoys understanding how things really work. With over 15 years of experience in the technology industry, Paul has helped many organizations build, maintain and secure their networks and systems.
This entry was posted in CCNA, Certification, General, Network, Security, Technology and tagged , , , . Bookmark the permalink.

8 Responses to Using NVI to Allow Internal Hosts to Connect to Public Addresses of Hosted Servers

  1. mihaicph says:

    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

    • Paul Stewart, CCIE 26009 (Security) says:

      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?

      • mihaicph says:

        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.

  2. mihaicph says:

    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 ?

  3. mihaicph says:

    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 ?

  4. mihaicph says:

    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.

Leave a Reply