|
Author
|
Topic: ASA traffic blogging
|
Smeans
unregistered
|
posted May 13, 2011 01:40 PM
Hi all, I've noticed in classes, test results and the real world that there is a lot of confusion about how an ASA actually processes traffic. So I decided to do a multi-part series on this foundation topic. Here is part 1:
This doc is meant to explain clearly how traffic actually travels through an ASA with various settings configured. This will include order of operations, inspection features, modes, contexts, etc… It will draw heavily on packet tracer for demonstrating as it tends to give the most complete information about the steps taken.
So, to start with we’re doing to have a simple single mode routed ASA with an inside (192.168.2.0) and outside (24.234.6.0) interface. Default inspections, no NAT, no ACLs. Telnet traffic from inside to outside looks like:
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
Phase: 3 Type: ROUTE-LOOKUP Subtype: input Result: ALLOW Config: Additional Information: in 24.234.6.0 255.255.255.0 outside Phase: 4 Type: IP-OPTIONS Subtype: Result: ALLOW Config: Additional Information:
Phase: 5 Type: IP-OPTIONS Subtype: Result: ALLOW Config: Additional Information:
Phase: 6 Type: FLOW-CREATION Subtype: Result: ALLOW Config: Additional Information: New flow created with id 2, packet dispatched to next module
Phase: 7 Type: ROUTE-LOOKUP Subtype: output and adjacency Result: ALLOW Config: Additional Information: found next-hop 24.234.6.6 using egress ifc outside adjacency Active next-hop mac address 001b.53b4.3650 hits 5
Result: input-interface: inside input-status: up input-line-status: up output-interface: outside output-status: up output-line-status: up Action: allow
We can see that the first check was for a MAC ACL and found none. Then an existing flow was looked for and none found. After that, the routing table is checked for a route to the destination. In this case there is a connected route, if there wasn’t the traffic would be dropped with “no route to host”. Two blank ip options are checked, then a flow created.
Finally a second more detailed route lookup is performed. This one actually checks egress interface, next hop IP and mask. About the two route lookups, I assume the first to be a simple, less resource intensive lookup with the point of, “Do I actually need to bother with this traffic if I don’t know the destination network?” This is backed up by the fact that even if an ingress ACL or implicit deny drops the traffic, the route lookup is still performed prior to this.
The second is “I actually have to route this traffic, where do I need to send it?”
So far so good, now let’s move on to a typical small office scenario. Natting all inside hosts to the outside interface IP. The steps taken are the same, but now in between the ip options checks we have the NAT.
Phase: 4 Type: NAT Subtype: Result: ALLOW Config: nat (inside) 1 0.0.0.0 0.0.0.0 match ip inside any outside any dynamic translation to pool 1 (24.234.6.100 [Interface PAT]) translate_hits = 1, untranslate_hits = 0 Additional Information: Dynamic translate 192.168.2.5/1024 to 24.234.6.100/5878 using netmask 255.255.255.255
Phase: 5 Type: NAT Subtype: host-limits Result: ALLOW Config: nat (inside) 1 0.0.0.0 0.0.0.0 match ip inside any inside any dynamic translation to pool 1 (No matching global) translate_hits = 0, untranslate_hits = 0 Additional Information:
The first is checking for a valid translation rule and the second checks host limits. Other than that, the results are the same.
Now, what happens when we do an ingress ACL on the inside interface?
Phase: 2 Type: ROUTE-LOOKUP Subtype: input Result: ALLOW Config: Additional Information: in 24.234.6.0 255.255.255.0 outside
Phase: 3 Type: ACCESS-LIST Subtype: log Result: ALLOW Config: access-group IN_OUT in interface inside access-list IN_OUT extended permit ip 192.168.2.0 255.255.255.0 any Additional Information:
Right after the initial route lookup but before the IP option and NAT checks we’re checking the ACL. This makes sense logically as you wouldn’t want translation entries for traffic that was to be dropped anyway.
Now let’s throw MPF into the mix. Instead of telnet traffic I’m going to do FTP which is inspected by default.
Phase: 5 Type: INSPECT Subtype: inspect-ftp Result: ALLOW Config: class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default inspect ftp service-policy global_policy global Additional Information:
After the ACL but before options it is inspected. Again this makes sense, not wasting resources inspecting if an ACL will drop the packet.
All of this is fairly standard/logical. Now, let’s introduce some contention between NAT and inspection and see which works. First up I’m going to introduce at static nat for an inside host 192.168.2.5 and prove that it takes precedence over the dynamic NAT as it says in the ASA order of operation literature. And sure enough it does:
Phase: 6 Type: NAT Subtype: Result: ALLOW Config: static (inside,outside) 24.234.6.5 192.168.2.5 netmask 255.255.255.255 match ip inside host 192.168.2.5 outside any static translation to 24.234.6.5 translate_hits = 1, untranslate_hits = 0 Additional Information: Static translate 192.168.2.5/0 to 24.234.6.5/0 using netmask 255.255.255.255
Next up, static identity NAT for the same host. Now we’ve got a mystery as it appear to trip BOTH nat rules:
Phase: 6 Type: NAT-EXEMPT Subtype: Result: ALLOW Config: match ip inside host 192.168.2.5 outside any NAT exempt translate_hits = 1, untranslate_hits = 0 Additional Information: Phase: 7 Type: NAT Subtype: Result: ALLOW Config: static (inside,outside) 24.234.6.5 192.168.2.5 netmask 255.255.255.255 match ip inside host 192.168.2.5 outside any static translation to 24.234.6.5 translate_hits = 5, untranslate_hits = 0 Additional Information:
So, let’s look at the actual device and see what happens:
R5#telnet 24.234.6.6 Trying 24.234.6.6 ... Open
User Access Verification
Password: R6#who Line User Host(s) Idle Location *514 vty 0 idle 00:00:00 192.168.2.5
Interface User Mode Idle Peer Address
As shown the identity nat takes precedence.
Now I’m going to introduce an FTP inspect and apply it to the inside interface. The interface specific policy should take precedence. It certainly inspects, but it isn’t clear in PT what policy was used:
Phase: 5 Type: INSPECT Subtype: inspect-ftp Result: ALLOW Config: Additional Information:
For that we just look at the service policy and see what policy got hits. Sure enough it’s the interface one:
Interface inside: Service-policy: FTP_TEST Class-map: FTP Inspect: ftp strict FTP, packet 2, drop 0, reset-drop 0
The point here is that the order of operations is fairly logical. Things that take resources come after things that don’t. When there is contention, the more specific configuration takes precedence. In part 2 we’re going to see how this stuff works on a multi-context firewall.
IP: Logged
|
|
Pushkar Bhatkoti
Brainiac
Member # 23144
Member Rated:
|
posted May 14, 2011 06:07 PM
Nice.. keep other posting coming please..
Posts: 860 | From: Sydney/Australia | Registered: Sep 2007
| IP: Logged
|
|
Smeans
unregistered
|
posted May 16, 2011 09:08 AM
The multi context setup at first is two contexts (c1 and c2) with unique inside interfaces (VLAN interfaces) and a shared outside. Now, as far as the contexts themselves are concerned there is really no difference here. If you run a packet tracer they’ll look just as they did with a single mode routed firewall. All the work is done by the switch/trunk on the inside interface and the classifier to send the traffic to the proper context for traffic incoming on the shared outside interface.
One note here is that with such a configuration you MUST be careful with the VLAN assignment of hosts on the inside because a packet going inside->outside WILL be sent regardless of the source IP. Return traffic will then be routed back to the opposite context (assuming unique MAC or nat rules) and all kinds of async routing problems will occur. For this reason it’s recommended to do uRPF on the inside of both contexts just in case. See below, the first packet tracer is an IP from context c2’s inside IP space sent on context c1. (cut for space)
Phase: 7 Type: ROUTE-LOOKUP Subtype: output and adjacency Result: ALLOW Config: Additional Information: found next-hop 24.234.6.6 using egress ifc Outside adjacency Active next-hop mac address 001b.53b4.3650 hits 5
Result: input-interface: Inside input-status: up input-line-status: up output-interface: Outside output-status: up output-line-status: up Action: allow
The second is with uRPF turned on, the route (default route) is found but uRPF does its job.
Phase: 1 Type: FLOW-LOOKUP Subtype: Result: ALLOW Config: Additional Information: Found no matching flow, creating a new flow
Phase: 2 Type: ROUTE-LOOKUP Subtype: input Result: ALLOW Config: Additional Information: in 24.234.6.0 255.255.255.0 Outside
Phase: 3 Type: ROUTE-LOOKUP Subtype: input Result: ALLOW Config: Additional Information: in 0.0.0.0 0.0.0.0 Outside
Result: input-interface: Inside input-status: up input-line-status: up output-interface: Outside output-status: up output-line-status: up Action: drop Drop-reason: (rpf-violated) Reverse-path verify failed
Now we’re going to change to a little bit of a nutty configuration to prove a point. Both inside and outside interfaces are going to be shared. The outside interfaces are on the same IP subnet (24.234.6.0/24) but the inside interfaces are on different IP subnets but the same VLAN (50.1.1.0/24 and 192.168.2.0/24)
Think, “Company A and B merged and are now using the same switched infrastructure but different IP subnets”. MAC address auto is turned off. Because the classifier requires a unique interface (we don’t have it), a unique MAC address (we don’t have it) or NAT rules (we don’t have them) the traffic should just not work. This is show by trying to ping from an inside host to an outside. The host (50.1.1.5) has a default gateway of 50.1.1.100 which is context c1’s inside IP.
R5#ping 24.234.6.6
Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 24.234.6.6, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)
The classifier simply doesn’t know which context to deliver this traffic to. Now, let’s create a NAT rule for the 50.1.1.5 host to translate to 24.234.6.5.
ASA1/c1(config)# static (i,o) 24.234.6.5 50.1.1.5
R5#ping 24.234.6.6
Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 24.234.6.6, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)
Still a no go. Why? Remember that the destination MAC is still not unique (same MAC for both c1 and c2) and the 50.1.1.5 source IP traffic could technically be destined for the 192.168.2.100 interface (c2’s inside interface) even though there is a NAT for it on c1. In this specific case, the only way to make this work is to have an outside NAT for the destination address.
ASA1/c1(config)# static (o,i) 50.1.1.6 24.234.6.6
R5#ping 50.1.1.6
Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 50.1.1.6, timeout is 2 seconds: .!!!! Success rate is 80 percent (4/5), round-trip min/avg/max = 1/1/4 ms
Obviously this would be a huge hassle in the real world if the Outside interface was the internet. And there really is no reason not to use mac-address auto instead. I’ll remove the statics and do that:
ASA1/c1(config)# no static (Outside,Inside) 50.1.1.6 24.234.6.6 netmask 255.25$ ASA1/c1(config)# no static (Inside,Outside) 24.234.6.5 50.1.1.5 netmask 255.25$ ASA1/c1(config)# changeto system ASA1(config)# mac-address auto
R5#ping 24.234.6.6
Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 24.234.6.6, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
That’s about it for multi-context. Next installment will be transparent firewall.
IP: Logged
|
|
|