ASA Dynamic Outside NAT

This is a bit of a followup post on my previous blog entry from earlier today covering NAT.  One of the only things I did not cover in that post was dynamic outside NAT.  I was labbing up some NAT tonight and couldn’t quite get my head wrapped around this for a while.  I figured it out and am excited to share with you guys what I learned about this topic.

Here is our scenario:

 

Here are the task requirements we need to accomplish:

  • NAT control should be enabled
  • R1 should only have directly connected routes.  Do not add any static or dynamic routes to complete this task
  • Hosts from the outside network should have their IP address mapped to the interface IP of the inside interface when accessing inside hosts
  • Make sure hosts on the inside are still able to access the ACS server in the DMZ

First, some quick verification of the first two points:  Also note that R2 has a default route pointing to the ASA outside interface to start with.  I have also enabled icmp inspection in the global policy to save us same ACL work, and have allowed ICMP in on the outside interface as well so we will be able to initiate a ping from R2 to R1.

sh run nat-control
nat-control
R1(config)#do sh ip route | b Gateway
Gateway of last resort is not set

     1.0.0.0/32 is subnetted, 1 subnets
C       1.1.1.1 is directly connected, Loopback0
     10.0.0.0/24 is subnetted, 1 subnets
C       10.10.10.0 is directly connected, FastEthernet0/0

Good.  We are enforcing nat-control and as far as R1 is concerned he is alone in the world. Let’s get started. The third point is really our dynamic outside NAT.  Dynamic outside NAT is basically just like regular dynamic NAT except the real addresses exist on the lower security interface and are being mapped to addresses on the higher security interface.  This is the exact opposite of how we “normally” do things.  In this case, the outside interface has a security-level of 0, whereas the inside has a security-level of 100 and the dmz has a security-level of 50.  We will use dynamic outside NAT (actually PAT) to map 123.123.123.0/24 to the inside interface of the ASA when hosts on the outside 123.123.123.0/24 subnet access the inside.  From the perspective of the inside, when they communicate with the outside they talk to what they think is something on their local subnet, but in reality they are talking to something on the 123.123.123.0/24.

We configure things basically the same way as dynamic NAT but with an extra “outside” keyword on the nat command

global (inside) 1 interface
nat (outside) 1 0.0.0.0 0.0.0.0 outside

Does it work?

R2#ping 10.10.10.1

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

Of course not, that would have been too easy :P Why? Ask the ASA for some help…

%ASA-6-305011: Built dynamic ICMP translation from outside:123.123.123.2/7 to inside:10.10.10.12/1
%ASA-3-305005: No translation group found for icmp src outside:123.123.123.2 dst inside:10.10.10.1 (type 8, code 0)
%ASA-3-305005: No translation group found for icmp src outside:123.123.123.2 dst inside:10.10.10.1 (type 8, code 0)
%ASA-3-305005: No translation group found for icmp src outside:123.123.123.2 dst inside:10.10.10.1 (type 8, code 0)
%ASA-3-305005: No translation group found for icmp src outside:123.123.123.2 dst inside:10.10.10.1 (type 8, code 0)
%ASA-3-305005: No translation group found for icmp src outside:123.123.123.2 dst inside:10.10.10.1 (type 8, code 0)
%ASA-6-305012: Teardown dynamic ICMP translation from outside:123.123.123.2/7 to inside:10.10.10.12/1 duration 0:00:33

So, it built the translation going from the outside to the inside. The dynamic outside nat part is working fine. It’s the return traffic that is a problem. Why? We have nat-control on and nat-control dictates that packets moving from higher to lower security-level interfaces MUST have a translation. But, we just saw the packet being dynamically translated from low –> high right? That should create a dynamic NAT xlate and allow the return traffic automatically. When the traffic comes back, isn’t it being NAT’d back? All of that is true, but that is all from the perspective of the low –> high flow. The packet comes in sourced from 123.123.123.2 destined for 10.10.10.1. The source IP address is translated to 10.10.10.12 so now we have a source of 10.10.10.12 and a destination of 10.10.10.1. R1 replies sourced from 10.10.10.1 destined to 10.10.10.12 and it hits the inside interface of the ASA. It is at this point we are moving from high to low and need a translation coming back the other way! The SOURCE IP coming back from high to low must be translated…or bypassed. Because we want to talk to the real IP address of R1, we will bypass NAT by using a static identity NAT here

static (inside,outside) 10.10.10.1 10.10.10.1

How about now?

R2#ping 10.10.10.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.10.10.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 128/220/304 ms

Awesome, it works! Now what about the rest of the task? R1 does not have a route at all to 20.20.20.0/24 and we can’t add one. That means when R1 is talking to the ACS server at 20.20.20.100 it has to believe it is talking to something on it’s own local subnet. We will use a static NAT to accomplish this so when R1 sends packets to 10.10.10.100 it is really talking to the ACS server at 20.20.20.100

static (dmz,inside) 10.10.10.100 20.20.20.100

Will that work?

R1(config)#do ping 10.10.10.100

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

Nope. Why? Same reason as before. We have nat-control enabled. Even though we have this static in place, that static is mapping the real address in the dmz to a mapped address on the inside. That means as of right now when R1 accesses that mapped address 10.10.10.100 and tries to pass traffic from a higher to lower level interface it will be denied. Sure, the destination IP is being changed here, but from the perspective of the ASA inside interface no NAT is happening from inside –> outside and it needs to.

If the ACS server has a route to 10.10.10.0/24 we could do another static identity NAT…but it doesn’t. This time we’ll actually setup another dynamic PAT. We will PAT 10.10.10.0/24 to the interface IP of the dmz.

nat (inside) 1 0 0
global (dmz) 1 interface

Now when R1 talks to the ACS server, the ACS server will think it is talking to 20.20.20.12. How about now?

R1(config)#do ping 10.10.10.100

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.10.10.100, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 168/280/444 ms

Beautiful! Hopefully this will help some others out there, because I know dynamic outside NAT was a tough one for me to get my head around initially, and there are not a lot of great resources out there talking about it.

 

 

 

2 Comments

  1. TheGrave TheGrave
    June 17, 2012    

    NAT can really piss you off in the Sec lab :) I can’t imaging what ridiculous customer requirements must have Cisco had to allow so many possible NAT scenarios. I’m trying to get my head around this one (Figure 19-14):

    http://www.cisco.com/en/US/docs/security/asa/asa80/configuration/guide/cfgnat.html#wp1042753

    The command in my opinion should be:

    hostname(config)# static (outside,inside) 209.165.201.10 10.1.2.56 netmask 255.255.255.255
    dns

    Plus, if I remember correctly when you apply the dns keyword you need a second statement to perform the actual IP header translation, e.g. end result should be:

    hostname(config)# static (outside,inside) 209.165.201.10 10.1.2.56 netmask 255.255.255.255
    dns
    hostname(config)# static (outside,inside) 209.165.201.10 10.1.2.56 netmask 255.255.255.255

    The one that really pisses me off is Figure 19-20 though. The documentation seems to be written by a chimp. It took me quite some time just to understand in which direction we are translating the source and in which the destination, what destination IPs does the DMZ host try to hit, etc. Arrows in the Translation and Undo Translation boxes seem to be in the wrong direction as well, somebody in Cisco must be shot! The NAT section of the config guide is the most messed up one.

  2. November 25, 2014    

    Touche. Great arguments. Keep up the amazing work.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>