Home | Access Control Lists Overview | 10 Things to know about ACLs | Adding Remarks
Anatomy of ACLs | ACL Tutorial with Q&A | ACL Wildcards
ACL PowerPoint 1 | ACL PowerPoint 2 | Cisco ACL paper

Demystifying Cisco Access Control Lists - By Peter Morrissey, edited by David Billings

Anyone who has managed a large network knows that control can be a wonderful thing. This is why routers are still so popular, in spite of the flat network craze. Routers can confine problems like excessive broadcasts, duplicate IP addresses, unauthorized DHCP servers and misbehaving Windows NT and Novell servers to a local network. In turn, fewer users are affected and the problems are easier to troubleshoot.

Sometimes, though, standard routing capabilities aren't enough. That's why Bay Networks, Cisco Systems and 3Com Corp. have added filtering capabilities, such as access control lists, to their routers. At Network Computings' lab at Syracuse University, we've been using these capabilities in our Cisco routers for the past five years to help us control some of the more difficult problems with our IP, Novell and AppleTalk networks.

Although access lists won't turn your router into a full-fledged firewall, they can be a powerful means of controlling your IP network. We'll focus here on the IP version of Cisco's access control lists, also known as extended access lists. You can apply these basic concepts to your Bay and 3Com routers, and possibly even your firewall. We've gathered extended access list information from various Cisco manuals and thrown in some tips we've learned along the way. To verify the syntax presented here, we configured one of our routers to run Cisco Internetwork Operating System (IOS) version 10.3(10). You can count on the syntax to work with that version or later versions. The text notes any features that are available only in higher versions of the IOS.

What They're All About
The access list is a group of statements. Each statement defines a pattern that would be found in an IP packet. As each packet comes through an interface with an associated access list, the list is scanned from top to bottom--in the exact order that it was entered--for a pattern that matches the incoming packet. A permit or deny rule associated with the pattern determines that packet's fate. You also can use a mask, which is like a wild card, to determine how much of an IP source or destination address to apply to the pattern match. The pattern statement also can include a TCP, UDP, Telnet, or ftp port number.

Access list statements are entered one line at a time, and the list is scanned for a match in that same order. If you must make a change, you have to re-enter the entire list. Also, keep in mind that once you associate the list with an interface, any packet not processed by the list is dropped by default.

Once the access list is entered, you must associate it with the interface on the router where you want to apply the filtering. You can apply the list to incoming packets, (an "in" access list) or outgoing packets (an "out" access list). Think of yourself inside the router and you are filtering packets coming in to you or going out from you through the affected interface or port. In most cases, either list will work. For out access lists, you need to set up the filter only on the one outgoing interface rather than on the individual incoming interfaces. This improves performance because only the network you are protecting will force a lookup on the access list.

Learn by Doing
The following examples should provide you with the basics you need to set up your own access lists. If you follow the rules we outline, then you should be able to come up with filters that meet your requirements.

Denying access to a host
Our first example is a statement that denies access to a host with the IP address of Make sure you are at the "enable" level and enter "config" mode (or config terminal), and enter the following:

   access-list 101 deny ip

The 255 mask on every octet of the source address signifies that the whole source address in the filter should be ignored. Technically, it doesn't matter what you use as the IP source address here, because it will be ignored. The all 0s mask on the destination address means that you want to apply the entire address. If you wanted to deny access to all addresses on the 130.120.110 network, you would use a mask of The 255 in this case means ignore the last octet of the address when looking for a matching packet.

Allowing access only to HTTP on a host
Here, we permit access only to the HTTP port on the host and deny all other access to the host. This requires two lines:

   access-list 101 permit tcp eq 80
   access-list 101 deny ip

The first statement matches any packet with as the destination IP address and with a TCP port equal to 80. The second rule applies a match to all IP packets with the destination address, thus denying access to all packets that are not permitted because of the previous rule.

Tying Up Loose Ends
Although all unmatched packets are dropped by default, it's still a good idea to end the list with a statement that denies everything. This helps you keep track of the end of the list:

   access-list 101 deny ip

Of course, if you want to begin your list by denying specific packets and you want to allow everything else, you would use the same statement with a permit instead of a deny. An easier way to state this is to use the following syntax:

   access-list 101 deny ip any any

This statement functions exactly the same as the previous one, and later versions of the IOS will translate the longer version into this shorter version when you display it.

When you display the list, you may find that some of the TCP and UDP port numbers have been changed to a verbose description. We prefer to enter numbers because they are backward compatible with previous IOS versions.

Turning It On
Once you have your access list set up, you must apply it to the interface before it becomes effective. Just as you would for any change to an interface configuration, you will have to enter "config" mode and designate the interface where you want to apply the filter. At this point, the list of access list statements is referred to as a "group." The command to apply access list 101 to incoming packets on an interface is: ip access-group 101 in

As soon as you enter this command, the access list will immediately take effect. It's helpful to start a continuous ping in another window to a host on the other side of the interface that you're filtering to monitor its accessibility while applying the list. Save your changes with a "write memory" and a "write network" if you're backing your configurations up on a TFTP server.

You can use the "show config" command to see which access groups are associated with particular interfaces. This command also will list all of the access list statements at the end. An easier way to look at the access lists is the "show access list" command. If you use an access list number as an argument, you will only see that list. (Do this before choosing an access list number to make sure it is not already in use.) This command also will give you statistics on matches to every access list statement. To clear all the statistics, issue a "clear access-list counters" using the list number as an argument to designate a specific list.

As stated earlier, you cannot easily go back and insert a change into an access list because the statements are processed in the order that they are originally entered into the router. (With version 11.2, you can go back and selectively delete lines, but not insert any.) If you use TFTP to load new configurations into the router, you can edit the configuration file on your TFTP host, which will get loaded in with the changes. The disadvantage to this is that you will have to schedule it for a time when you can reboot the router.

Changing Lists in Midstream
Another approach is to copy and paste the list into an editor or word processor, and then reload it. You will have to get rid of the old version before pasting the new version into the router; otherwise the new version will just be appended to the end of the old version. To remove a configuration statement from a Cisco router, enter the statement again preceded by a "no." But with access lists, you only need to re-enter one of the statements in the list, preceded by a "no," and the entire list will be removed. The disadvantages to this approach is that no access list will be in place while you go through the process, and, if you make a mistake and unintentionally deny access to a host or service, you may have to turn off the list while you figure out what you did wrong.

We've found that the best way to change an access list is to edit the old list with your word processor, then rename it before applying it to the interface. For example:
1. Copy the original access list after displaying it with the "show config" command and paste it into your word processor.

2. Use search and replace to change the access list number to a new number.

3. Edit the list.

4. Go into "config" mode and copy and paste the new list of statements back into the router.

5. Designate the interface where you are changing the list. Then using the "ip access-group xxx in/out" command, apply the new list (you don't have to turn off the old list by issuing the command with a "no" in front of it. The old list will be turned off automatically when you turn on the new list. This means that you can have only one access list per interface.)

6. If there are problems with your new list, simply reapply the old list by entering the "ip access-group xxx in/out" command again using the old list number.
Performance Issues
Access list filters exact a toll on router performance. Some of the performance-enhancing features Cisco has built into its routers will not work when access lists are used. As a result, features such as fast switching, autonomous switching, distributed switching and optimal switching will not be utilized, forcing many of the packets to be process-switched. This can burden your router's main CPU. You will want to keep an eye on the router's CPU utilization using the "show process CPU", command and watch for packets dropped at the interface. Cisco's NetFlow feature apparently does support access lists, but its new express forwarding will not support access lists. This is a good reason to do your filtering just on routers at the edge of your network and avoid it at the core, where you might have higher concentrations of traffic.

A more obvious issue is that the longer your access list, the more work your router will have to perform every time a packet has to be processed. The size of the list probably will not hurt you quite as much as the performance penalties we just described, but you should try to locate the most-likely matches at the top of your lists.

One way to ensure that most of the incoming packets are matched on the first line of the list is to put in a rule that allows all TCP established or ACK (acknowledged) packets. Established packets are those that are the result of an already established session. Generally, the majority of network packets are established. Because it's very unlikely that these packets can be harmful, even if they are spoofed, you may want to consider letting them all in right off the bat. You might want to try your access list with and without this rule, and observe changes in the CPU utilization.

The following statement at the top of your access list allows all established packets:

   access-list 101 permit tcp established

If you have many access lists, take a look at Check Point Software Technologies' Router Management Module, available with its Firewall-1 product. It lets you centrally manage the configuration of access lists on Bay, Cisco and 3Com routers via a GUI. And Cisco's Netsys Enterprise Solver product will help you check for errors in access lists as well as their impact on connectivity.

Odd or even hosts

Given the IP address: (Network Address) with a wildcard mask of
The last octet is 1111 1110, so we are going to ignore everything except the last bit.

If we say: permit tcp, then we are saying that we have to match that last bit.

For odd numbers, the last bit will always be turned on. This would permit odd and explicitly deny even.

If we wanted to use the same IP address to do the opposite: permit all odd and deny all even, we could use the deny statement: deny tcp This would explicitly deny odd and allow even.