Notes / Module 14
Access Control Lists
An ACL is an ordered list of permit and deny statements a router checks top-down, first match wins, with a hidden deny at the end. Expect wildcard masks, standard versus extended, placement and writing the IOS commands.
14.1What an ACL is, and standard versus extended
An ACL (access control list) is a series of IOS commands that filter packets by information in the packet header. A router has no ACLs by default. Once an ACL is applied to an interface, the router also evaluates every packet passing through it to decide whether it may be forwarded.
- ACE
- Access control entry: one permit or deny statement in the list, also called an ACL statement.
- Packet filtering
- Comparing a packet against each ACE in sequential order to permit or deny it. Works at Layer 3 and Layer 4.
- Implicit deny
- The hidden last statement that denies everything not matched earlier.
- Limit traffic to improve performance: block video, or restrict routing updates to known sources.
- Traffic flow control: for example, only authorized users reach the Human Resources network.
- Basic security: permit email but deny Telnet.
- Filter by traffic type: limit FTP or HTTP to user groups.
- Screen hosts to permit or deny access to services.
- Priority: with QoS, identify voice traffic and process it first.
- ACLs also select traffic for NAT, QoS and VPNs.
| Standard ACL | Extended ACL | |
|---|---|---|
| Filters on | Source IPv4 address only (Layer 3) | Source and/or destination IPv4 address (Layer 3), plus protocol and TCP/UDP ports (Layer 4) |
| Numbers | 1 to 99 and 1300 to 1999 | 100 to 199 and 2000 to 2699 |
| Named | ip access-list standard NAME | ip access-list extended NAME |
Named ACLs are the preferred method. A name tells you the purpose (FTP-FILTER beats ACL 100), and entries can be added or deleted inside the ACL. Names are alphanumeric, with no spaces or punctuation, case sensitive and unique. CAPITAL LETTERS are suggested so the names stand out in the running-config and you do not create two ACLs that differ only by capitalization.
R1(config)# access-list ? <1-99> IP standard access list <100-199> IP extended access list <1300-1999> IP standard access list (expanded range) <2000-2699> IP extended access list (expanded range)
R1(config)# ip access-list extended FTP-FILTER R1(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 any eq ftp R1(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 any eq ftp-data
14.1How a router processes an ACL
A router checks an ACL top-down and stops at the first match. If nothing matches, the implicit deny drops the packet. For an inbound standard ACL the steps are below.
- The router extracts the source IPv4 address from the packet header.
- It starts at the top and compares that address to each ACE in order.
- On a match it carries out the permit or deny, and the remaining ACEs are not examined.
- If no ACE matches, the packet is discarded by the implicit deny.
Try it
Send a packet from
- 10 deny 192.168.10.10 0.0.0.0match — stop
- 20 permit 192.168.10.0 0.0.0.255never read
- 30 permit 192.168.20.0 0.0.0.255never read
- deny any (implicit — not shown)never read
Result: dropped by line 10; lines after it are never read.
- The implicit deny is applied to every ACL but not displayed in the configuration.
- An ACL needs at least one permit, otherwise all traffic is denied.
- Inbound ACL: filters before the routing lookup, so discarded packets save the lookup. Best when the network on that interface is the only source that needs examining.
- Outbound ACL: filters after routing, whichever inbound interface the packet used. Best when one filter serves packets from several inbound interfaces leaving through the same outbound interface.
- ACLs do not act on packets the router itself originates.
14.2Wildcard masks
A wildcard mask is a 32-bit mask that tells an ACE which bits of an address to check. It works like a subnet mask but with the meaning reversed. OSPF also uses wildcard masks.
| Wildcard bit | Meaning |
|---|---|
| 0 | Match the corresponding bit of the address |
| 1 | Ignore the corresponding bit of the address |
wildcard = 255.255.255.255 − subnet mask
- each octet
- Subtracted separately from 255.
- bit 0
- Must match.
- bit 1
- Ignore.
Try it
mask11111111.11111111.11111111.11100000
wildcard00000000.00000000.00000000.00011111
0 = this bit must match · 1 = ignore this bit
| Wildcard | Last octet in binary | Meaning |
|---|---|---|
| 0.0.0.0 | 00000000 | Match all octets (one host) |
| 0.0.0.15 | 00001111 | Match first three octets and the four leftmost bits of the last; ignore the last 4 bits |
| 0.0.0.63 | 00111111 | Match first three octets and the two leftmost bits of the last; ignore the last 6 bits |
| 0.0.0.252 | 11111100 | Match first three octets; ignore the six leftmost bits of the last; match the last two |
| 0.0.0.255 | 11111111 | Match first three octets; ignore the last octet |
| To match | Wildcard | Example ACE |
|---|---|---|
| One host | 0.0.0.0 | access-list 10 permit 192.168.1.1 0.0.0.0 |
| A /24 subnet | 0.0.0.255 | access-list 10 permit 192.168.1.0 0.0.0.255 |
| A /16 network (10.10.0.0) | 0.0.255.255 | network 10.10.0.0 with 0.0.255.255 |
| A range, 192.168.16.0 to 192.168.31.0 (as /20) | 0.0.15.255 | access-list 10 permit 192.168.16.0 0.0.15.255 |
| Prefix | Subnet mask | Wildcard |
|---|---|---|
| /24 | 255.255.255.0 | 0.0.0.255 |
| /23 | 255.255.254.0 | 0.0.1.255 |
| /20 | 255.255.240.0 | 0.0.15.255 |
| /27 | 255.255.255.224 | 0.0.0.31 |
| /28 | 255.255.255.240 | 0.0.0.15 |
| /30 | 255.255.255.252 | 0.0.0.3 |
Worked example
Wildcard mask for 172.22.34.64/27
- 1A /27 subnet mask is 255.255.255.224.
- 2Subtract each octet from 255: 255−255 = 0, 255−255 = 0, 255−255 = 0, 255−224 = 31.
- 3The wildcard mask is 0.0.0.31.
- 4The ACE source is
172.22.34.64 0.0.0.31: the first three octets and the network bits of the last must match; the last 5 bits are ignored.
Worked example
Summarizing two networks
- 1Permit only 192.168.10.0 and 192.168.11.0.
- 2Summarize as 192.168.10.0/23, subnet mask 255.255.254.0.
- 3255.255.255.255 − 255.255.254.0 = 0.0.1.255.
- 4ACE:
access-list 10 permit 192.168.10.0 0.0.1.255.
| Keyword | Equals | Meaning |
|---|---|---|
host 192.168.1.10 | 192.168.1.10 0.0.0.0 | One exact host; all bits must match |
any | 0.0.0.0 255.255.255.255 | Every address; ignore the whole address |
R1(config)# access-list 10 permit 192.168.10.10 0.0.0.0 R1(config)# access-list 11 permit 0.0.0.0 255.255.255.255 R1(config)# access-list 10 permit host 192.168.10.10 R1(config)# access-list 11 permit any
14.3Configuring standard IPv4 ACLs
Plan every ACL first, especially ones with many ACEs. Write the policy and the IOS commands in a text editor, add remarks to document it, paste it onto the device, then test thoroughly that it applies the policy.
Router(config)# access-list access-list-number {deny | permit | remark text} source [source-wildcard] [log]
Router(config)# no access-list access-list-number- access-list-number
- 1 to 99 or 1300 to 1999.
- source
- Network or host to filter.
anyis all networks;host ip-address, or just the address, is one host. - source-wildcard
- Optional. If omitted,
0.0.0.0is assumed (one host). - remark text
- Optional documentation, limited to 100 characters.
- log
- Optional. Generates a message on a match (ACL number, permit or deny, source, packet count) for the first matched packet. Can be CPU intensive; use for troubleshooting or security only.
R1(config)# ip access-list standard NO-ACCESS R1(config-std-nacl)# deny host 192.168.11.10 R1(config-std-nacl)# permit any R1(config-std-nacl)# exit R1(config)# interface g0/0 R1(config-if)# ip access-group NO-ACCESS out
- Remove a named standard ACL with
no ip access-list standard name. - In named mode you do not repeat the
ip access-listcommand for each ACE; you just typepermitordeny. - Without a wildcard,
access-list 10 permit 192.168.1.1means that one host.
14.3Configuring extended IPv4 ACLs
Extended ACLs follow the same steps as standard ones (configure, then activate on an interface) but the syntax has protocol, destination and ports.
Router(config)# access-list access-list-number {deny | permit | remark text} protocol source source-wildcard [operator {port}] destination destination-wildcard [operator {port}] [established] [log]
Router(config)# no access-list access-list-number- protocol: name or number; common keywords are
ip,tcp,udp,icmp.ipmatches all IP protocols. If a protocol has no keyword, use its number: ICMP is 1, TCP is 6, UDP is 17. - operator:
lt,gt,eq,neqcompare source or destination ports.eqmatches one specific application port. - port: a number or a name. Use the number when no keyword exists, such as SSH (22) and HTTPS (443).
- established: TCP only.
- Statements stay in the order you entered them; the standard-ACL ordering logic does not apply to extended ACLs.
- Selecting
tcpshows TCP port options,udpshows UDP ones,icmpshows ICMP messages. Use?for help.
| Service | Protocol and port | ACL keyword |
|---|---|---|
| FTP | TCP 20, 21 | ftp-data, ftp |
| SSH | TCP 22 | 22 |
| Telnet | TCP 23 | telnet |
| SMTP | TCP 25 | smtp |
| DNS | UDP/TCP 53 | domain |
| HTTP | TCP 80 | www |
| POP3 | TCP 110 | pop3 |
| HTTPS | TCP 443 | 443 |
| SNMP | UDP 161 | snmp |
R1(config)# access-list 100 permit tcp any any eq www R1(config)# !or... R1(config)# access-list 100 permit tcp any any eq 80 R1(config)# access-list 100 permit tcp any any eq 22 R1(config)# access-list 100 permit tcp any any eq 443
The `established` keyword gives a basic stateful firewall: inside hosts can start connections out and replies come back in, but traffic started from outside is denied. A match happens when the returning TCP segment has the ACK or RST flag set, meaning it belongs to an existing connection. Without it, anything from the web server would be permitted.
R1(config)# ip access-list extended SURFING R1(config-ext-nacl)# remark Permits inside HTTP and HTTPS traffic R1(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 any eq 80 R1(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 any eq 443 R1(config-ext-nacl)# exit R1(config)# ip access-list extended BROWSING R1(config-ext-nacl)# remark Only permit returning HTTP and HTTPS traffic R1(config-ext-nacl)# permit tcp any 192.168.10.0 0.0.0.255 established R1(config)# interface g0/0/0 R1(config-if)# ip access-group SURFING in R1(config-if)# ip access-group BROWSING out
- Apply with
ip access-group {number | name} {in | out}, same command as for standard ACLs. - To remove: first
no ip access-groupon the interface (the ACL is still configured on the router), thenno access-listglobally.
14.4Modifying an ACL
There are two methods to fix an ACL: the text editor method and the sequence number method. The module's example: ACL 1 was typed with 19.168.10.10 instead of 192.168.10.10.
- Copy the ACL from the running configuration into a text editor.
- Make the changes.
- Remove the old ACL on the router. Skip this and pasting only appends to the old ACEs.
- Paste the corrected ACL back in global configuration mode.
R1(config)# no access-list 1 R1(config)# access-list 1 deny 192.168.10.10 R1(config)# access-list 1 permit 192.168.10.0 0.0.0.255
Sequence numbers are assigned automatically when an ACE is entered. show access-lists displays them; show running-config does not. An existing sequence number cannot be overwritten, so delete the bad line first, then add the correct one with that number.
R1# show access-lists
Standard IP access list 1
10 deny 19.168.10.10
20 permit 192.168.10.0, wildcard bits 0.0.0.255
R1# conf t
R1(config)# ip access-list standard 1
R1(config-std-nacl)# no 10
R1(config-std-nacl)# 10 deny host 192.168.10.10
R1(config-std-nacl)# end
R1# show access-lists14.5Applying ACLs and the guidelines
Router(config-if)# ip access-group {acl-# | name} {in | out}
Router(config-line)# ip access-class {acl-# | name} {in | out}- Create the ACL globally, then apply it.
- Statement order matters: top-down, and the ACL is exited at the first match.
- Filter from the most specific to the most generic: deny a specific host, then permit all other hosts.
- Only one ACL per interface, per protocol, per direction.
- New statements for an existing ACL go to the bottom by default.
- Router-generated packets are not filtered by outbound ACLs.
- Place standard ACLs as close to the destination as possible; extended as close to the source as possible.
R1(config)# ip access-list standard VTY_ACCESS R1(config-std-nacl)# permit 192.168.10.10 log R1(config-std-nacl)# deny any R1(config-std-nacl)# exit R1(config)# line vty 0 4 R1(config-line)# access-class VTY_ACCESS in R1(config-line)# end
The log keyword seriously affects the performance of a router or switch. Use it only when the network is under attack and you are trying to identify the attacker.
14.5Where to place ACLs
Place every ACL where it is most efficient. Standard ACLs go close to the destination, because they see only the source address: at the source they would permit or deny that source whatever the destination. Extended ACLs go close to the source, so unwanted traffic is dropped before it crosses the network.
Extended checks source, destination, protocol and port, so it can drop exactly the unwanted traffic before it crosses the network.
Standard sees only the source. Put on R1 it would cut Net A off from everything beyond R1, not just the server.
| Factor | Why it matters |
|---|---|
| Extent of organizational control | You can only place ACLs on devices you control, so you need control of the source or destination network. |
| Bandwidth of the networks involved | Filtering at the source stops bandwidth-consuming traffic being sent at all. |
| Ease of configuration | A destination ACL is easier, but traffic uses bandwidth first. Extended ACLs at the source save bandwidth but may be needed on several routers. |
Worked example
Standard ACL: block 192.168.10.0/24 from 192.168.30.0/24
- 1The policy names only a source network, so a standard ACL is enough.
- 2Place it near the destination, on router R3.
- 3R3 S0/1/1 inbound would also block the .10 network from reaching 192.168.31.0/24, which the policy did not ask for.
- 4R3 G0/0/0 outbound affects only traffic toward the .30 network; .10 traffic can still reach .31.
- 5Answer: standard ACL on R3 G0/0/0, outbound.
Worked example
Extended ACL: deny Telnet and FTP from 192.168.11.0/24 to 192.168.30.0/24
- 1The policy names source, destination and services (Telnet, FTP), so an extended ACL is needed, and all other traffic must be permitted.
- 2Place it close to the source, on R1; an ACL on R3 would work but the organization does not control R3 and unwanted traffic would cross the whole network first.
- 3R1 S0/1/0 outbound examines all packets leaving R1, including those from 192.168.10.0/24.
- 4R1 G0/0/1 inbound examines only packets from 192.168.11.0/24.
- 5Answer: extended ACL on R1 G0/0/1, inbound, ending with a permit for all other traffic.
14.6Mitigating attacks with ACLs
ACLs help against IP address spoofing (inserting a custom IP header with a different source address to hide identity) and DoS attacks, since most DoS attacks use spoofing. An internet-facing interface should never accept these as source addresses.
- All-zeros address and broadcast addresses.
- Local host
127.0.0.0/8. - APIPA
169.254.0.0/16. - Reserved private (RFC 1918) addresses.
- IP multicast
224.0.0.0/4. - An internal LAN interface should accept only sources from its own network.
R1(config)# access-list 150 deny ip host 0.0.0.0 any R1(config)# access-list 150 deny ip 10.0.0.0 0.255.255.255 any R1(config)# access-list 150 deny ip 127.0.0.0 0.255.255.255 any R1(config)# access-list 150 deny ip 172.16.0.0 0.15.255.255 any R1(config)# access-list 150 deny ip 192.168.0.0 0.0.255.255 any R1(config)# access-list 150 deny ip 224.0.0.0 15.255.255.255 any R1(config)# access-list 150 deny ip host 255.255.255.255 any R1(config)# access-list 105 permit ip 192.168.1.0 0.0.0.255 any
Permit only what is needed through a firewall. DNS, SMTP and FTP often must pass; SSH, syslog and SNMP may be needed for remote administration. Control and monitor them, because exploiting them creates vulnerabilities.
R1(config)# access-list 180 permit udp any host 192.168.20.2 eq domain R1(config)# access-list 180 permit tcp any host 192.168.20.2 eq smtp R1(config)# access-list 180 permit tcp any host 192.168.20.2 eq ftp R1(config)# access-list 180 permit tcp host 200.5.5.5 host 10.0.1.1 eq 22 R1(config)# access-list 180 permit udp host 200.5.5.5 host 10.0.1.1 eq syslog R1(config)# access-list 180 permit udp host 200.5.5.5 host 10.0.1.1 eq snmptrap
ICMP: echo pings can map subnets and hosts and flood a network; redirects can alter host routing tables. Block both inbound. Allow certain messages in and out, and block all other ICMP types outbound.
| Direction | Allow | Why |
|---|---|---|
| Inbound | Echo reply | Lets users ping external hosts |
| Inbound | Source quench | Asks the sender to slow down |
| Inbound | Unreachable | Generated for packets an ACL administratively denied |
| Outbound | Echo | Lets users ping external hosts |
| Outbound | Parameter problem | Informs a host of packet header problems |
| Outbound | Packet too big | Enables MTU discovery |
| Outbound | Source quench | Throttles traffic when necessary |
R1(config)# access-list 112 permit icmp any any echo-reply R1(config)# access-list 112 permit icmp any any source-quench R1(config)# access-list 112 permit icmp any any unreachable R1(config)# access-list 112 deny icmp any any R1(config)# access-list 112 permit ip any any
SNMP: if needed, apply interface ACLs to filter SNMP from unauthorized systems (a spoofed permitted source can still get through). The most effective prevention is to disable it when not required.
Router(config)# no snmp-server
14.7IPv6 ACLs
IPv4 and IPv6 coexist during the transition, which opens holes. Attackers can use dual-stack hosts, rogue NDP messages and tunneling. For example, Teredo tunneling embeds IPv6 packets inside IPv4 UDP packets, so an IPv4 firewall sees and allows the UDP without inspecting the IPv6. Filtering at the edge, including IPv6 ACLs, is part of the answer.
- There is no standard IPv6 ACL; every IPv6 ACL is named and works like an extended IPv4 ACL, filtering on source and destination addresses.
- Create with
ipv6 access-list name, apply to an interface withipv6 traffic-filter. - There is no wildcard mask: use a prefix and prefix length,
any(::/0) orhost. - Every IPv6 ACL ends with an implicit
deny ipv6 any any, preceded by implicit permits for neighbor discovery (NA and NS), which NDP needs. - If you add your own
deny ipv6 any any, permitnd-naandnd-nsfirst or NDP is disabled.
R1(config)# ipv6 access-list LAN_ONLY R1(config-ipv6-acl)# permit 2001:db8:1:1::/64 any R1(config-ipv6-acl)# permit icmp any any nd-na R1(config-ipv6-acl)# permit icmp any any nd-ns R1(config-ipv6-acl)# deny ipv6 any any R1(config-ipv6-acl)# end R1# show ipv6 access-list
14 labPacket Tracer ACL lab: workflow and numbered listings
Every ACL lab follows four moves: plan the policy, write the statements, apply them to the right interface and direction, then verify with pings and show access-lists.
- Ping between all devices first to confirm full connectivity.
- Read the policy: who is blocked from what, and is everything else allowed?
- Choose the type: source only is standard; source plus destination, protocol or port is extended.
- Choose placement: standard near the destination, extended near the source. Decide in or out from the router's point of view.
- Write the statements, most specific first. Add
permit any(standard) orpermit ip any any(extended) if all other traffic should pass. - Run
show access-listsbefore applying to check order. - Apply with
ip access-group, then test the pings that should pass and the ones that should fail.
Worked example
Standard or extended, and where?
- 1Policy: 192.168.11.0/24 may not reach the WebServer network; everything else is allowed.
- 2It names only a source, so it is standard.
- 3Standard goes near the destination: R2, outbound toward the server.
- 4Deny the network first, then add
permit anyor the implicit deny blocks everyone.
R2(config)# access-list 1 deny 192.168.11.0 0.0.0.255 R2(config)# access-list 1 permit any R2(config)# interface GigabitEthernet0/0 R2(config-if)# ip access-group 1 out R2# show access-lists
R1(config)# ip access-list standard File_Server_Restrictions R1(config-std-nacl)# permit host 192.168.20.4 R1(config-std-nacl)# permit host 192.168.100.100 R1(config-std-nacl)# deny any R1(config)# interface GigabitEthernet0/1 R1(config-if)# ip access-group File_Server_Restrictions out
Extended scenario: the PC1 LAN (172.22.34.64/27, wildcard 0.0.0.31) gets FTP only, the PC2 LAN (172.22.34.96/28, wildcard 0.0.0.15) gets web only, and both can ping the server 172.22.34.62. Each ACL is applied inbound on the interface facing that LAN.
R1(config)# access-list 100 permit tcp 172.22.34.64 0.0.0.31 host 172.22.34.62 eq ftp R1(config)# access-list 100 permit icmp 172.22.34.64 0.0.0.31 host 172.22.34.62 R1(config)# interface GigabitEthernet0/0 R1(config-if)# ip access-group 100 in
R1(config)# ip access-list extended HTTP_ONLY R1(config-ext-nacl)# permit tcp 172.22.34.96 0.0.0.15 host 172.22.34.62 eq www R1(config-ext-nacl)# permit icmp 172.22.34.96 0.0.0.15 host 172.22.34.62 R1(config)# interface GigabitEthernet0/1 R1(config-if)# ip access-group HTTP_ONLY in
14 labLab: editing, VTY lines, IPv6, verifying and common mistakes
R1(config)# ip access-list standard 1 R1(config-std-nacl)# no 10 R1(config-std-nacl)# 10 deny host 192.168.10.10 R1(config)# no access-list 1 R1(config-if)# no ip access-group 1 out R1(config)# line vty 0 4 R1(config-line)# access-class 1 in
access-class filters remote management (Telnet/SSH) sessions; access-group filters traffic through an interface.
R1(config)# ipv6 access-list BLOCK_HTTP R1(config-ipv6-acl)# deny tcp any host 2001:db8:1:30::30 eq www R1(config-ipv6-acl)# permit ipv6 any any R1(config)# interface GigabitEthernet0/1 R1(config-if)# ipv6 traffic-filter BLOCK_HTTP in
| Command | Shows |
|---|---|
show access-lists | Every ACL, its sequence numbers and match counts |
show ip interface g0/0 | Which ACL is applied, and in which direction |
show running-config | Full ACL and interface config (no sequence numbers) |
clear access-list counters | Resets match counts before testing |
show ipv6 access-list | IPv6 ACLs with sequence numbers |
- Forgetting
permit any, so the implicit deny blocks all other traffic. - Applying to the wrong interface or direction; think from the router's view of where the packet enters or leaves.
- Using a subnet mask instead of a wildcard (0.0.0.255, not 255.255.255.0).
- Putting a general statement above a specific one, so the specific one never matches.
- Using
access-groupon VTY lines instead ofaccess-class.
Check yourself
Answer these out loud, without scrolling up. Any you can't, reread that section — then let the deck mark you.
- 1.What does an ACL do when a packet matches no ACE, and why must an ACL have at least one permit?
- 2.Give the number ranges for standard and extended ACLs, and what each type can filter on.
- 3.Work out the wildcard mask for a /27 and write the ACE that matches 172.22.34.64/27.
- 4.Where do standard and extended ACLs go, and why? Place a standard ACL to block 192.168.10.0/24 from 192.168.30.0/24.
- 5.What is the difference between ip access-group and access-class?
- 6.How do you edit line 10 of a standard ACL using sequence numbers, and how do you remove an applied ACL completely?