An access list can be (and usually is) made up of more than just one packet-filtering rule. Rules in an access list are evaluated from the start of the list, in sequential order. The evaluation process occurs only until the conditions of one of the rules are met. After that, no further rules are looked at.
If you’ve ever done programming, think of an access list as being similar to an “if-else” loop. A router will inspect traffic it receives on an interface, and compare it to the configured access list, starting from the first rule. Let’s say that two simple rules exist in an access list, as shown in the figure below.
This access list has been configured to filter traffic as it exits interface E0, onto network 192.168.1.0/24. When RouterA receives traffic to be forwarded out interface E0, it will evaluate it against the access list. In this case, let’s assume that the traffic has a source address of 192.168.1.100. The first rule specifies that all traffic from network 192.168.25.0/24 should be denied. Obviously the rule doesn’t affect this packet. Because of this, the router looks at the next rule, which specifies that all other traffic should be allowed to pass. Our packet meets this criteria – it is part of “all other traffic”, after all. The router will forward this packet.
However, when traffic is reaches interface E0 from address 192.168.25.3, the router will evaluate the first rule and find a match – this traffic is from network 192.168.25.0/24. Because of this, the action specified in the rule should be carried out, and no other rules will be evaluated. In this case, the rule specifies that traffic from 192.168.25.0/24 should be denied, so the packet is dropped.
Getting back to my “if-else” comment from earlier, think of it like this. An access list will inspect traffic according to the rules specified, moving from top to bottom. If the packet matches the criteria specified in the rule, the associated action (permit or deny) will be carried out. If not (else), the next rule will be evaluated. This will continue until the end of the access list is reached.
Tip: Access lists are evaluated starting with the first rule, and only until a match is made.
The second critical thing to understand about access lists is how they end. Every single access list ends with what is known as an “implicit deny all” statement. This deny statement, which is not visible when viewing the list, specifies that all traffic that does not match any of the rules in the access list should be denied, and as such, dropped.
This is critical – on every access list you look at, always remember that it ends in a “deny all” statement, even though you don’t see it. Since access lists are evaluated sequentially from the beginning of the list, the purpose this serves is to deny any traffic that you haven’t explicitly permitted. I can’t overstate the importance of remembering that all access lists end with this “phantom” statement.
Tip: All access lists end with a hidden statement that denies all traffic.
For example, consider the simple access list applied to interface E0, shown in the figure below. It includes three rules, some of which permit traffic, and some of which deny it. Our phantom “deny all” is there, even though we don’t see it. This particular access list filters all traffic as it attempts to exit interface E0 on RouterA. This is known as an outbound access list.
In this case, when a packet with a source address of 192.168.10.13 reaches interface E0, it will be permitted, since the first rule doesn’t apply, and the second rule permits access from systems on network 192.168.10.0/24. When a packet from source address 192.168.20.3 reaches interface E0, it will be denied (according to the first rule), and dropped. Notice what happens when a packet from source address 192.168.100.13 reaches interface E0: the first rule doesn’t impact this packet, nor do the second and third. So what happens? The packet is denied and dropped, because of the “invisible” deny statement at the end of list. Don’t underestimate the importance of this – forgetting about the implicit deny statement is probably the cause of more access list “problems” than all others combined.
The question then becomes what to do if you only want to deny traffic from certain source addresses. Consider the simple access list shown in the figure below. The second visible rule specifies that all traffic should be permitted.
In this case, traffic that isn’t filtered by the first rule would move on to the second, and then be allowed to pass. The implicit deny at the end of the access list would never be reached, since the second rule says that all traffic should be permitted to pass. We’ll look at this in more detail later in the chapter, when we start defining real access lists.