NAT Extendable on Cisco IOS

The NAT extendable parameter can be used if you want to translate a private IP address to more than one public IP address. Let’s look at an configuration example.

Configuration

I will use the following topology:

s1 r1 isp1 isp2 nat topology

Above we have on the left side our S1 router, let’s imagine that this is some web server that has to be accessible on the Internet. Our R1 router that is connected to two ISP routers will be configured for NAT.

For this example, let’s imagine that 192.168.12.100 is a public IP address that was assigned by ISP1, 192.168.13.100 is a public IP address that is assigned by ISP2.

The NAT extendable parameter can be used if you want to translate a private IP address to more than one public IP address. Let's look at an configuration example. Configuration I will use the following topology: Above we have on the left side our S1 router, let's imagine that this is some web server

On S1, I will disable routing and configure a default gateway that points to R1:

S1(config)#no ip routing
S1(config)#ip default-gateway 192.168.1.254

Let’s add the NAT inside and outside commands on R1:

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

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

R1(config)#interface GigabitEthernet 0/3
R1(config-if)#ip nat outside

Let’s say that I want to make S1 reachable from 192.168.12.100, an imaginative public IP address from ISP1. I could use the following command:

R1(config)#ip nat inside source static 192.168.1.1 192.168.12.100

This creates a 1:1 NAT translation between 192.168.1.1 and 192.168.12.100. So far so good, now let’s say I want to do the same thing for imaginative public IP address 192.168.13.100 so that the server is also reachable through ISP2:

R1(config)#ip nat inside source static 192.168.1.1 192.168.13.100
% 192.168.1.1 already mapped (192.168.1.1 -> 192.168.12.100)

Our router complains since we already mapped 192.168.1.1 to 192.168.12.100. This makes sense but there is a way around this. Let’s get rid of the current NAT rule:

R1(config)#no ip nat inside source static 192.168.1.1 192.168.12.100

Now we will recreate our NAT rules, but we’ll add the extendable parameter:

R1(config)#ip nat inside source static 192.168.1.1 192.168.12.100 extendable 
R1(config)#ip nat inside source static 192.168.1.1 192.168.13.100 extendable

Cisco IOS no longer complains and accepts our commands.

Verification

Let’s see if our NAT configuration works. Here’s the NAT translation table:

R1#show ip nat translations 
Pro Inside global      Inside local       Outside local      Outside global
--- 192.168.12.100     192.168.1.1        ---                ---
--- 192.168.13.100     192.168.1.1        ---                ---

We can see above that 192.168.1.1 is mapped to both 192.168.12.100 and 192.168.13.100. Let’s see if ISP1 and ISP2 are able to reach 192.168.12.100 and 192.168.13.100. To see the NAT translation in action, let’s enable a debug:

R1#debug ip nat
IP NAT debugging is on

Let’s try a ping:

ISP1#ping 192.168.12.100
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.12.100, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 2/3/4 ms

Our ping is working and we can see the NAT translation on R1:

R1#
NAT*: s=192.168.12.2, d=192.168.12.100->192.168.1.1 [33]
NAT*: s=192.168.1.1->192.168.12.100, d=192.168.12.2 [33]

192.168.1.1 is translated to 192.168.12.100. Let’s try a ping from ISP2:

ISP2#ping 192.168.13.100
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.13.100, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 2/2/3 ms

You will see the following translation:

R1#
NAT*: s=192.168.13.3, d=192.168.13.100->192.168.1.1 [20]
NAT*: s=192.168.1.1->192.168.13.100, d=192.168.13.3 [20]

This is looking good, 192.168.1.1 is now reachable from both 192.168.12.100 and 192.168.13.100.

What about traffic that originates from S1? We have two NAT rules so which one will our router use? Let’s find out:

S1#ping 192.168.12.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.12.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 2/4/6 ms

A ping to 192.168.12.2 (ISP1) is working. Let’s check the NAT translation table:

R1#show ip nat translations 
Pro Inside global      Inside local       Outside local      Outside global
icmp 192.168.12.100:5  192.168.1.1:5      192.168.12.2:5     192.168.12.2:5
--- 192.168.12.100     192.168.1.1        ---                ---
--- 192.168.13.100     192.168.1.1        ---                ---

We can see that 192.168.1.1 got translated to 192.168.12.100. What about a ping to 192.168.13.3?

S1#ping 192.168.13.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.13.3, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)

This one fails…why? Let’s check the table again:

R1#show ip nat translations 
Pro Inside global      Inside local       Outside local      Outside global
icmp 192.168.12.100:5  192.168.1.1:5      192.168.12.2:5     192.168.12.2:5
icmp 192.168.12.100:6  192.168.1.1:6      192.168.13.3:6     192.168.13.3:6
--- 192.168.12.100     192.168.1.1        ---                ---
--- 192.168.13.100     192.168.1.1        ---                ---

Above you can see that this traffic also got translated to 192.168.12.100. Is this because we sent a ping to ISP1 first? Let’s clear the NAT table:

R1#clear ip nat translation *

And try another ping to 192.168.13.3:

S1#ping 192.168.13.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.13.3, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)

The ping is still failing, let’s check the NAT table again:

R1#show ip nat translations  
Pro Inside global      Inside local       Outside local      Outside global
icmp 192.168.12.100:7  192.168.1.1:7      192.168.13.3:7     192.168.13.3:7
--- 192.168.12.100     192.168.1.1        ---                ---
--- 192.168.13.100     192.168.1.1        ---                ---

Above we can see that it still gets translated to 192.168.12.100. Why? This has to do with the order of NAT commands. Take a look at our running configuration:

R1#show running-config | include nat inside source
ip nat inside source static 192.168.1.1 192.168.12.100 extendable
ip nat inside source static 192.168.1.1 192.168.13.100 extendable

Above you can see that the rule to translate to 192.168.12.100 is found first, this is the rule that the router will use when it has to translate traffic from 192.168.1.1. This is something to keep in mind when you use the extendable command.

Configurations

Want to take a look for yourself? Here you will find the final configuration of each device.

ISP1

hostname ISP1
!
ip cef
!
interface GigabitEthernet0/1
 ip address 192.168.12.2 255.255.255.0
!
end

ISP2

hostname ISP2
!
ip cef
!
interface GigabitEthernet0/1
 ip address 192.168.13.3 255.255.255.0
!
end

R1

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.12.1 255.255.255.0
 ip nat outside
 ip virtual-reassembly in
!
interface GigabitEthernet0/3
 ip address 192.168.13.1 255.255.255.0
 ip nat outside
 ip virtual-reassembly in
!
ip nat inside source static 192.168.1.1 192.168.12.100 extendable
ip nat inside source static 192.168.1.1 192.168.13.100 extendable
!
end

S1

hostname S1
!
no ip routing
!
no ip cef
!
interface GigabitEthernet0/1
 ip address 192.168.1.1 255.255.255.0
!
ip default-gateway 192.168.1.254
!
end

Conclusion

You have now learned how you can use the NAT extendable parameter to translate a private IP address to two or more public IP addresses. Keep in mind that the first rule in your configuration will be used for traffic that originates from the inside.

Tags: ,


Ask a question or start a discussion by visiting our Community Forum