Egress Interface Selection on the Cisco ASA

One of the frustrating things about the Cisco ASA is that it does not support policy based routing, or pbr.  With pbr, an administrator can get very granular with routing IP traffic.  For example, an access-list can match traffic and steer it to an alternative next hop based on things like TCP/UDP port or IP source address.  The ASA does not have the same level of granularity.  However, a solid understanding of the interface selection process will allow an administrator to get creative and achieve some of the same results.

Prior to discussing the interface selection process, it is important to understand one of the other nuances of the ASA.  That nuance is the arp behavior.  The reason this is so important is that some of the configuration options discussed will cause the ASA to respond to any arp request on the inside interface.  This can cause unpredictable behavior for communications between hosts connected to the inside interface.  This is discussed more thoroughly in the article below.

The ASA’s ARP Behavior
http://packetu.com/2011/11/07/the-asas-arp-behavior/

Cisco has published the egress interface selection process for the ASA at the following URL
Cisco ASA 5500 Series Configuration Guide

An excerpt from this article states:

1.    If destination IP translating XLATE already exists, the egress interface for the packet is determined from the XLATE table, but not from the routing table.

2.    If destination IP translating XLATE does not exist, but a matching static translation exists, then the egress interface is determined from the static route and an XLATE is created, and the routing table is not used.

3.    If destination IP translating XLATE does not exist and no matching static translation exists, the packet is not destination IP translated. The ASA processes this packet by looking up the route to select egress interface, then source IP translation is performed (if necessary).

For regular dynamic outbound NAT, initial outgoing packets are routed using the route table and then creating the XLATE. Incoming return packets are forwarded using existing XLATE only. For static NAT, destination translated incoming packets are always forwarded using existing XLATE or static translation rules.
Next Hop Selection Process

Understanding and Testing this Process
In order to test the selection process, a small lab can be constructed.  This needs to include an inside host and two external routers to be configured as next hop addresses.

As a starting point, the ASA should be configured with addressing that matches the drawing.

//base ASA configuration

ASA# show run interface
!
interface Vlan1
nameif inside
security-level 100
ip address 10.1.1.1 255.255.255.0
!
interface Vlan2
nameif isp1
security-level 0
ip address 1.1.1.2 255.255.255.0
!
interface Vlan3
nameif isp2
security-level 0
ip address 2.2.2.2 255.255.255.0
!
interface Ethernet0/0
description Connected to ISP1
switchport access vlan 2
!
interface Ethernet0/1
description Connected to Inside
!
interface Ethernet0/2
description Connected to ISP2
switchport access vlan 3

At this point, it is a good idea to test the local connectivity.

ASA(config)# ping 10.1.1.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.1.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms
ASA(config)# ping 1.1.1.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/10 ms
ASA(config)# ping 2.2.2.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2.2.2.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/10 ms

In order to route packets to both ISPs, there will need to be a route out each interface.  This should probably look something like the following.

//route to isp1
route isp1 0.0.0.0 0.0.0.0 1.1.1.1

//route to isp2
route isp2 0.0.0.0 0.0.0.0 2.2.2.1

However when this configuration is attempted, the ASA will throw an error because the routes overlap.

ASA(config)#
ASA(config)# route isp1 0.0.0.0 0.0.0.0 1.1.1.1

ASA(config)#
ASA(config)# route isp2 0.0.0.0 0.0.0.0 2.2.2.1
ERROR: Cannot add route entry, conflict with existing routes

ASA(config)# show run route
route isp1 0.0.0.0 0.0.0.0 1.1.1.1 1

Only one route was accepted and it has an administrative distance of “1”.  A second route to the same destination can be added by using a higher administrative distance.

ASA(config)#
ASA(config)# route isp2 0.0.0.0 0.0.0.0 2.2.2.1
ASA(config)# show run route
route isp1 0.0.0.0 0.0.0.0 1.1.1.1 1
route isp2 0.0.0.0 0.0.0.0 2.2.2.1 2

At this point, packets originating from or going through the ASA going with “unknown” destinations will have a next hop of 1.1.1.1.  This is because of the lower administrative distance of that default route and the absence of a destination nat configuration.  If the administrative distance of the first route is set to “3”, the route to 2.2.2.1 will be preferred.

If some traffic should be routed to one interface and other traffic should be routed to another interface, the second step in the egress interface selection process (step 2 from Cisco’s excerpt above) should be looked at.  With the default route to 1.1.1.1 set with an administrative distance of 1, traffic can still be steered traffic to 2.2.2.1.  This is done by creating a destination translation.  Actually the destination translation that is used below is an exemption, but it works the same for egress interface selection.  Basically it translates w.x.y.z to w.x.y.z.  Prior to attempting this, it is recommended that proxy arp be disabled on the inside interface.

//disable proxy arp on inside
ASA(config)#sysopt noproxyarp inside

//create a destination translation to match everything
ASA(config)#static (isp2,inside) 0.0.0.0 0.0.0.0 netmask 0.0.0.0

At this point, all traffic going through the ASA would be routed to the isp2 interface.  Alternatively, half of the traffic could be routed to isp2.

//delete the existing translation
ASA(config)#no static (isp2,inside) 0.0.0.0 0.0.0.0 netmask 0.0.0.0

//create a destination translation for 128-255
ASA(config)#static (isp2,inside) 128.0.0.0 128.0.0.0 netmask 128.0.0.0

At this point, packets destined to 0-127.x.x.x will go to isp1.  Packets with a destination of 128-255.x.x.x will go to ISP2.  That still is not too interesting.  This could actually be accomplished with two routes in the route table.

One of the more interesting things that some desire to achieve with policy based routing in IOS is routing by traffic type.  For example, traffic to port 80 and 443 might go to isp2.  All other traffic could go to isp1.  This can be accomplished in the ASA by using a configuration similar to the following.

//delete the previous destination translation
ASA(config)#no static (isp2,inside) 128.0.0.0 128.0.0.0 netmask 128.0.0.0

//create destination translations that include tcp/udp ports
static (isp2,inside) tcp 0.0.0.0 80 0.0.0.0 80 netmask 0.0.0.0
static (isp2,inside) tcp 0.0.0.0 443 0.0.0.0 443 netmask 0.0.0.0

Unlike IOS based routers, the ASA does not support policy based routing.  While this certainly creates limitations, there are options that will allow an administrator to achieve some of the same goals.  Prior to implementing destination translation or destination translation exemptions, it is very important to understand the proxy arp behavior on the ASA.  When a destination translation or exemption exists, outbound packets use the entry to determine the egress interface.  Once the egress interface is chosen, the ASA does a route lookup specific to the chosen interface.  By understanding these interactions, an administrator can use destination translation exemptions to steer packets to the desired interface.  This can alleviate some of the limitations found in the ASA.

About Paul Stewart, CCIE 26009 (Security)

Paul is a Network and Security Engineer, Trainer and Blogger who enjoys understanding how things really work. With over 15 years of experience in the technology industry, Paul has helped many organizations build, maintain and secure their networks and systems.
This entry was posted in CCIE Security, Certification, Security, Technology and tagged , , . Bookmark the permalink.

17 Responses to Egress Interface Selection on the Cisco ASA

  1. Darren says:

    Hi Paul

    Really useful post, been struggling with how to do this with an ASA for a while.

    I do have a question though, how can I exclude traffic to certain destinations from matching the static NATs? I want to send all http(s) traffic down ISP2 except traffic to certain ranges which must go through ISP1 because it has the better upload speed.

    Thanks

  2. Fabian says:

    Hi Paul,

    Great post!

    We’re trying to mix “destination translations that include tcp/udp ports” with failover between 2 isp’s.

    Is there a way to include tracking in static translation rules ?

    When isp2 goes down, 80 and 443 traffic is still being translated to isp2.

    Thanks,

    Fabian

    • I don’t think that can be done any way in the ASA. you can only add tracking to routes. The challenge is that static xlate entries unconditionally steer traffic to an interface based on the criteria in the static. If that interface does not have a functional route, the packet isn’t going to make it.

  3. Greg says:

    Hi Paul,
    This is a great explanation, thanks! Since you’re using the ‘static’ command, I assume you’re running 8.2 or lower on your ASA.
    Is this type of interface selection possible under 8.3 or higher? How would you accomplish this?
    Greg

  4. Rohan says:

    So How would it work from traffic inititating from the outside?
    For e.g.

    ASA(config)# static (isp1,inside) 0.0.0.0 128.0.0.0 netmask 0.0.0.0

    ASA(config)#static (isp2,inside) 128.0.0.0 128.0.0.0 netmask 128.0.0.0

    Now if traffic is initiated by some host on the internet say 8.8.8.8 and is routedto isp2 and isp2 sends it to FW. Now return traffic must go bak through isp2 but it would asa allow it? since according to static it should go through isp1? Or is this where the 1st point

    If destination IP translating XLATE already exists, the egress interface for the packet is determined from the XLATE table, but not from the routing table. comes into play?

    Also what does cisco exactly mean when they refer to If destination IP translating XLATE?

    Thanks!

  5. papacheops says:

    Have you done any work or testing of this with 8.4(x) ? I have been struggling to get this to work on my 8.3 and 8.4 ASAs…

    • Paul Stewart says:

      I have not done any significant testing in regards to this on the ASA code with the new NAT syntax. Although it has piqued my curiosity, I have just failed to find the time.

      • papacheops says:

        For the life of me, I can’t get it to “activate” the NAT processing and select the second interface for egress. Packet tracer just shows it flowing out the first egress interface.

        nat (DMZ,outside2) source static any any unidirectional

        I would have thought this would have matched any packet coming in the “DMZ” interface and pushed it out the “outside2″ interface.

      • Paul Stewart says:

        I would thought so as well. Probably what I need to do (when I can find the time) is configure that in 8.2 and upgrade to 8.4. That would tell us what Cisco thinks the new syntax should look like. Then I could see if It works similarly.

      • papacheops says:

        Using ASDM, I can build the bi-directional NAT specifications, and the syntax comes out like:

        nat (outside2,DMZ) source static any any destination static DmzIpRange DmzIpRange

        And packets coming IN from the outside2 interface aimed at the DMZ get processed by the NAT logic… but the reverse (DMZ going out) do not, and therefore follow the routing rules and go out the default route…

        I may have to give up on this. It just doesn’t seem logical… But then, when have computers been logical! :) haaaaa

  6. Mihaylov says:

    What about post-8.4?
    Has anyone succeeded overriding the egress interface logic with that kind of NAT?

    • Paul Stewart says:

      I haven’t experimented personally with this. I do think it is possible. I found the article below that talks about the misconception that the ASA (article is based on the later code) always forwards bases on route table. You may be able to use it as a starting point. I may experiment and write more about it in the future. Thanks for the comment.
      http://packetpushers.net/understanding-when-a-cisco-asa-nat-rule-can-override-the-asa-routing-table/

      • Mihaylov says:

        I’ve read this article too. Thanks.
        But the “identity NAT divert egress interface” feature seems to work in another way in the 9.x versions.
        In 9.x code, I’ve gotten it to work for TCP and UDP traffic.. like this:
        nat (inside,isp2) source static any any service obj-tcp-any obj-tcp-any
        nat (inside,isp2) source static any any service obj-udp-any obj-udp-any

        Otherwise it just does the route look up first and goes on.

Leave a Reply