09-02-2012 07:23 AM - edited 03-11-2019 04:48 PM
Hello
Since I have seen a plethora of contradicting posts and documentation regarding the ASA order of operations,
I would like to clarify this topic regarding Routing, NAT, ACL on both pre-8.3 and post-8.3 ASA. I don't want to check
more features since I would like to clarify these 3 first that I consider the most basic.
Topology used for the testing:
1.1.1.1 R1 -----100.0.0.0/24------ INSIDE ASA1 OUTSIDE ------100.0.1.0/24-------- R2 2.2.2.2
Pre-8.3 ASA
The initial ASA configuration:
ASA1# sh run static
static (insidE,outside) 100.0.1.99 1.1.1.1 netmask 255.255.255.255
ASA1# sh run access-list
access-list INSIDE_IN extended permit ip host 1.1.1.1 host 2.2.2.2
access-list OUTSIDE_IN extended permit ip host 2.2.2.2 host 1.1.1.1
access-list OUTSIDE_IN extended permit ip host 2.2.2.2 host 100.0.1.99
ASA1# sh run access-group
access-group INSIDE_IN in interface inside
access-group OUTSIDE_IN in interface outside
Case 1 - source NAT
Without configuring any routing on ASA1
When I try to ping from 1.1.1.1 to 2.2.2.2 I see that the ACL INSIDE_IN doesn't get any hit counts.
Also packet-tracer output shows a failure due to missing routing without checking for ACL or NAT
(the Implicit ACL is not the ACL INSIDE_IN)
ASA1# packet-tracer input inside icmp 1.1.1.1 8 0 2.2.2.2
Phase: 1
Type: ACCESS-LIST
Subtype:
Result: ALLOW
Config:
Implicit Rule
Additional Information:
MAC Access list
Phase: 2
Type: FLOW-LOOKUP
Subtype:
Result: ALLOW
Config:
Additional Information:
Found no matching flow, creating a new flow
Result:
input-interface: inside
input-status: up
input-line-status: up
Action: drop
Drop-reason: (no-route) No route to host
Conclusion 1:
Routing is checked before ACL and NAT.
I add routing on ASA1:
ASA1# sh run route
route insidE 1.1.1.1 255.255.255.255 100.0.0.1 1
route outside 2.2.2.2 255.255.255.255 100.0.1.1 1
Now packet-tracer shows:
ASA1#packet-tracer input inside icmp 1.1.1.1 8 0 2.2.2.2
Phase: 1
Type: FLOW-LOOKUP
Subtype:
Result: ALLOW
Phase: 2
Type: ROUTE-LOOKUP
...
in 2.2.2.2 255.255.255.255 outside
Phase: 3
Type: ACCESS-LIST
...
access-group INSIDE_IN in interface inside
access-list INSIDE_IN extended permit ip host 1.1.1.1 host 2.2.2.2
...
Phase: 6
Type: NAT
...
static (inside,outside) 100.0.1.99 1.1.1.1 netmask 255.255.255.255
Conclusion 2:
On pre-8.3 ASA for source NAT the order of operations is:
1. Routing
2. Inbound ACL
3. NAT
Case 2 - destination NAT (UN-NAT)
I remove again the 2 static routes:
ASA1(config)# no route outside 2.2.2.2 255.255.255.255 100.0.1.1 1
ASA1(config)# no route inside 1.1.1.1 255.255.255.255 100.0.0.1
I try to ping from 2.2.2.2 the 100.0.1.99 (NATed IP of 1.1.1.1)
The ping fails, but the ACL OUTSIDE_IN is getting hit counts although there is no routing towards 1.1.1.1
Also, note that only the ACE with destination 100.0.1.99 (post-NAT) gets hit counts. That means the ACL
is checked before the destination NAT (UN-NAT) and the routing:
access-list OUTSIDE_IN line 1 extended permit ip host 2.2.2.2 host 1.1.1.1 (hitcnt=0)
access-list OUTSIDE_IN line 2 extended permit ip host 2.2.2.2 host 100.0.1.99 (hitcnt=2)
Conclusion 3:
For destination NAT, the ACL is checked before routing. Also the ACL is checked before the NAT.
I add the static routes and now ping succeeds.
Packet-tracer shows:
ASA1#packet-tracer input outside icmp 2.2.2.2 8 0 100.0.1.99
Phase: 1
Type: FLOW-LOOKUP
...
Phase: 2
Type: UN-NAT
Subtype: static
...
static (inside,outside) 100.0.1.99 1.1.1.1 netmask 255.255.255.255
Untranslate 100.0.1.99/0 to 1.1.1.1/0 using netmask 255.255.255.255
Phase: 3
Type: ACCESS-LIST
...
access-list OUTSIDE_IN extended permit ip host 2.2.2.2 host 100.0.1.99
...
Phase: 6
Type: NAT
Subtype: rpf-check
Result: ALLOW
Config:
static (inside,outside) 100.0.1.99 1.1.1.1 netmask 255.255.255.255
...
Phase: 8
Type: ROUTE-LOOKUP
...
found next-hop 100.0.0.1 using egress ifc inside
adjacency Active
next-hop mac address cc00.0d18.0000 hits 2
Conclusion 4:
On pre-8.3 ASA with destination NAT the order of operations is:
1. ACL
2. UN-NAT (destination NAT)
3. Routing
Post 8.3 ASA - (8.4(2) on GNS3)
Same topology:
1.1.1.1 R1 -----100.0.0.0/24------ INSIDE ASA1 OUTSIDE ------100.0.1.0/24-------- R2 2.2.2.2
ASA initial config (In configured a Manual Static NAT (Twice NAT) same as before (1.1.1.1 will be
translated to 100.0.1.99 as it goes from inside to outside):
ASA1# sh run object
object network R1_REAL_1.1.1.1
host 1.1.1.1
object network R1_NAT_100.0.1.99
host 100.0.1.99
nat (inside,outside) source static R1_REAL_1.1.1.1 R1_NAT_100.0.1.99
ASA1# sh run access-list
access-list INSIDE_IN extended permit ip host 1.1.1.1 host 2.2.2.2
access-list OUTSIDE_IN extended permit ip host 2.2.2.2 host 1.1.1.1
access-list OUTSIDE_IN extended permit ip host 2.2.2.2 host 100.0.1.99
ASA1# sh run access-group
access-group INSIDE_IN in interface inside
access-group OUTSIDE_IN in interface outside
Case 1
I try to ping from R1 (1.1.1.1) to R2 (2.2.2.2). Ping fails since ASA1 doesn't have routing towards
2.2.2.2. The ACL INSIDE_IN doesn't get any hit-counts.
Conclusion 5:
As with pre-8.3 ASA, the routing is checked before the inbound ACL and the NAT.
packet-tracer verifies this:
ASA1# packet-tracer input inside icmp 1.1.1.1 8 0 2.2.2.2
Phase: 1
Type: ACCESS-LIST
Subtype:
Result: ALLOW
Config:
Implicit Rule
Additional Information:
MAC Access list
Result:
input-interface: inside
input-status: up
input-line-status: up
Action: drop
Drop-reason: (no-route) No route to host
I add static routes on ASA1:
ASA1(config)# route inside 1.1.1.1 255.255.255.255 100.0.0.1
ASA1(config)# route outside 2.2.2.2 255.255.255.255 100.0.1.1
Now ping succeeds. Packet-tracer shows:
ASA1#packet-tracer input inside icmp 1.1.1.1 8 0 2.2.2.2
Phase: 1
Type: ROUTE-LOOKUP
...
in 2.2.2.2 255.255.255.255 outside
Phase: 2
Type: ACCESS-LIST
...
access-group INSIDE_IN in interface inside
access-list INSIDE_IN extended permit ip host 1.1.1.1 host 2.2.2.2
Additional Information:
...
Phase: 5
Type: NAT
...
nat (inside,outside) source static R1_REAL_1.1.1.1 R1_NAT_100.0.1.99
Additional Information:
Conclusion 6:
On post-8.3 ASA, for destination NAT, NAT is checked before the ACL and before the routing.
1. UN-NAT (destination NAT)/Partial Routing (find the exit interface based on NAT configuration)
2. ACL
Packet-tracer shows:
ASA1# packet-tracer input outside icmp 2.2.2.2 8 0 100.0.1.99
Phase: 1
Type: ACCESS-LIST
Subtype:
Result: ALLOW
Config:
Implicit Rule
Additional Information:
MAC Access list
Phase: 2
Type: UN-NAT
Subtype: static
...
nat (inside,outside) source static R1_REAL_1.1.1.1 R1_NAT_100.0.1.99
Additional Information:
NAT divert to egress interface inside
Untranslate 100.0.1.99/0 to 1.1.1.1/0
Phase: 3
Type: ACCESS-LIST
...
access-group OUTSIDE_IN in interface outside
access-list OUTSIDE_IN extended permit ip host 2.2.2.2 host 1.1.1.1
...
Phase: 6
Type: NAT
Subtype: rpf-check
Result: ALLOW
Config:
nat (inside,outside) source static R1_REAL_1.1.1.1 R1_NAT_100.0.1.99
Note that packet-tracer doesn't show explicitly the routing checking phase since there was 'partial routing' check after the UN-NAT
SUMMARY
pre-8.3 ASA with source NAT:
1. Routing
2. Inbound ACL
3. NAT
pre-8.3 ASA with destination NAT:
1. ACL
2. UN-NAT (destination NAT)
3. Routing
post-8.3 ASA with source NAT:
1. Routing
2. Inbound ACL
3. NAT
post-8.3 ASA with destination NAT:
1. UN-NAT (destination NAT)/Partial Routing
2. ACL
Please, feel free to correct me or to add on my testings above.
Mikis