Cisco routers make use of ACLs (access control lists) to match packets moving through the network. The packet-matching function of ACLs is essential for traffic filtering, NAT (network address translation), QoS (quality of service), and several other applications. The CCNA exams tend to focus on traffic filtering, which happens to be the most commonly used application of ACLs. IPv4 ACLs are either standard or extended, with standard ACLs matching only source IP addresses and extended ACLs matching a variety of fields in packet headers. If you haven’t seen our take on standard ACLs in GNS3 Labs for CCNA: Basic Access Control Lists, it is a good time to do that now. In the present article, we are expanding our coverage to include both numbered and named extended ACLs. We are offering the GNS3 topology and initial configuration files for download, as usual. You may refer to GNS3 Labs for CCNA: Getting Started if you need help setting up GNS3.

Extended ACL Concepts

An ACL, whether standard or extended, is identified by either a number or a name. The focus of this article is numbered and named extended IPv4 access control lists. Extended ACLs are numbered 100 to 199 or 2000 to 2699. The range of extended ACLs was initially only 100 to 199, but was later expanded to include the range 2000 to 2699.

The following graphic shows the syntax of numbered extended ACLs. Please note that the graphic shows the most commonly used options and not every possible combination.

The following steps describe how an access control list is processed by the Cisco IOS software:

  1. The software receives a packet and compares it to the first permit or deny statement in the ACL. For example, the software may compare the source and destination IP addresses in the packet header to the source and destination IP addresses in the statement.
  2. If the packet does not match the first statement, it is then compared to the next statement. The process continues until either the packet matches a statement or the end of access list is reached.
  3. Once the packet matches a statement, the rest of statements in the list are skipped and the packet is permitted or denied as specified in the statement matched. The first statement matched by a packet determines the action to be taken once and for ever, and no further statements are considered.
  4. If a statement denies a packet, the packet is just discarded and an ICMP (Internet control message protocol) Host Unreachable message is sent to the source IP address in the packet being discarded. It is a way of notifying the packet originator of the fate of unfortunate packet.
  5. There is a hidden deny statement at the end of every ACL, which is not written but is always present. If a packet does not match any statement and the end of ACL is reached, the packet hits the implicit deny statement at the end and is therefore discarded. The invisible deny statement matches just any packet.

Extended ACL Configuration

We will use the GNS3 topology shown in the following graphic to perform all configuration and verification.

Please note that hosts A, B, and C are actually routers but we changed their symbols to make the topology more intuitive. In this article, we are not using Linux hosts emulated by Qemu.

We start out by creating a numbered extended ACL on R2 using the following commands in global configuration mode.

access-list 101 deny tcp host 172.16.1.2 host 172.16.3.2 eq 80
!
access-list 101 deny udp 172.16.1.0 0.0.0.255 172.16.3.0 0.0.0.255
!
access-list 101 deny ip 172.16.2.0 0.0.0.255 172.16.3.0 0.0.0.255
!
access-list 101 permit ip any any

The access list has four statements, also known as entries, which are explained below:

  1. The first statement specifically denies HTTP traffic from 172.16.1.2 to 172.16.3.2. You should note the use of the eq operator and TCP port number 80 to identify HTTP traffic. Please keep in mind that we are matching TCP destination ports here.
  2. The second statement is supposed to block all UDP traffic from any host in the subnet 172.16.1.0/24 to any other host in the subnet 172.16.3.0/24. Please note the use of wildcard mask 0.0.0.255 to identify /24 subnets.
  3. The third statement blocks all IP traffic from any host in the subnet 172.16.2.0/24 to any other host in the subnet 172.16.3.0/24.
  4. The fourth and last statement permits all other IP traffic from any host to any other host. Any packet that does not match any of the first three statements will definitely match this statement and will be let through.
  5. There is an implicit deny statement at the end but we have effectively undone it by strategically placing access-list 101 permit any statement. This statement will match and permit just any IP packet that does not match any of the first three deny statements. No IP packet will ever reach the implicit deny statement.

Please note that the ACL is created but it is not yet applied to a router interface. The ACL has no effect so far and it is just sitting idle in the router configuration. The ACL verification may come directly from generating various types of traffic from hosts and seeing the results.

We will do a few tests before applying the ACL and then repeat the same tests afterward. Please note that the four points below correspond to four statements of the ACL (not including the implicit deny at the end).

STEP 1

You can use the telnet command with non-standard destination port 80 to test if the ACL blocks HTTP traffic. Please keep in mind that the standard telnet port is 23, which is used if you do not specify a port explicitly.

A#telnet 172.16.3.2 80
Trying 172.16.3.2, 80 ...
% Connection refused by remote host

The above output indicates that a telnet connection is refused by C. That makes sense as there is no telnet service listening on port 80. Nevertheless, the output serves as verification that TCP traffic with destination port number 80 is not blocked yet.

STEP 2

We use the traceroute utility to have the routers between source and destination reveal themselves and finally have the final destination reveal itself. The traceroute implementation on different operating systems is based on different protocols but the Cisco IOS software uses UDP (user datagram protocol). This will come in handy for generating some UDP traffic from the CLI (command-line interface) to test if our access control list blocks UDP traffic. You can simply run a traceroute from A to C for verifying if UDP traffic is blocked.

A#traceroute 172.16.3.2

Type escape sequence to abort.
Tracing the route to 172.16.3.2

1 172.16.1.1 88 msec 56 msec 24 msec
2 172.16.12.2 8 msec 28 msec 8 msec
3 172.16.3.2 52 msec 28 msec 20 msec

The above output shows a complete route trace from A to C, indicating UDP traffic is not blocked yet, as expected.

STEP 3

You can simply use a ping from B to C to verify if IP traffic is blocked between corresponding subnets.

B#ping 172.16.3.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.16.3.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max= 20/51/128 ms

STEP 4

You should be able to telnet from A to C on the standard port without problems. Please keep in mind that the first ACL statement only blocks HTTP traffic between the two hosts and we used telnet on the non-standard port just to verify it.

A#telnet 172.16.3.2
Trying 172.16.3.2 ... Open

User Access Verification

Password:

This completes our pre-tests.

Let’s now apply the access list inbound to Serial0/0 of R2, using the ip access-group command in interface configuration mode. You may recall that creating an access list is not enough to make it filter any traffic. You also have to apply it to the right interface in the right direction.

interface Serial0/0
 ip access-group 101 in

You may run the same tests again to see the results of ACL application. The first three verification steps that were successful before we applied the ACL are all broken now.

STEP 1

The telnet packets never make it to the destination. as indicated by the Destination unreachable message.

A#telnet 172.16.3.2 80
Trying 172.16.3.2, 80 ...
% Destination unreachable; gateway or host down

STEP 2

The route trace breaks at 172.16.12.2; that is the IP address configured on Serial0/0 of R2. It is the same interface to which we applied the ACL.

A#traceroute 172.16.3.2

Type escape sequence to abort.
Tracing the route to 172.16.3.2

  1 172.16.1.1 80 msec 56 msec 28 msec
  2 172.16.12.2 !A  !A  !A

STEP 3

The ping simply fails and the sequence of U indicates the ICMP Destination Unreachable messages sent by R2 as it discards packets hitting the third ACL statement.

B#ping 172.16.3.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.16.3.2, timeout is 2 seconds:
UUUUU
Success rate is 0 percent (0/5)

STEP 4\

There are no changes in the output here as compared with the corresponding pre-tests. This is expected, as the fourth ACL statement allows all IP traffic.

A#telnet 172.16.3.2
Trying 172.16.3.2 ... Open

User Access Verification

Password:

Our verification is complete here but we would like to run the show access-lists command on R2 to see hits for individual ACL statements. You can see that all ACL statements have seen some packet matches as a result of our tests.

R2#show access-lists
Extended IP access list 101
    10 deny tcp host 172.16.1.2 host 172.16.3.2 eq www (6 matches)
    20 deny udp 172.16.1.0 0.0.0.255 172.16.3.0 0.0.0.255 (6 matches)
    30 deny ip 172.16.2.0 0.0.0.255 172.16.3.0 0.0.0.255 (30 matches)
    40 permit ip any any (23 matches)

We have been talking about numbered access lists almost entirely in this article so far. But, once you understand the syntax of numbered access lists, it is trivial to construct named access lists. The following graphic presents both formats of the access list we created in this article, highlighting similarities.

You may remove the numbered ACL you created on R2 and configure the corresponding ACL in the named format as shown in the graphic above. That will be a great exercise to practice your ACL skills hands on.