NAT Virtual Interface

The most common method to configure NAT on Cisco IOS routers is what we call “domain-based NAT”. Each interface on the router has to be configured as “inside” or “outside”. This method of configuring NAT is considered the legacy method. The new way of configuring NAT is by using the NAT virtual interface.




Before I show you the configuration of the NAT virtual interface, let’s look at the differences between legacy NAT and the NAT virtual interface.

When we use the inside and outside domains then the “order of operations” of the router looks like this:

Cisco NAT Inside Outside Operations

When an IP packet is received on the inside interface, then the router will first do a looking in the routing table and then it will perform NAT translation. When we receive IP packets on the outside interface, then it’s the other way around:

Cisco NAT Outside Inside operations

IP packets will first be NAT translated and then routed. Now you might be wondering, why should I care about this? To answer that question, we’ll have to do a little experiment. Here are three routers that we will use:

R1 R2 R3 NAT Virtual Interface

R1 on the left side is on our LAN, the “inside” of our network. R3 is on the “outside” and R2 will be configured for NAT.

Configurations

Want to try this example yourself? Here you will find the startup configuration of each device.

R1

hostname R1
!
no ip routing
!
no ip cef
!
interface GigabitEthernet0/1
 ip address 192.168.12.1 255.255.255.0
!
end

R2

hostname R2
!
ip cef
!
interface GigabitEthernet0/1
 ip address 192.168.12.2 255.255.255.0
!
interface GigabitEthernet0/2
 ip address 192.168.23.2 255.255.255.0
!
end

R3

hostname R3
!
no ip routing
!
no ip cef
!
interface GigabitEthernet0/1
 ip address 192.168.23.3 255.255.255.0
!
end

Let’s start by defining the inside and outside interfaces and we’ll add a simple static NAT rule:

R2(config)#interface GigabitEthernet 0/1
R2(config-if)#ip nat inside

R2(config)#interface GigabitEthernet 0/2
R2(config-if)#ip nat outside

R2(config)#ip nat inside source static 192.168.12.1 192.168.23.1

The NAT rule above will translate source IP address 192.168.12.1 (R1) to 192.168.23.1. We’ll see if it works by sending a ping from R1 to R3. Before we do this, we’ll have to add a default route on R1 so that it knows how to reach 192.168.23.3 (R3):

R1(config)#ip route 0.0.0.0 0.0.0.0 192.168.12.2

We want to see the routing and NAT actions of R2 so let’s enable some debugs:

R2#debug ip packet detail 
IP packet debugging is on (detailed)

R2#debug ip nat detailed 
IP NAT detailed debugging is on

If we want to see all debug info, then we should disable route caching on R2 so that packets are handled by the CPU:

R2(config)#interface GigabitEthernet 0/1
R2(config-if)#no ip route-cache 

R2(config)#interface GigabitEthernet 0/2
R2(config-if)#no ip route-cache 

Now let’s send that ping from R1 to R3:

R1#ping 192.168.23.3 repeat 1
Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 192.168.23.3, timeout is 2 seconds:
!
Success rate is 100 percent (1/1), round-trip min/avg/max = 42/42/42 ms

The ping is successful. Let’s take a closer look at R2:

R2#
IP: tableid=0, s=192.168.12.1 (GigabitEthernet0/1), d=192.168.23.3 (GigabitEthernet0/2), routed via FIB
NAT: i: icmp (192.168.12.1, 2) -> (192.168.23.3, 2) [6]     
NAT: s=192.168.12.1->192.168.23.1, d=192.168.23.3 [6]
IP: s=192.168.23.1 (GigabitEthernet0/1), d=192.168.23.3 (GigabitEthernet0/2), g=192.168.23.3, len 100, forward
    ICMP type=8, code=0

What we see above is that the IP packet from 192.168.12.1 to 192.168.23.3 is routed first and then translated by NAT. What about the return traffic?

R2#
NAT*: o: icmp (192.168.23.3, 2) -> (192.168.23.1, 2) [6]
NAT*: s=192.168.23.3, d=192.168.23.1->192.168.12.1 [6]
IP: tableid=0, s=192.168.23.3 (GigabitEthernet0/2), d=192.168.12.1 (GigabitEthernet0/1), routed via FIB
IP: s=192.168.23.3 (GigabitEthernet0/2), d=192.168.12.1 (GigabitEthernet0/1), g=192.168.12.1, len 100, forward
    ICMP type=0, code=0

The return traffic is the opposite. First, it is translated by NAT and then we forward it. So far, so good.

Let’s try something else. We want our network to be as transparent as possible. R1 is currently using a default route to reach 192.168.23.3.

Let’s change this; we’ll add another NAT rule:

R2(config)#ip nat outside source static 192.168.23.3 192.168.12.3

The rule above will translate 192.168.23.3 to 192.168.12.3. R1 should now be able to send a ping to 192.168.12.3 instead of 192.168.23.3. Since 192.168.12.3 is on the local subnet of R1, we won’t need its default route anymore:

R1(config)#no ip route 0.0.0.0 0.0.0.0 192.168.12.2

Let’s send another ping:

R1#ping 192.168.12.3 repeat 1
Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 192.168.12.3, timeout is 2 seconds:
!
Success rate is 100 percent (1/1), round-trip min/avg/max = 48/48/48 ms

Our ping is successful but something funny is going on. Take a look at the debug of R2:

R2#
IP: tableid=0, s=192.168.12.1 (GigabitEthernet0/1), d=192.168.12.3 (GigabitEthernet0/1), routed via RIB
IP: s=192.168.12.1 (GigabitEthernet0/1), d=192.168.12.3 (GigabitEthernet0/1), len 100, rcvd 3
    ICMP type=8, code=0
IP: tableid=0, s=192.168.12.3 (local), d=192.168.12.1 (GigabitEthernet0/1), routed via FIB
IP: s=192.168.12.3 (local), d=192.168.12.1 (GigabitEthernet0/1), len 100, sending
    ICMP type=0, code=0

Above you can see that R2 is receiving the packet from 192.168.12.1 to 192.168.12.3 and replying with an IP packet from 192.168.12.3 to 192.168.12.1. There are no NAT entries at all. What is going on?

Once we configured the second NAT rule, R2 will respond to packets that are destined for 192.168.12.3. Since our traffic is going from the inside to the outside, we do routing first and NAT second.

R2 receives the packet from R1, checks its routing table and routes the packet out of the same interface. No NAT translation will occur since our traffic is not routing out of the outside interface. Here you can see the entry that R2 is “listening” for the 192.168.12.3 address:

R2#show ip cef 192.168.12.3
192.168.12.3/32, version 15, epoch 0, receive

Let’s try something else. We will send a ping from R3 to R1:

R3#ping 192.168.23.1 repeat 1
Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 192.168.23.1, timeout is 2 seconds:
.
Success rate is 0 percent (0/1)

This ping is failing. Why? Let’s check R2:

R2#    
NAT*: o: icmp (192.168.23.3, 4) -> (192.168.23.1, 4) [4]
NAT*: s=192.168.23.3->192.168.12.3, d=192.168.23.1 [4]
IP: tableid=0, s=192.168.12.3 (GigabitEthernet0/2), d=192.168.12.1 (GigabitEthernet0/1), routed via FIB
IP: s=192.168.12.3 (GigabitEthernet0/2), d=192.168.12.1 (GigabitEthernet0/1), g=192.168.12.1, len 100, forward
    ICMP type=8, code=0

Above we see that R2 receives the IP packet from 192.168.23.3 destined to 192.168.23.1. Since this IP packet is received on the outside interface, we do NAT first and routing second. You can see that source address 192.168.23.3 is translated to 192.168.12.3.

R2 will then do a routing table lookup for the destination (192.168.12.1) and forwards it towards R1. When R1 receives this packet, it will reply and here’s what R2 will do with it:

R2#
IP: tableid=0, s=192.168.12.1 (GigabitEthernet0/1), d=192.168.12.3 (GigabitEthernet0/1), routed via RIB
IP: s=192.168.12.1 (GigabitEthernet0/1), d=192.168.12.3 (GigabitEthernet0/1), len 100, rcvd 3
    ICMP type=0, code=0

R2 receives the packet from 192.168.12.1 with destination 192.168.12.3. It does a lookup in the routing table, finds a matching entry for its GigabitEthernet0/1 interface and sends it out of the interface. This packet is never translated and will never make it to R3.

So how do we solve this problem with “legacy” NAT?

We're Sorry, Full Content Access is for Members Only...

If you like to keep on reading, Become a Member Now! Here is why:

  • Learn any CCNA, CCNP and CCIE R&S Topic. Explained As Simple As Possible.
  • Try for Just $1. The Best Dollar You’ve Ever Spent on Your Cisco Career!
  • Full Access to our 799 Lessons. More Lessons Added Every Week!
  • Content created by Rene Molenaar (CCIE #41726)

573 Sign Ups in the last 30 days

satisfaction-guaranteed
100% Satisfaction Guaranteed!
You may cancel your monthly membership at any time.
No Questions Asked!

Tags: , ,


Forum Replies

  1. Hi Rene,

    So far I know we dont use src rewrite for Outside NAT . For outsite NAT ,We use Port forwarding to a particular IP(Dont translate SRC IP Just rewrite DST IP).So how the problem occure .I think no issue on Legacy NAT or do me more explanation in which situation, we will use NAT Virtual Interface.Thanks

    br//
    zaman

  2. Hi Zaman,

    The most common NAT setup is to translate from inside to outside, translating only the source IP address. Port forwarding is also very common.

    It’s unlikely to see this example often in a production network but understanding the “order of operation” might be important for CCIE R&S students.

    The configuration of the NAT virtual interface might be a bit simpler. One problem though is that one some routers, it’s performance is worse than “legacy NAT” so that is something to check.

    Rene

  3. This article is important, for having a good understanding of NAT.

    I do understand that the real issue is : How to reach a WAN address from a LAN domain, by pinging a LAN address (that is supposed to be translated to the target WAN address). I do also understand that the solution is not supposed to use routing rules for jumping from LAN side to WAN side.

    However, some points are confusing for me.

    • Point-1

    The issue is first demonstrated by typing the command below :

    R1#ping 192.168.12.3 repeat 1

    But ; the following explanation lines do no longer use it. Inst

    ... Continue reading in our forum

  4. Hello Maodo

    The command ping 19.168.12.3 repeat 1 is used to test if a NAT translation without a default route will function correctly.

    The command ping 192.168.23.1 repeat 1 is a completely different test. which is testing the NAT translation between 192.168.23.1 and 192.168.12.1. This can be seen from the words: “Let’s try something else…” before the command as seen below:

    https://cdn-forum.networklessons.com/uploads/default/original/1X/6d0c020b8ef1d033c9bbeda758f898967e8ce214.png

    Secondly:

    ... Continue reading in our forum

41 more replies! Ask a question or join the discussion by visiting our Community Forum