The “Inside & Outside” Of NAT For Overlapping Networks

Introduction

 

 

I have been doing a lot of mentoring lately, and have started thinking about different ways to explain certain concepts to people.  One of the things that tends to come up is the terminology used in NAT.  We have “inside local” “inside global” “outside local” and “outside global”.  These tend to really confuse people.  I know it confused me a LOT when I was first learning, and if I don’t stay on it all the time or use it, I *still* have to review these concepts from time to time.

While searching around the internet, I came across this fantastic post on the Cisco learning network about this very concept.  Keith Barker, a fellow CCIE and well known security guru in the industry posted an example that really solidified the terminology in a way I had not thought of before. If you are reading, thanks Keith, great post!  Anyways, the post really drives home the terminology by using an example of NAT to solve overlapping IP address space issues. NAT to overcome overlapping networks is something I have read about and labbed up a few times during my studies, but one of those things I never really dove into, so I decided to do that.  The point of Keith’s post was to demonstrate the terminology of NAT, so certain configuration aspects in the example that make things work under the hood were not specifically pointed out.  I kept going over these issues in my head, and decided to lab it up myself to see what I could learn.  I ran across a few interesting “gotchas” and thought I would share the knowledge gained.

 

The Topology

 

I went ahead and basically reconstructed the topology that Keith laid out in the post I mentioned above.  Mine is slightly modified, but it is the same idea.  Here it is.  Notice that both R1 and R4 have loopback0 interfaces in the same network, 100.0.0.0/24

 

 

The Configuration

 

Let’s talk through what we are going to do here.  We want R1 to be able to hit R4’s loopback and visa versa, but we need to trick both routers in a way.  If R1 just tries to ping 100.0.0.4 nothing is going to go down because R1 has a directly connected route for 100.0.0.0/24.  If R4 tries to ping 100.0.0.1 it will have the same issue. We will use NAT in both directions to solve this problem. In other words, R1 has to believe it is talking to some other IP address other than 100.0.0.4 and R4 has to believe it is talking to something other than 100.0.0.1.  Before we do that, let’s setup some basic default routing on R1 and R4

R1(config)#ip route 0.0.0.0 0.0.0.0 12.12.12.2
R4(config)#ip route 0.0.0.0 0.0.0.0 24.24.24.2

OK, let’s setup our NAT on R2

interface FastEthernet0/0.12
 ip nat inside
!
interface FastEthernet0/0.24
 ip nat outside
!
!
ip nat inside source static 100.0.0.1 11.11.11.11
ip nat outside source static 100.0.0.4 44.44.44.44

Let’s break down what the packet flow is going to look like here.  When R1 sources a ping packet from 100.0.0.1 destined to 44.44.44.44 two things will happen.  Our inside NAT rule there will translate the source of the packet to 11.11.11.11.  At the same time, the outside NAT rule will translate the destination of the packet to 100.0.0.4

If everything gets routed OK, R4 will receive an ICMP echo packet sourced from 11.11.11.11 and destined to 100.0.0.4 and it will send an ICMP echo reply sourced from 100.0.0.4 and destined to 11.11.11.11.  When R2 receives the packet, it will then translate the source of the packet to 44.44.44.44 and translate the destination of the packet to 100.0.0.1 at the same time

Does that blow your mind? : )  The thing to keep in mind is that both the inside and outside NAT rules work bidirectionally.  In other words, when I say ip nat inside source static 100.0.0.1 11.11.11.11 I am actually telling the router to do two things.  If the packet is sourced from 100.0.0.1 on the inside interface, translate the source to 11.11.11.11.  Also, if the packet is destined to 11.11.11.11 on the outside interface, translate the destination to 100.0.0.1.  The outside NAT rule is similar in accomplishing two things.  When I say ip nat outside source static 100.0.0.4 44.44.44.44  I am telling the router to do two things.  If the packet is sourced from 100.0.0.4 and coming in the outside interface, translate the source to 44.44.44.44.  When packets come in the inside interface destined to 44.44.44.44, translate the destination to 100.0.0.4.  Get it? Got it? Good!

 

Troubleshooting

 

Let’s test this out and see what happens.  We will ping 44.44.44.44 from R1 sourced from 100.0.0.1.  This should trigger our NAT.

R1#ping 44.44.44.44 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 44.44.44.44, timeout is 2 seconds:
Packet sent with a source address of 100.0.0.1
.....
Success rate is 0 percent (0/5)

Nothing…looking at a debug on R2 gives us the reason why

R2#debug ip icmp
ICMP packet debugging is on

*Aug 16 13:46:07.731: ICMP: dst (44.44.44.44) host unreachable sent to 12.12.12.1
*Aug 16 13:46:09.731: ICMP: dst (44.44.44.44) host unreachable sent to 12.12.12.1
*Aug 16 13:46:11.731: ICMP: dst (44.44.44.44) host unreachable sent to 12.12.12.1
*Aug 16 13:46:25.175: ICMP: dst (44.44.44.44) host unreachable sent to 12.12.12.1
*Aug 16 13:46:27.179: ICMP: dst (44.44.44.44) host unreachable sent to 12.12.12.1

So what is happening? Simple, R2 gets a packet destined for 44.44.44.44 and it doesn’t have a route to it.  Therefore, it returns an ICMP destination unreachable to the source, 100.0.0.1.  Look closely at R1 though.  If it was receiving ICMP unreachables from R2, we would have seen “U” codes in our ping instead of “.” but we didn’t.  Why?  R2 doesn’t have a route back to 100.0.0.1 either!  Two problems there!

This also reminds us of a VERY interesting fact about the NAT order of operations.  When going from inside –> outside, routing is always done FIRST, followed by NAT.  When going from outside –> inside the NAT is done first and then the packet is routed.

When doing outside NAT, you can tack on the “add-route” parameter.  What this does, is it adds a static host route for the outside local address.  In other words, in our scenario, it would add a static route for 44.44.44.44/32 on R2.  Let’s see how that works, and fix our routing issue for 100.0.0.1 at the same time.

R2(config)#ip route 100.0.0.1 255.255.255.255 12.12.12.1
R2(config)#ip nat outside source static 100.0.0.4 44.44.44.44 add-route

R2(config)#do sh ip route static
     100.0.0.0/32 is subnetted, 1 subnets
S       100.0.0.1 [1/0] via 12.12.12.1

Well well well…that didn’t seem to work at all?! Where is my static route to 44.44.44.44/32 as promised by the add-route parameter? Here is the thing — When you use the add-route parameter it will indeed try to add a route to the outside local address, but guess what? The next hop will be the outside global address. In other words, R2 just tried to add a static route to 44.44.44.44/32 with a next hop of 100.0.0.4 but guess what? R2 doesn’t have a route to 100.0.0.4 either! Therefore, inserting the static route fails. Bummer. What can we do? We can add a route to 100.0.0.4 ourselves, or we can just scratch the whole “add-route” thing and add a route to 44.44.44.44 with a next hop of 24.24.24.4 ourselves. We will go with option #1

R2(config)#ip route 100.0.0.4 255.255.255.255 24.24.24.4
R2(config)#do sh ip route static
     100.0.0.0/32 is subnetted, 2 subnets
S       100.0.0.4 [1/0] via 24.24.24.4
S       100.0.0.1 [1/0] via 12.12.12.1
     44.0.0.0/32 is subnetted, 1 subnets
S 44.44.44.44 [1/0] via 100.0.0.4

After a few moments, our magic static route from “add-route” showed up. Why? Because now it has a recursive route to the next-hop of 100.0.0.4 which was not there before. Awesome.  Why don’t I need a route for 11.11.11.11? NAT order of operations.  When the packets come in to R2 on Fa0/0.24 the NAT will happen first, thereby changing the destination address to 100.0.0.1.  Only then will routing happen.  Let’s test again

R1#ping 44.44.44.44 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 44.44.44.44, timeout is 2 seconds:
Packet sent with a source address of 100.0.0.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/4/8 ms

Victory is mine!!! (Stewie Griffin voice). Let’s break it down one more time. R1 sends a packet source from 100.0.0.1 to what it believes is 44.44.44.44. R1 default routes the packet to R2. We are going from inside to outside, so routing happens first. R2 does a route lookup for 44.44.44.44 and finds a static route with next hop 100.0.0.4. R2 then does a recursive route lookup on 100.0.0.4 and finds a route to 24.24.24.4 and routes the packet out fa0/0.24. Because the source of the packet is 100.0.0.1, R2 translates the source IP address to 11.11.11.11. Because the destination of the packet is 44.44.44.44, R2 translates the destination of the packet to 100.0.0.4.

R4 receives an ICMP echo request from 11.11.11.11 destined to 100.0.0.4 and replies with an ICMP echo-reply. The reply is sourced from 100.0.0.4 and destined to 11.11.11.11. R4 does a route lookup for 11.11.11.11 and default routes the packet to R2. Because the packet is sourced from 100.0.0.4, R2 translates the source of the packet to 44.44.44.44. Because the destination of the packet is 11.11.11.11, R2 translates the destination to 100.0.0.1. Now, routing happens and R2 does a route lookup for 100.0.0.1. It finds a static route with next hop 12.12.12.1 and sends the packet along to R1. Done!

 

The Terminology

 

OK, so what does this have to do with “inside local” “inside global” “outside local” and “outside global” ?  This particular example makes it very clear, at least to me. Let’s look at the NAT translation table after R1 sent the ping

R2#sh ip nat trans
Pro Inside global      Inside local       Outside local      Outside global
--- ---                ---                44.44.44.44        100.0.0.4
icmp 11.11.11.11:22    100.0.0.1:22       44.44.44.44:22     100.0.0.4:22
--- 11.11.11.11        100.0.0.1          ---                ---

We basically have inside and outside and we have local and global.  When we say inside we are referencing an IP address of a device on the inside NAT interface.  When we say outside we are referencing an IP address of a device on the outside NAT interface.  When we say local, we mean the IP address as viewed locally or before anything changed.  When we say global we mean the IP address as viewed by the rest of the world.  So…

Inside Local — The IP address of the inside machine as viewed locally on the inside network

Inside Global – The IP address of the inside machine as viewed by the world on the outside network

Outside Local – The IP address of the outside machine as viewed locally on the inside network

Outside Global – the IP address of the outside machine as viewed globally on the outside network

 

24 Comments

Leave a Reply