Explanation of Access Control Lists

Currently I am working on a project where I am going through and optimizing a large set of Access Control Lists (ACL) on a set of 5585 Firewalls.  While going through these massive lists I have noticed a few mistakes other engineers have made while configuring these rules.  I figured I might as well write about ACLs and point out some common mistakes.

What is an ACL?

To start lets talk about what an ACL is.  An Access Control List is a list of rules on a firewall, router, or switch which allows or denies traffic from a source IP and port to a destination IP and port.  The list is applied to either the ingress (inbound) or egress (outbound) of a specific interface; meaning when traffic is coming into that interface (ingress) or leaving that interface (egress) then the device will filter each packet through the ACL.

It is important to understand how the data will flow through the network so that ACLs can be used most efficiently.  There are three types of ACLs, Standard, Extended, and Named:

  • Standard ACL (1 – 99 and 1300 – 1999): These ACLs filter only on the source address.  These need to be placed closest to the destination of the data flow, otherwise traffic destined for other destinations will be filtered by these rules as well.  We also see these types of ACLs used for management access into the device.  For instance, you can create an ACL with all of the source addresses that are allowed to SSH into your Cisco device.
  • Extended ACL (100 – 199 and 2000 – 2699): These ACLs are the most common as they filter based on both the source and destination address and port.  Cisco’s best practice guide suggests placing these ACLs closest to the source.  This will ensure any traffic not allowed by the ACL is blocked before it traverses the network.
  • Named ACL: A named ACL for all intense and purposes is an extended ACL but rather than assigning a number it uses a name.  This makes it much easier to manage a larger number of ACLs as the name could give a hint to what it is used for.

ACL Syntax

Whether your using Standard, Extended or Named ACLs the syntax is relatively the same.  The ACL rule will have a name or number to distinguish it from other ACL, it will include whether the rule should permit or deny traffic, it will say which IP protocol to use, and finally it will have the source and or destination address and port information.  The syntax for each type is as follows:

  • Standard: access-list access-list-number {permit | deny} {host source-host-address | source-subnet source-wildcard | any}
    Ex. access-list 10 permit host 10.1.10.1 or access-list 20 permit 10.1.10.0 0.0.0.255
  • Extended: access-list {access-list-number | name} extended {permit | deny} {ip | tcp | udp} {host source-host-address | source-subnet source-wildcard | any} eq {source-port | port-name} {host destination-host-address | destination-subnet source-wildcard | any} eq {destination-port | port-name}
    Ex.
    access-list 101 extended permit 10.1.10.0 0.0.0.255 host 10.1.20.5 eq snmp
    N
    ote that the eq and port information is optional, if it is excluded it is assumed all ports are filtered by the rule.

Applying ACLs

As I hinted at above there are two major ways an ACL is applied, on an interface or tied to a management protocol.  Here are to two ways to apply an ACL:

  • Apply to an interface: To apply an ACL to an interface in a Cisco device an access-group is used.  This group associates the access list with an interface.  The syntax is as follows:

ASA: access-group access_list {in | out} interface interface_name

IOS: Under the interface, type the command: ip access-group {number|name} {in|out}

  • Apply to a management protocol: Depending on the protocol, there are a few ways an ACL is applied.  For accessing the device via SSH or Telnet an access-class is used under the vty line.  For any other protocol the ACL name or number is referenced in the command. (check the command reference for the particular protocol for more details)  As stated before standard ACLs are used to specify what IP addresses have access to the device.  There isn’t a need for extended ACLs sense the protocol and destination are implied.  Here is the syntax for the access-class:
line vty 0 15
 access-class {list_name | list_number} {in | out}

Object Oriented ACLs

For firewalls and zone based routers (such as the Cisco 4000 series routers) the ACLs can be object oriented.  This means rather than specifying the IP or port information in the rule it can be specified in an object, and objects can then be grouped into object groups.  There are two types of objects, network objects which define IP addresses, and service object which define ports.  To create a network object use the syntax:

object network obj_name
 { host ip_addr | subnet net_addr net_mask | range ip_addr_1 ip_addr_2 | fqdn fully_qualified_domain_name }

This allows for great flexibility as you can define single hosts, full subnets, a range of ip addresses within a subnet, or if you defined a DNS server a fully qualified domain name.  Creating service objects is a similar process with its own caveats:

object service obj_name
 service { protocol | { icmp | icmp6 } [ icmp-type [ icmp_code ]] | { tcp | udp } [ source operator port ] [ destination operator port ]}

Just like the network object the service object allows for great flexibility as you can define the IP protocol and if this port is for a source or destination.

Object Groups

Defining objects are great, however if you have a large number of like objects that fit together in a single data flow you would still need to write a single ACL rule per object.  To fix this issue we have object groups.  As the name implies, an object group is a single object that represents multiple groups, so now all of those ACL rules can be condensed into a single rule.  Just like objects, object groups come in two types, network and service.  The network object group syntax is as follows:

object-group network grp_id
 network-object object name

or

object-group network grp_id
 network-object { host ipv4_address | ipv4_address mask | ipv6-address / prefix-length }

or

object-group network grp_id
 group-object group_id

With network object-groups you have three options.  You can either reference an object (option 1), reference a host IP address or subnet (option 2), or reference another object-group (option 3).  The syntax for service object groups are here:

object-group service grp_id
 service-object protocol

or

object-group service grp_id
 service-object { tcp | udp | tcp-udp } [ source operator number ] [ destination operator number ]

or

object-group service grp_id
 service-object { icmp | icmp6 } [ icmp_type [ icmp_code ]]

or

object-group service grp_id
 service-object object name

or

object-group service grp_id
 group-object group_id

With service object-groups there are a few more options than the network object-groups.  You can call out a protocol outright (option 1), define the source and destination ports over a specific IP protocol (option 2 and 3), reference a service object (option 4), and finally reference another service object-group (option 5).

Applying objects to ACLs

To apply an object or object group to an ACL is pretty easy.  Rather than specify the IP address and port information in the rule just add the keyword object or object-group then the name of the object or object-group you created.  This works for ports as well; using the same object, object-group keyword specify the service object or object-group.  This will not only help to condense the number of ACL rules but also make it easier to read what the rule is doing.  Here is an example of what this will look like:

object network DC01
host 10.1.10.5
!
object network 3RD-FLOOR-USERS
subnet 10.1.30.0 255.255.255.0
!
object-group network ALL-DC-SERVERS
group-object DC01
network-object host 10.1.10.8
!
object-group service DC-PORTS
service-object tcp destination ldap
service-object tcp destination ldaps
!
access-list 101 extended permit tcp object 3RD-FLOOR-USERS object-group ALL-DC-SERVERS object-group DC-PORTS

You can see how easy it is to figure out what this rule allows as well as allows four rules to be configured as one.  Now if you enter the command “show access-list access-list_number” you can see the device breaks the rule out into its individual components each with a hit counter for easy tracking.

As far as objects, object-groups, and how to apply them to ACLs I just scratched the surface.  I suggest reading Cisco’s guide on the subject: http://www.cisco.com/c/en/us/td/docs/security/asa/asa91/configuration/general/asa_91_general_config/acl_objects.html#74795

Common Mistakes

Now that we have a great understanding of what an ACL is and how to apply one, lets talk about some common mistakes that I have seen other engineers, including myself, make when configuring an ACL.

Not understanding the data flow

It is critical to understand how data flows through the network.  I have seen on more than a few occasions where rules are included in an ACL that don’t make logical sense to data flow.  A common example has to do with extended ACLs applied ingress on a server interface.  I have seen rules that have the source address differ from the subnet that is sourcing the traffic.  These rules will never be used because there isn’t ever a chance that legitimate traffic will be sourced outside its given subnet.

On the opposite end, we have ACLs that don’t include certain subnets off of interfaces that may be transit interfaces.  These are typical for say an interface that caries WAN traffic.  At the bottom of every ACL is an implicate deny so any traffic not specified in the ACL will get blocked.  An example I’ve seen usually revolves around SSL VPN traffic.  Many engineers forgot about SSL VPN traffic because it isn’t tied to an interface and obvious.

In general, having good documentation of your network can save you a major headache when trying to figure out the data flows and how they interact with ACLs.

Not looking where the rule is placed in the overall ACL

Beyond knowing how the data flows though the network, understanding how the ACL filters traffic is critical as well.  ACLs filter in a top down fashion, and when there is a match the device follows that rule.  This means that if a permit rule is placed below a deny rule that matches the same traffic, the traffic will be denied regardless of the permit rule below it.

This is where understanding the flow of the ACL is critical.  Whenever a group of engineers start haphazardly adding rules we tend to see this mistake happen.  By default an ACL is added to the bottom of the list.  To move a rule the command “line line-number” can be added after the ACL name or number.  This will place the ACL on the corresponding line.  Now by default each line when added without a line number has a line number in multiples of 10.  So the first line is line 10, the second line is line 20, ect.  This allows an engineer to add multiple rules between existing rules.

Creating redundant rules or objects

This mistake, unfortunately, can only be chocked up to laziness.  Not checking to see if a rule or object already exists is the start of what always ends with what I would call a rats nest ACL.  A common example is when there are a mixture of object oriented rules and non-object oriented rules.  At a first glance an engineer doesn’t see the IP addresses they need to allow a data flow so they add it to the ACL, however all that need to do was look at the objects to see that their data flow is already allowed.  This is a common scenario when troubleshooting an issue and someone suggests that maybe the firewall or router is blocking the traffic.

For ASA firewalls a good tool to check if a data flow is allowed is the packet tracer tool that is built into the ASA’s OS.  It is a great tool for troubleshooting not only ACLs on the ASA but also NAT traversals and inspects as well.  Check out the command reference here for more information: http://www.cisco.com/c/en/us/td/docs/security/asa/asa-command-reference/I-R/cmdref2/p1.html

On the same topic, adding a permit any any rule is also a common troubleshooting mistake engineers make.  Depending on company policy adding a permit any any rule to an ACL might work for troubleshooting purposes, however it should never be used as a permanent solution.  Depending on where it is placed a permit any any negates the need for the ACL in the first place and is usually considered a major security breach.  Using the packet tracer tool for troubleshooting and understanding the data flow is always the preferred method.

Not understanding stateful vs stateless devices

Finally, the last common mistake I have seen engineers make is not understand if they are on a device that is stateful or stateless.  A stateful device is a device that keeps a record of the data flows it allows in one direction so that it can identify and allow any return traffic.  By default most firewalls are stateful.

A stateless device is the opposite of a stateful device; it does not keep track of data flows.  This means the engineer must explicitly allow the return traffic on any ACLs the return traffic may hit on the device.  By default most routers and switches are stateless, however inspection can be turned on turning that device into a stateful device.

Hopefully at this point you should know more than enough about ACLs to give you confidence behind the console.  Please let me know if you like this article and if this has helped you in any way.

One thought on “Explanation of Access Control Lists

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s