Access Lists
What are they?
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 or UDP (User Datagram Protocol)
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). 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.
Standard Access Lists
Access lists are generally broken into 2 major groups, standard and extended. Standard
access lists only operate on the Network layer of the OSI model. These are used to block
or permit networks from reaching other networks. For example, suppose I have a network
with a web server on it. I would like to have the router filter traffic going to that
webserver so that only a few home users and all users at work can access that machine. I
could use a standard access list to permit these allowed hosts and deny traffic from every
other host on the Internet.
To enable an access list such as this for IP, we need to configure an access list in the
range of 1 to 99. For example:
access-list 1 permit 206.50.17.0 0.0.0.255
The first part shows "access-list" which is what all access lists start with, regardless of
what network technology is used. The next part is "1" which specifies the # of the access
list. To add additional rules to this list, you would start each line with "access-list 1".
Permit indicates to the router that this is a rule specifying what should be allowed. Next is
the network and subnet mask pair. Notice, however, that the subnet mask is inversed.
Normally, for a /24 you would use a netmask of 255.255.255.0, but in access-lists, the
subnet masks are inversed so that 255.255.255.0 becomes 0.0.0.255. The 255 in this case
means ignore the last octet of the address when looking for a matching packet.
Extended Access Lists
Extended access lists function on both layer 3 and 4 of the OSI model. That is, they allow
you to filter not only by network address but also by the type of traffic that is being sent
or received. Extended access lists are much more flexible and allow for much greater
control of traffic into and out of your network than standard access lists.
Let's go through an example to see how extended access-lists work.
fred# config t
fred(config)# access-list udp 100 permit any 172.50.10.0 0.0.0.255 eq
53
fred(config)# access-list tcp 100 permit any 172.50.10.0 0.0.0.255 eq
25
fred(config)# access-list tcp 100 deny 172.50.12.0 0.0.0.255
172.50.10.0 0.0.0.255
fred(config)# access-list tcp 100 permit any any
fred(config)# int s1
fred(config-if)# ip access-group 100 in
fred(config-if)# exit
fred(config)# exit
The first line takes into configuration mode so that we can setup our access list. The next
line configures access list 100 to permit any traffic from 172.50.10.0/24 to reach our
network on port 53. I know that this is for inbound traffic because of the line that says "ip
access-group 100 in". When designing access lists, it is important to know before hand
how you are designing your access-list whether for inbound or outbound traffic.
The third line specifies that SMTP traffic from 172.50.10.0/24 is to be allowed into our
network. Next, traffic from 172.50.12.0/24 is not allowed to go to the network
172.50.10.0/24. Finally, any traffic that did not match any of the above rules is allowed
by the line that says "access-list tcp 100 permit any any".
Let's look at another couple of examples.
Denying access to a host
Our first example is a statement that denies access to a host with the IP address of
130.120.110.100. Make sure you are at the "enable" level and enter "config" mode (or
config terminal), and enter the following:
access-list 101 deny ip 0.0.0.0 255.255.255.255 130.120.110.100 0.0.0.0
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 0's 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 0.0.0.255. 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 0.0.0.0 255.255.255.255 130.120.110.100
0.0.0.0 eq 80
access-list 101 deny ip 0.0.0.0 255.255.255.255 130.120.110.100 0.0.0.0
The first statement matches any packet with 130.120.110.100 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 0.0.0.0 255.255.255.255 0.0.0.0 255.255.255.255
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.
Enabling and Disabling
In our above example, there are 2 lines use to apply, or enable, the access list to an
interface. The first line is "int s1" which takes you into the configuration for that
interface. The second line, "ip access-group 100 in" sets up the access list 100 to act as an
inbound filter for that interface. An interface can only have 1 inbound and 1 outbound
access list applied to it at any one time.
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.
If we wanted to take down the access list, for example to troubleshoot a connectivity
problem, we would need to remove the line from the configuration that says "ip access-
group 100 in". To do this, we can type the following:
fred# config t
fred(config)# int s1
fred(config-if)# no ip access-group 100 in
fred(config-if)# exit
fred(config)# exit
This only disables the access list. It does not delete or remove it from the configuration.
Access-list 100 is still present in the configurations. It is generally advisable that if you
are modifying an access-list that you disable it before making any modifications so that
just in case you make a mistake, you won't stop any wanted traffic, such as your users or
yourself.
Modifying Access Lists
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.
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. Instead, what
many administrator do is to use a text editor such as Notepad or VIM to hold a copy of
the access list. After viewing the running configuration, copy the access list to your text
editor. Make any modifications that you are going to make to the access list. Then, you
will need to disable the old access-list, delete it, add the new one, and then enable it.
Here's how you can do that.
fred# config t
fred(config)# int s1
fred(config-if)# no ip access-group 100 in
fred(config-if)# exit
fred(config)# no access-list 100
fred(config)# INSERT YOUR NEW LIST HERE
fred(config)# int s1
fred(config-f)# ip access-group 100 in
fred(config-if)# exit
fred(config)# exit
fred# copy start run
Issues and Drawbacks
Access lists are great for doing simple filtering and security for basic networks. However,
there are some things to keep in mind when building and implementing them. First, the
longer an access list, the more processor time it uses. Really long access lists can slow
your router down significantly and even put an appreciable wait time for users trying to
access machines on your network. Second, make sure that you put your most general
statements at the top. That is, any statements that affect most of your users should be
placed near the top of an access list while more specific statements that may only affect
one machine should be placed near the bottom. Remember that access lists work serially,
one right after the other. Third, access lists are not dynamic, so they cannot adapt to
changing network or security situations. Therefore, as things get more complex, you
might want to consider a true firewall package to use in its place.