Monday, October 1, 2012

ASA 8.2 and Hairpin NAT

Don't ask me why people still do this, but there is occasionally the need to set up hairpin NAT on a firewall. This functionality is where a LAN user accesses another server on the LAN by its static public IP. For example, if i am 10.0.0.6 and i try to access 1.1.1.5, the firewall will turn the traffic around (and rewrite the IP) and send it down to whatever 1.1.1.5 is mapped to in the LAN. This functionality is different depending on the version of ASA software you're running, this is specifically for 8.2. This gets a little messier when you have a mixture of people with 1:1 NAT and PAT set up, but it works either way. Base config that will not work for hairpinning:
interface Vlan1
 nameif inside
 security-level 100
 ip address 10.0.0.1 255.255.255.0

interface Vlan2
 nameif outside
 security-level 0
 ip address 1.1.1.1 255.255.255.0

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

static (inside,outside) 1.1.1.5 10.0.0.5 netmask 255.255.255.255
static (inside,outside) 1.1.1.6 10.0.0.6 netmask 255.255.255.255
The issue with this is that if any user on the LAN tries to access 1.1.1.6, the ASA doesn't really know what to do with it, and drops it. So there are a few things that need to be fixed at this point:

Allow the ASA to turn the traffic around:

same-security-traffic permit intra-interface

Allow PAT'd users to have their IP rewritten when being hairpinned:

global (inside) 1 interface

Allow static NAT users to have their IP rewritten as well:

static (inside,inside) 1.1.1.5 10.0.0.5 netmask 255.255.255.255
static (inside,inside) 1.1.1.6 10.0.0.6 netmask 255.255.255.255


At this point it should be working normally, so here is the completed config:
interface Vlan1
 nameif inside
 security-level 100
 ip address 10.0.0.1 255.255.255.0

interface Vlan2
 nameif outside
 security-level 0
 ip address 1.1.1.1 255.255.255.0

same-security-traffic permit intra-interface
global (outside) 1 interface
global (inside) 1 interface
nat (inside) 1 0.0.0.0 0.0.0.0

static (inside,outside) 1.1.1.5 10.0.0.5 netmask 255.255.255.255
static (inside,outside) 1.1.1.6 10.0.0.6 netmask 255.255.255.255
static (inside,inside) 1.1.1.5 10.0.0.5 netmask 255.255.255.255
static (inside,inside) 1.1.1.6 10.0.0.6 netmask 255.255.255.255


Once this is done, you should be able to access the public IPs internally and get the traffic routed appropriately. If you are still having problems, i highly recommend the packet-trace command which can help you find out where the problem is occurring.

5 comments:

  1. Thanks for the explanation. What would be the configuration if I would like only a handful of users (and not everyone) point to the Static public IP of the server from the inside? The other users continue to point to the internal IP of the server. Plus there are other servers in the DMZ that would be accessed the same way down the road, but not now.

    ReplyDelete
    Replies
    1. I would just stick with the global (inside) part of the config, that way if a user does attempt to access the LAN server using the public IP it will work. If they use the private IP it won't ever hit the ASA so it's not much of a concern. If you specifically wanted to disable certain users from using this functionality then it would probably be easiest to just do an ACL to filter it, otherwise you're looking at 1:1 NAT or NAT pools for the users which can get messy.

      Delete
  2. worked with this config last night and ran into an error trying to load the static inside,outside command. The ASA came back saying it could not load to an ip address it needed an interface. Any thoughts?

    ReplyDelete
  3. Great article! Here in 2017 I sometimes run into 8.2 and still have to do things like this...

    ReplyDelete