Traffic filtering with Cisco access lists: Why, how, and what to consider

If you are new to Cisco and security, you will want to begin at the beginning. In this Daily Drill Down, Robert McIntire starts from the very beginning to explain the details of this popular security tool.

Sometimes we find ourselves caught up in the day-to-day tasks of managing a network and rarely have time to take a hard look at the type of protocol traffic passing across that network. That is, until a traffic problem arises. Is this starting to sound familiar? For those of us plagued by unnecessary or nonsecure network traffic, there is a solution—the access list. An access list is quite literally a traffic filter applied to the router, either denying or allowing specific network traffic. Often used for network security and bandwidth control, access lists come in a few basic flavors, ranging from simple to complex. Access lists can be used in a broad scope to block whole networks or an entire protocol suite. However, they can also be used with granular precision to pinpoint only specific addresses, protocols, or ports. One thing to keep in mind is that access lists are protocol-specific. So, if multiple protocols (e.g., IPX, IP) are running on the network, you may need an access list for each one.

In this Daily Drill Down, I will introduce you to access lists, how to filter, and how to control bandwidth.

When to implement
When, you may ask, do I need to implement access lists? In the following scenario, we’ll use bandwidth control as our reason for implementing a filter.

Let’s say, for instance, that the accounting department is off-site and has a slow, 64K connection to the central office. The application they use most frequently is a custom database application (using port 12312) located at the central office. Also, e-mail transfer is necessary, but minimal. When accounting was first connected to the central office network, traffic estimates were based only upon these business necessities. Lately, accounting personnel have been complaining about slow response times and application errors with the custom application. In analyzing network traffic, you find that there is a great deal of World Wide Web traffic crossing this slow link, headed eventually to the Internet. This additional traffic, in conjunction with that originally considered, has overwhelmed available bandwidth and the application clients are timing out as a result. What to do? We could replace the slow link with a higher bandwidth connection to support the additional traffic. But, considering how long it may take to upgrade the communication link, this is not a very timely solution. On the other hand, we could filter the WWW traffic, thereby freeing up bandwidth. Put another way, we can create an access list to allow only the necessary traffic from the accounting network.

Access list details
Let’s briefly review some of the details about access lists. The access list types are basic and extended. The basic access list only allows the filtering of traffic based on source address. It is ideal for a simple filter, which for instance, could block all traffic from a source subnet. The other type, extended, affords a greater level of control when specifying traffic through several different parameters, including source, destination, protocol, and port. Additionally, access lists are designated by name or numbered within certain prescribed ranges, depending upon type and protocol. Implementing an access list generally requires only a couple of steps. First we create it, and then we apply it to the router interface.

The basic access list
Now, let’s apply these concepts by creating a basic access list for our accounting department. The following examples presume a basic understanding of IP addressing. Assuming that all accounting machines are on the same subnet,, we could try the following access list. First, we simply create the access list from the router global configuration prompt, as follows:
AcctRouter(config)#access-list 1

Here, we entered the keyword, access-list, followed by the number. Since this is a basic IP access list, we use a number within the allowed range, 1-99. The basic list syntax is as follows.

Notice that some parameters are optional, such as remark.

From there, we just add individual statements to the list allowing or denying traffic from certain addresses, ports, etc. You can add as many statements as you like (based on available memory), but keep in mind that every statement the router has to process has a cost with respect to throughput. Each packet is checked against each statement. If no match occurs, the packet is dropped. This occurs because of the implicit deny all attribute of access lists. This implicit deny all is the last statement in an access list and denies all traffic not explicitly allowed. Now we add a filter statement to the access list for the accounting subnet.

First we specify the access list keyword, number, then deny, and the protocol and source address/wildcard information. This is the syntax.

Let’s take a look at the wildcard parameter. It specifies how to treat the source address and is a somewhat misunderstood parameter with Cisco access lists. Any bit that is off or 0 is checked for a match, and any bit that is on is ignored. So, the preceding statement will cause the first 3 octets (the network number) to be checked, and the host number to be ignored, thereby blocking all hosts on this subnet. Using the basic list, we can filter entire networks, address ranges, or a single host.

Applying the access list
Remember that the last step when implementing an access list is to apply it to an interface. Until we do so, it has no filtering effect on traffic. Before we apply it, we should probably consider a few other details, namely, which interface to filter and in which direction. It is generally best to filter traffic as close to the source as possible. So, in this case, we’ll filter inbound traffic entering the router interface that is locally connected to the accounting network:
AcctRouter(config)#interface ethernet0
AcctRouter(config-if)#ip access-group 1 in

In this example, we change to interface configuration mode for the ethernet0 interface and then apply the access list using the access-group statement. The syntax for the access-group statement is as follows:
ip access-group {access-list-number | name}{in | out}

After applying an access list to your router, it’s not a bad idea to verify that the access list is active, like so:
AcctRouter#show ip access-lists

The output of this show command will display which lists exist on the router, in detail. There are also counters that you can view to see the specific access list violations or packets filtered, but we won’t delve quite that deep here.

At this point, we’ll assume we have an active access list (access-list 1) filtering on the source IP address of the entire accounting subnet. Now the help desk phone begins to ring, and by coincidence, several of the incoming calls are from the accounting department. All callers claim that they can no longer access the central office network. After checking the access list counters, as previously mentioned, we determine that we are filtering all traffic entering the accounting router from the local subnet. Needless to say, this is not what we intended. At this point, the quickest way to remedy the situation is to delete the filter using the no form of the command, as follows:
AcctRouter(config)#no access-list 1

You can verify this by again showing the access lists:
AcctRouter#show ip access-lists

The output of this statement should display nothing, as there are no longer any access lists.

The extended access list
So, we’re out of hot water for the moment, but what went wrong, you may ask. Remember that the basic access list only allows filtering by source address. But we need to filter just the WWW traffic coming from the accounting subnet, not all traffic from accounting. So, in this case, we should have used an extended access list, which would provide us with the ability to also specify the HTTP protocol.

The syntax of the extended IP access list goes something like this.

Note that there are other parameters available with later IOS versions, which have been abbreviated here for simplicity.

Now, before we try again, let’s consider another feature that might help to simplify the process. What if we could shortcut the addressing notation? Rather than using the full form of the source and destination address/wildcard combination, we can use keywords to abbreviate, as well as make the statement easier to read. For this, we can use the keywords any and host.

Let’s try it again with an extended list, like this.

In the first line, we create the IP extended access list, 100, which is in the allowed numeric range of 100-199. The next statement explicitly allows the custom application (on port number 12312) from the accounting subnet to any destination address. The next statement allows client e-mail traffic on POP3. Also, we have designated the protocol by name instead of the number. Lastly, we apply it to the interface.

If we only wanted to allow one host from accounting to access the WWW, we could do this using the host keyword, much like this.

What if at this point you realize that the port number should have been 12112 for the custom application. We simply delete the list and re-create it, right? Yes, but first we’re going to select and copy all the valid statements in the current list for a future paste into our telnet session. You can do this easily by displaying the router configuration with the show run command and copying the commands directly from your telnet session. Now we delete the list, re-create it, and then paste and/or add statements, like so.

Now apply it to the interface as before.

Another issue that we’ve only touched on is the permit/deny paradigm of the access list. If we remember the concept of the implicit deny all, we know that all traffic not specifically allowed in a statement will be denied. But the only traffic we’ve looked at so far is at the application level. Depending on your network, you will most likely need to permit other forms of traffic that support the communications infrastructure. What if all server resources were at the central office? Will you allow accounting users to contact a server there to get an IP address (DHCP), browse outside their network (Netbios), or log in?

Now we begin to see the impending headache of this method.

On the other hand, we can approach the access list from a different angle. Rather than a deny-all-except model, what if we employed an allow-all-except model? Since our end goal is to simply restrict the flow of Web traffic, why not deny only that and allow everything else, protocol-wise, to pass go? It may not be as secure as the deny-all model, but it’s certainly simpler and less problematic. To do this, let’s try this.

Here, the first statement prohibits only HTTP (WWW traffic), while the second statement allows everything else. Again, if you use this method, you don’t have to concern yourself with DHCP, browsing issues, etc. But the tradeoff between simplicity and security should be factored into your configuration. Consider all traffic carefully before filtering. Following are some of the more common IP protocols:
Common IP protocols / ports:
HTTP – 80
FTP – 20,21
Telnet – 23
POP3 – 110
SMTP – 25

As may already be evident, this Daily Drill Down is not meant to explain the full breadth and depth of the access list functionality, but rather to introduce the basic tasks and reasoning behind the use of access lists as a network traffic solution. It is not meant to be IOS-specific. Feature sets vary from version to version, and platform to platform. Later versions generally provide additional features for filtering traffic. We’ve made every effort to deal with common issues that transcend IOS version. I recommend that you check the documentation for your platform and IOS for specific syntax and features.

Things to keep in mind
  1. ·        Use only one access list per protocol per interface.
  2. ·        The order and number of statements can greatly affect router performance. Place the statements mostly likely to match a packet near the beginning of the list.
  3. ·        Implicit deny all.
  4. ·        Use keywords to make your configuration more readable.
  5. ·        Be careful not to disconnect yourself from a telnet session with an access list.

Hints and tips
Maintain copies of your access lists in a text file. This can make it easier to view and modify them. You can cut and paste this text copy directly into a router configuration via a telnet session. This technique can really cut down on access list configuration and management time.

Save your configuration often when working on a router. If it resets unexpectedly, you may not lose all your changes (even though you might want to at that point).

Back up your configuration to a TFTP server before making changes. This way you can easily fall back to a previous configuration. If you completely lose the configuration and need to start from scratch, it simplifies things if your TFTP server is on the same subnet as the router.

Editor's Picks