The Woes of Using an ASA as a Default Gateway

Some people often think of an ASA Security Appliance as a router.  The ASA is a firewall.  As a firewall, the ASA does not always forward traffic or behave as we would expect (if we expect it to behave like a router).  This can have ramifications if we place it in a network and expect it to route traffic to arbitrary interfaces based on the routing table.  Actually the route table has lower priority in the routing process than that translation table (XLATEs).

ASA Egress Interface Selection

To get perspective on where this is relevant, let’s take a look at a real world example.  This network below has a temporary need to route traffic to a third party network.  A more robust routing solution could be placed where the ASA firewall is positioned.  In my opinion, the ASA is superior solution to Internet firewalling as compared to a router doing CBAC.  So I wouldn’t want to use a router instead of an ASA here.  If there were no financial restrictions, we could simply place a router behind the ASA.  The final option is to try to get the router to behave as a router.  That’s the solution that we’ll talk about in this article.

Requirements:

  • Hosts Must Use 10.1.1.100 as their Gateway
  • ASA Must Direct Traffic Destined to 100.1.1.0/24 to 10.1.1.200
  • ASA Must Perform PAT (NAT Overload) for traffic going to the Internet
  • No STATICs or ACL for inbound traffic

 

At first glance, this seems really simple. We’ve all done this with routers, so we just need the ASA equivalent of–”ip route 100.1.1.0 255.255.255.0 10.1.1.200″. Right? That should be easy. Let’s just go ahead and configure up our ASA for PAT and then add the static route.

interface ethernet0/1
nameif inside
security-level 100
ip address 10.1.1.100 255.255.255.0
!
interface ethernet0/0
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
!

route outside 0.0.0.0 0.0.0.0 66.49.27.153
route inside 100.1.1.0 255.255.255.0 10.1.1.200

Well that was easy, but does it work?  When you try to ping something on 100.1.1.0/24 from a host that is using the ASA as a default gateway, you will find that it fails.  You’ve seen that before, right?  Remember, we always have to turn on icmp inspection on ASA’s.  The shortcut for that is:

fixup protocol icmp

Great, but it still doesn’t work.  Then it hits you.  The ASA is a product that came from the PIX firewall.  The PIX, if you recall, will never forward a packet out the same interface it was received on.  But the ASA was supposed to allow this with a strange command.

same-security-traffic permit intra-interface

That’s still not too bad, if that was all you actually had to do.  Unfortunately it still doesn’t seem to work.  Maybe we better take a look at how the ASA is processing our ICMP echo.  We can issue a command like “packet-tracer input inside 10.1.1.50 0 0 100.1.1.20″.  That will show us all of the steps that the ASA goes through when processing the packet.  What you will find is that the ASA is actually trying to do NAT and there is a missing global statement for the inside interface.  But we don’t really want to do NAT for traffic to or from our third party network.  So we need to write a NAT exemption rule and test our connectivity once again.

access-list NONAT extended permit ip any 100.1.1.0 255.255.255.0
//return traffic shouldn’t hit the ASA, but in any case we never
//want to create an XLATE for the traffic in either direction
access-list NONAT extended permit ip 100.1.1.0 255.255.255.0 any

nat (inside) 0 access-list NONAT

Now let’s ping something in 100.1.1.0/24 from one of our hosts again.  Success!  It should be working at this point, but we’re not done yet.  Try using the TCP protocol to reach something at 100.1.1.0/24.  If you look at this in Wireshark, you’ll probably see something like SYN, SYN-ACK, ACK, RST or SYN, SYN-ACK, ACK, ACT (Retrans), ACK (Retrans).  What is going on?  The ASA is actually trying to create a session for the TCP connection.  It is actually inspecting the TCP traffic.  Since the router delivers the second part of the three-way handshake directly to the host, the ASA never sees the “SYN-ACK”.  Therefore, the ASA doesn’t believe the three-way handshake has occurred and does not allow the third packet.  Well that just sucks.  The ASA is trying to sessionize traffic that doesn’t even go through the appliance.  What to do?

ASA OS 8.2 introduced a feature called TCP State Bypass.  That allows the ASA to pass traffic without validating the TCP state.  The configuration of that uses the modular policy framework (MPF).

access-list STATEBYPASS extended permit ip any 100.1.1.0 255.255.255.0

//the ASA will probably never see traffic sourced from 100.1.1.0/24, but just in case
access-list STATEBYPASS extended permit ip 100.1.1.0 255.255.255.0 any

!

class-map STATEBYPASS
match access-list STATEBYPASS
policy-map STATEBYPASS
class STATEBYPASS
set connection advanced-options tcp-state-bypass
!
service-policy STATEBYPASS interface inside

Now a test using TCP from one of the hosts to something on 100.1.1.0/24 should succeed.  What else should we do?  Anytime I am doing  anything strange with NAT on the ASA, I disable proxy-arp.  This case shouldn’t require it, but I have had cases where the ASA responds to ARPs that it shouldn’t and it’s really hard to track down.  So for good measure, I would add the following command.

sysopt noproxyarp inside

The final configuration looks something like the following:

interface ethernet0/1
nameif inside
security-level 100
ip address 10.1.1.100 255.255.255.0
!
interface ethernet0/0
nameif outside
security-level 0
ip address 1.1.1.1 255.255.255.0

!

nat (inside) 0 access-list NONAT

nat (inside) 1 0.0.0.0 0.0.0.0
!

global (outside) 1 interface

!

route outside 0.0.0.0 0.0.0.0 66.49.27.153
route inside 100.1.1.0 255.255.255.0 10.1.1.200

!

access-list NONAT extended permit ip any 100.1.1.0 255.255.255.0
access-list NONAT extended permit ip 100.1.1.0 255.255.255.0 any

!

access-list STATEBYPASS extended permit ip any 100.1.1.0 255.255.255.0

access-list STATEBYPASS extended permit ip 100.1.1.0 255.255.255.0 any

!

same-security-interface permit intra-interface

!

class-map STATEBYPASS
match access-list STATEBYPASS
policy-map STATEBYPASS
class STATEBYPASS
set connection advanced-options tcp-state-bypass
!
service-policy STATEBYPASS interface inside

!

sysopt noproxyarp inside

In conclusion, the ASA is not a router.  However going through the exercise of making it behave like one can help you understand some of the logic and processing order of the firewall appliance.

About Paul Stewart, CCIE 26009 (Security)

Network and Security Consultant, Trainer and Blogger who enjoys understanding how things really work. Troubleshooting and problem resolution is fun, especially if it involves packet. What's on your wire[s]?
This entry was posted in Uncategorized and tagged . Bookmark the permalink.

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=""> <strike> <strong>