This article provides information and commands concerning the following topics:
Access List Numbers
Although many different protocols can use access control lists (ACLs), the CCNA 200-301 certification exam is concerned only with IPv4 ACLs. The following chart shows some of the other protocols that can use ACLs.
1–99 or 1300–1999 | Standard IPv4 |
100–199 or 2000–2699 | Extended IPv4 |
IPv6 ACLs do not use numbers; IPv6 ACLs are configured using names only.
Using Wildcard Masks
When applied to an IP address, a wildcard mask identifies which addresses get matched to be applied to the permit or deny argument in an ACL statement. A wildcard mask can identify a single host, a range of hosts, a complete network or subnetwork, or even all possible addresses.
There are two rules when working with wildcard masks:
A 0 (zero) in a wildcard mask means to check the corresponding bit in the address for an exact match.
A 1 (one) in a wildcard mask means to ignore the corresponding bit in the address—can be either 1 or 0. In the examples, this is shown as x.
Example 1: 172.16.0.0 0.0.255.255
172.16.0.0 = 10101100.00010000.00000000.00000000
0.0.255.255 = 00000000.00000000.11111111.11111111
Result = 10101100.00010000.xxxxxxxx.xxxxxxxx
172.16.x.x (Anything between 172.16.0.0 and 172.16.255.255 matches the example statement)
An octet of all 0s means that the octet has to match exactly to the address. An octet of all 1s means that the octet can be ignored.
Example 2: 172.16.8.0 0.0.7.255
172.16.8.0 = 10101100.00010000.00001000.00000000
0.0.7.255 = 00000000.00000000.00000111.11111111
Result = 10101100.00010000.00001xxx.xxxxxxxx
00001xxx = 00001000 to 00001111 = 8–15
xxxxxxxx = 00000000 to 11111111 = 0–255
Anything between 172.16.8.0 and 172.16.15.255 matches the example statement
ACL Keywords
any | Used in place of 0.0.0.0 255.255.255.255, matches any address that it is compared against |
host | Used in place of 0.0.0.0 in the wildcard mask, matches only one specific address |
Creating Standard ACLs
Standard ACLs are the oldest type of ACL. They date back as early as Cisco IOS Release 8.3. Standard ACLs control traffic by comparing the source of the IP packets to the addresses configured in the ACL.
Each line in an ACL is called an access control entry (ACE). Many ACEs grouped together form a single ACL.
Router(config)# access-list 10 permit 172.16.0.0 0.0.255.255 | Read this line to say, “All packets with a source IP address of 172.16.x.x will be matched by the statement, and the packet will be exited from processing the rest of the ACL” access-list = ACL command 10 = Arbitrary number between 1 and 99, or 1300 and 1999, designating this as a standard IP ACL permit = Packets that match this statement will be allowed to continue 172.16.0.0 = Source IP address to be compared to 0.0.255.255 = Wildcard mask |
Router(config)# access-list 10 deny host 172.17.0.1 | Read this line to say, “All packets with a source IP address of 172.17.0.1 will be dropped and discarded” |
access-list | ACL command |
10 | Number between 1 and 99, or 1300 and 1999, designating this as a standard IP ACL |
deny | Packets that match this statement will be dropped and discarded |
host | Keyword |
172.17.0.1 | Specific host address |
Router(config)# access-list 10 permit any | Read this line to say, “All packets with any source IP address will be matched by the statement, and the packet will be exited from processing the rest of the ACL” |
access-list | ACL command |
10 | Number between 1 and 99, or 1300 and 1999, designating this as a standard IP ACL |
permit | Packets that match this statement will be allowed to continue |
any | Keyword to mean all IP addresses |
An implicit deny statement is assumed into every ACL. You cannot see it, but it states “deny everything not already matched by an ACE in the list.” This is always the last line of any ACL. If you want to defeat this implicit deny, put a permit any statement in your standard ACLs or a permit ip any any in your extended ACLs as the last line.
Applying Standard ACLs to an Interface
Router(config)# interface gigabitethernet 0/0 | Moves to interface configuration mode |
Router(config-if)# ip access-group 10 out | Takes all ACEs that are defined as being part of group 10 and applies them in an outbound manner. Packets leaving the router through interface gigabitethernet 0/0 will be checked |
Access lists can be applied in either an inbound direction (keyword in) or an outbound direction (keyword out). Best practice is to have ACLs applied in an outbound direction.
Not sure in which direction to apply an ACL? Look at the flow of packets. Do you want to filter packets as they are going in a router’s interface from an external source? Use the keyword in for this ACL. Do you want to filter packets before they go out of the router’s interface toward another device? Use the keyword out for this ACL.
Apply a standard ACL as close as possible to the destination network or device. You do not want packets with the same source IP address to be filtered out early and prevented from reaching a legitimate destination.
Verifying ACLs
Router# show ip interface | Displays any ACLs applied to that interface |
Router# show access-lists | Displays the contents of all ACLs on the router |
Router# show access-list access-list-number | Displays the contents of the ACL by the number specified |
Router# show access-list name | Displays the contents of the ACL by the name specified |
Router# show run | Displays all ACLs and interface assignments |
Removing ACLs
Router(config)# no access-list 10 | Removes all ACEs in ACL number 10 |
Creating Extended ACLs
Extended ACLs were also introduced in Cisco IOS Release 8.3. Extended ACLs control traffic by comparing the source and destination of the IP packets to the addresses configured in the ACL. Extended ACLs can also filter packets using protocol/port numbers for a more granular filter.
Router(config)# access-list 110 permit tcp 172.16.0.0 0.0.0.255 192.168.100.0 0.0.0.255 eq 80 | Read this line to say, “HTTP packets with a source IP address of 172.16.0.x will be matched by the statement, and the packet will be exited from processing the rest of the ACL” access-list = ACL command 110 = Number between 100 and 199, or 2000 and 2699, designating this as an extended IP ACL permit = Packets that match this statement will be allowed to continue tcp = Protocol must be TCP 172.16.0.0 = Source IP address to be compared to 0.0.0.255 = Wildcard mask for the source IP address 192.168.100.0 = Destination IP address to be compared to 0.0.0.255 = Wildcard mask for the destination IP address eq = Operand; means “equal to” 80 = Port 80, indicating HTTP traffic |
Router(config)# access-list 110 deny tcp any 192.168.100.7 0.0.0.0 eq 23 | Read this line to say, “Telnet packets with any source IP address will be dropped if they are addressed to specific host 192.168.100.7” access-list = ACL command 110 = Number between 100 and 199, or 2000 and 2699, designating this as an extended IP ACL deny = Packets that match this statement will be dropped and discarded tcp = Protocol must be TCP protocol any = Any source IP address 192.168.100.7 = Destination IP address to be compared to 0.0.0.0 = Wildcard mask; address must match exactly eq = Operand, means “equal to” 23 = Port 23, indicating Telnet traffic |
Applying Extended ACLs to an Interface
Router(config)# interface gigabitethernet 0/0 | Moves to interface configuration mode and takes all access list lines that are defined as being part of group 110 and applies them in an inbound manner. Packets going in gigabitethernet 0/0 will be checked |
Router(config-if)# ip access-group 110 in |
Access lists can be applied in either an inbound direction (keyword in) or an outbound direction (keyword out). Best practice for extended ACLs is to apply them in an inbound manner.
Only one access list can be applied per interface, per direction, per protocol.
Apply an extended ACL as close as possible to the source network or device. This ensures that packets that are intended to be dropped are not allowed to travel.
The established Keyword
The established keyword is an optional keyword that is used with the TCP protocol only. It indicates an established connection. A match occurs only if the TCP segment has the ACK or RST control bits set.
Router(config)# access-list 110 permit tcp 172.16.0.0 0.0.0.255 eq 80 192.168.100.0 0.0.0.255 established | Indicates an established connection |
The established keyword works only for TCP, not User Datagram Protocol (UDP).
Consider the following situation: You do not want hackers exploiting destination port 80 to access your network. Because you do not host a local web server (destination port 80), it is possible to block incoming (to your network) traffic on destination port 80, except that your internal users need web access. When they request a web page from the Internet, return traffic inbound on source port 80 must be allowed. The solution to this problem is to use the established command. The ACL allows the response to enter your network because it has the ACK bit set as a result of the initial request from inside your network. Requests from the outside world are blocked because the ACK bit is not set, but responses are allowed through.
The log Keyword
The log keyword is an optional parameter that causes an informational logging message about the packet matching the entry to be sent to the console. The log message includes the access list number, whether the packet was permitted or denied, the source address, the number of packets, and if appropriate, the user-defined cookie or router-generated hash value. The message is generated for the first packet that matches and then at 5-minute intervals, including the number of packets permitted or denied in the prior 5-minute interval.
ACL logging can be CPU intensive and can negatively affect other functions of the network device.
Router(config)# access-list 1 permit 172.16.10.0 0.0.0.255 log | Indicates that logging will be enabled on this ACE |
Router(config)# access-list 1 permit 172.16.10.0 0.0.0.255 log SampleUserValue | Indicates that logging will be enabled on this ACE. The word SampleUserValue will be appended to each syslog entry |
Router(config)# access-list 110 permit tcp 172.16.0.0 0.0.0.255 192.168.100.0 0.0.0.255 eq 80 log | Indicates that logging will be enabled on this ACE |
Router(config)# access-list 110 permit tcp 172.16.0.0 0.0.0.255 192.168.100.0 0.0.0.255 eq 80 log-input | Indicates that logging will be enabled on this input and will include the input interface and source MAC address or virtual circuit in the logging output |
Router(config)# access-list 110 permit tcp 172.16.0.0 0.0.0.255 192.168.100.0 0.0.0.255 eq 80 log-input SampleUserValue | Indicates that logging will be enabled on this ACE and will include the input interface and source MAC address or virtual circuit in the logging output. The word SampleUserValue will be appended to each syslog entry |
The level of messages logged to the console is controlled by the logging console command.
After you specify the log keyword (and the associated word argument) or the log-input keyword (and the associated word argument), you cannot specify any other keywords or settings for this command.
The log-input keyword (and the associated word argument) is only available in extended ACLs for IPv4 or IPv6 ACLs.
Creating Named ACLs
Router(config)# ip access-list extended serveraccess | Creates an extended named ACL called serveraccess and moves to named ACL configuration mode |
Router(config-ext-nacl)# permit tcp any host 131.108.101.99 eq smtp | Permits mail packets from any source to reach host 131.108.101.99 |
Router(config-ext-nacl)# permit udp any host 131.108.101.99 eq domain | Permits Domain Name System (DNS) packets from any source to reach host 131.108.101.99 |
Router(config-ext-nacl)# deny ip any any log | Denies all other packets from going anywhere. If any packets do get denied, this logs the results for you to look at later |
Router(config-ext-nacl)# exit | Returns to global configuration mode |
| Moves to interface configuration mode and applies this ACL to the gigabitethernet interface 0/0 in an outbound direction |
Router(config)# ip access-list standard teststandardacl | Creates a standard-named ACL called teststandardacl and moves to named ACL configuration mode |
Router(config-std-nacl)# permit host 192.168.1.11 | Permits packets from source address 192.168.1.11 |
Router(config-std-nacl)# exit | Returns to global configuration mode |
| Moves to interface configuration mode and applies this ACL to the gigabitethernet interface 0/1 in an outbound direction |
The prompt of the device changes according to whether the named ACL is standard (config-std-nacl) or extended (config-ext-nacl).
Using Sequence Numbers in Named ACLs
Router(config)# ip access-list extended serveraccess2 | Creates an extended-named ACL called serveraccess2 |
Router(config-ext-nacl)# 10 permit tcp any host 131.108.101.99 eq smtp | Uses sequence number 10 for this line |
Router(config-ext-nacl)# 20 permit udp any host 131.108.101.99 eq domain | Sequence number 20 will be applied after line 10 |
Router(config-ext-nacl)# 30 deny ip any any log | Sequence number 30 will be applied after line 20 |
Router(config-ext-nacl)# exit | Returns to global configuration mode |
Router(config)# interface gigabitethernet 0/0 | Moves to interface configuration mode |
Router(config-if)# ip access-group serveraccess2 out | Applies this ACL in an outbound direction |
Router(config-if)# exit | Returns to global configuration mode |
Router(config)# ip access-list extended serveraccess2 | Moves to named ACL configuration mode for the ACL serveraccess2 |
Router(config-ext-nacl)# 25 permit tcp any host 131.108.101.99 eq ftp | Sequence number 25 places this line after line 20 and before line 30 |
Router(config-ext-nacl)# exit | Returns to global configuration mode |
Sequence numbers are used to allow for easier editing of your ACLs. The preceding example used numbers 10, 20, and 30 in the ACL lines. If you had needed to add another line to this ACL, it would have previously been added after the last line—line 30. If you had needed a line to go closer to the top, you would have had to remove the entire ACL and then reapply it with the lines in the correct order. Now you can enter a new line with a sequence number (this example used number 25), placing it in the correct location.
The sequence-number argument was added in Cisco IOS Release 12.2(14)S. It was integrated into Cisco IOS Release 12.2(15)T.
Removing Specific Lines in Named ACLs Using Sequence Numbers
Router(config)# ip access-list extended serveraccess2 | Moves to named ACL configuration mode for the ACL serveraccess2 |
Router(config-ext-nacl)# no 20 | Removes line 20 from the list |
Router(config-ext-nacl)# exit | Returns to global configuration mode |
Sequence Number Tips
Sequence numbers start at 10 and increment by 10 for each line.
The maximum sequence number is 2147483647.
If you have an ACL that is so complex that it needs a number this big, I’d ask your boss for a raise.
If you forget to add a sequence number, the line is added to the end of the list and assigned a number that is 10 greater than the last sequence number.
If you enter an entry that matches an existing entry (except for the sequence number), no changes are made.
If the user enters a sequence number that is already present, an error message of “Duplicate sequence number” displays. You have to reenter the line with a new sequence number.
Sequence numbers are changed on a router reload to reflect the increment by 10 policy (see first tip in this section). If your ACL has numbers 10, 20, 30, 32, 40, 50, and 60 in it, on reload these numbers become 10, 20, 30, 40, 50, 60, 70.
If you want to change the numbering sequence of your ACLs to something other than incrementing by 10, use the global configuration command ip access-list resequence name/number start# increment#:
Router(config)# ip access-list resequence serveracces 1 2
This resets the ACL named serveraccess to start at 1 and increment by steps of 2 (1, 3, 5, 7, 9, and so on). The range for using this command is 1 to 2147483647.
Sequence numbers cannot be seen when using the Router# show running-config or Router# show startup-config command. To see sequence numbers, use one of the following commands:
Router# show access-lists Router# show access-lists list_name Router# show ip access-list Router# show ip access-list list_name
Including Comments About Entries in ACLs
Router(config)# access-list 10 remark only Neo has access | The remark command allows you to include a comment (limited to 100 characters) |
Router(config)# access-list 10 permit host 172.16.100.119 | Read this line to say, “Host 172.16.100.119 will be permitted through the internetwork” |
Router(config)# ip access-list extended telnetaccess | Creates a named ACL called telnetaccess and moves to named ACL configuration mode |
Router(config-ext-nacl)# remark do not let Agent Smith have telnet | The remark command allows you to include a comment (limited to 100 characters) |
Router(config-ext-nacl)# deny tcp host 172.16.100.153 any eq telnet | Read this line to say, “Deny this specific host Telnet access to anywhere in the internetwork” |
You can use the remark command in any of the IP numbered standard, IP numbered extended, or named IP ACLs.
You can use the remark command either before or after a permit or deny statement. Therefore, be consistent in your placement to avoid confusion about which line the remark statement is referring to.
Restricting Virtual Terminal Access
Router(config)# access-list 2 permit host 172.16.10.2 | Permits host from source address of 172.16.10.2 to telnet/SSH into this router based on where this ACL is applied |
Router(config)# access-list 2 permit 172.16.20.0 0.0.0.255 | Permits anyone from the 172.16.20.x address range to telnet/SSH into this router based on where this ACL is applied The implicit deny statement restricts anyone else from being permitted to telnet/SSH |
Router(config)# line vty 0 4 | Moves to vty line configuration mode |
Router(config-line)# access-class 2 in | Applies this ACL to all five vty virtual interfaces in an inbound direction |
When restricting access through Telnet, use the access-class command rather than the access-group command, which is used when applying an ACL to a physical interface.
Do not apply an ACL intending to restrict Telnet traffic on a physical interface. If you apply to a physical interface, all packets are compared to the ACL before it can continue on its path to its destination. This scenario can lead to a large reduction in router performance.
Tips for Configuring ACLs
Each statement in an ACL is known as an ACE.
Conversely, ACEs are commonly called ACL statements.
The type of ACL determines what is filtered.
Standard ACLs filter only on source IP address.
Extended ACLs filter on source IP address, destination IP address, protocol number, and port number.
Use only one ACL per interface, per protocol (IPv4 or IPv6), per direction.
Place your most specific statements at the top of the ACL. The most general statements should be at the bottom of the ACL.
The last test in any ACL is the implicit deny statement. You cannot see it, but it is there.
Every ACL must have at least one permit statement. Otherwise, you will deny everything.
Place extended ACLs as close as possible to the source network or device when applying ACLs to an interface.
Place standard ACLs as close as possible to the destination network or device when applying ACLs to an interface.
You can use numbers when creating a named ACL. The name you choose is the number. For example, ip access-list extended 150 creates an extended ACL named 150.
An ACL can filter traffic going through a router, depending on how the ACL is applied. Think of yourself as standing in the middle of the router.
Are you filtering traffic that is coming into the router toward you? If so, make the ACL an inbound one using the keyword in.
Are you filtering traffic that is going away from you and the router and toward another device? If so, make the ACL an outbound one using the keyword out.
Access lists that are applied to interfaces do not filter traffic that originates from that router.
When restricting access through Telnet, use the access-class command rather than the access-group command, which is used when applying an ACL to a physical interface.
IPv6 ACLs
ACLs can also be created in IPv6. The syntax for creating an IPv6 ACL is limited to named ACLs.
Router(config)# ipv6 access-list v6example | Creates an IPv6 ACL called v6example and moves to IPv6 ACL configuration mode |
Router(config-ipv6-acl)# permit tcp 2001:db8:300:201::/32 eq telnet any | Permits the specified IPv6 address to telnet to any destination |
Router(config-ipv6-acl)# deny tcp host 2001:db8:1::1 any log-input | Denies a specific IPv6 host. Attempts will be logged |
Router(config-ipv6-acl)# exit | Returns to global configuration mode |
Router(config)# interface gigabitethernet 0/0 | Moves to interface configuration mode |
Router(config-if)# ipv6 traffic-filter v6example out | Applies the IPv6 ACL named v6example to the interface in an outbound direction |
You use the traffic-filter keyword rather than the access-group keyword when assigning IPv6 ACLs to an interface.
Wildcard masks are not used in IPv6 ACLs. Instead, the prefix length is used.
You still use the access-class keyword to assign an IPv6 ACL to virtual terminal (vty) lines for restricting Telnet/SSH access.
Verifying IPv6 ACLs
R1# show ipv6 access-list | Displays the configured statements, their matches, and the sequence number of all access lists |
Configuration Examples: IPv4 ACLs
Figure 21-1 illustrates the network topology for the configuration that follows, which shows five ACL examples using the commands covered in this post.
Example 1: Write an ACL that prevents the 10.0 network from accessing the 40.0 network but allows everyone else to access the 40.0 network.
RedDeer(config)# access-list 10 deny 172.16.10.0 0.0.0.255 | The standard ACL denies the complete network for the complete TCP/IP suite of protocols |
RedDeer(config)# access-list 10 permit any | Defeats the implicit deny |
RedDeer(config)# interface gigabitethernet 0/0 | Moves to interface configuration mode |
RedDeer(config)# ip access-group 10 out | Applies ACL in an outbound direction |
Example 2: Write an ACL that states that 10.5 cannot access 50.7. Everyone else can.
Edmonton(config)# access list 115 deny ip host 172.16.10.5 host 172.16.50.7 | The extended ACL denies a specific host for the entire TCP/IP suite to a specific destination |
Edmonton(config)# access list 115 permit ip any any | All others are permitted through |
Edmonton(config)# interface gigabitethernet 0/0 | Moves to interface configuration mode |
Edmonton(config)# ip access-group 115 in | Applies the ACL in an inbound direction |
Example 3: Write an ACL that states that 10.5 can telnet to the Red Deer router. No one else can.
RedDeer(config)# access-list 20 permit host 172.16.10.5 | The standard ACL allows a specific host access. The implicit deny statement filters everyone else out |
RedDeer(config)# line vty 0 4 | Moves to vty configuration mode |
RedDeer(config-line)# access-class 20 in | Applies ACL 20 in an inbound direction. Remember to use access-class, not access-group |
Example 4: Write a named ACL that states that 20.163 can telnet to 70.2. No one else from 20.0 can telnet to 70.2. Any other host from any other subnet can connect to 70.2 using anything that is available.
Edmonton(config)# ip access-list extended serveraccess | Creates a named ACL and moves to named ACL configuration mode |
Edmonton(config-ext-nacl)# 10 permit tcp host 172.16.20.163 host 172.16.70.2 eq telnet | The specific host is permitted Telnet access to a specific destination |
Edmonton(config-ext-nacl)# 20 deny tcp 172.16.20.0 0.0.0.255 host 172.16.70.2 eq telnet | No other hosts are allowed to Telnet to the specified destination |
Edmonton(config-ext-nacl)# 30 permit ip any any | Defeats the implicit deny statement and allows all other traffic to pass through |
Edmonton(config-ext-nacl)# exit | Returns to global configuration mode |
Edmonton(config)# interface gigabitethernet 0/0 | Moves to interface configuration mode |
Edmonton(config)# ip access-group serveraccess out | Sets the ACL named serveraccess in an outbound direction on the interface |
Example 5: Write an ACL that states that hosts 50.1 to 50.63 are not allowed web access to 80.16. Hosts 50.64 to 50.254 are. Everyone else can do everything else.
RedDeer(config)# access-list 101 deny tcp 172.16.50.0 0.0.0.63 host 172.16.80.16 eq 80 | Creates an ACL that denies HTTP traffic from a range of hosts to a specific destination |
RedDeer(config)# access-list 101 permit ip any any | Defeats the implicit deny statement and allows all other traffic to pass through |
RedDeer(config)# interface gigabitethernet 0/1 | Moves to interface configuration mode |
RedDeer(config)# ip access-group 101 in | Applies the ACL in an inbound direction |
Configuration Examples: IPv6 ACLs
Figure 21-2 shows the network topology for the configuration that follows, which demonstrates how to configure IPv6 ACLs. Assume that all basic configurations are accurate. The objective here is to create an ACL that acts as a firewall allowing HTTP, HTTPS, DNS, and Internet Control Message Protocol (ICMP) traffic to return from the Internet.
R1(config)# ipv6 access-list FIREWALL | Creates a named extended IPv6 access list called FIREWALL and moves to IPv6 access list configuration mode |
R1(config-ipv6-acl)# permit tcp any eq www any established | Permits HTTP traffic to return to the corporate LAN from the Internet if that traffic was originally sourced from the corporate LAN |
R1(config-ipv6-acl)# permit tcp any eq 443 any established | Permits HTTPS traffic to return to the corporate LAN from the Internet if that traffic was originally sourced from the corporate LAN |
R1(config-ipv6-acl)# permit udp any eq domain any | Permits DNS responses to return to the corporate LAN from the Internet |
R1(config-ipv6-acl)# permit icmp any any echo-reply | Permits ICMP ping responses to return to the corporate LAN from the Internet |
R1(config-ipv6-acl)# permit icmp any any packet-too-big | Permits ICMP Packet Too Big messages to return to the corporate LAN from the Internet In IPv6, maximum transmission unit (MTU) discovery has moved from the router to the hosts. It is important to allow Packet Too Big messages to flow through the router to allow hosts to detect whether fragmentation is required |
R1(config-ipv6-acl)# exit | Returns to global configuration mode |
R1(config)# interface gigabitethernet0/0 | Enters GigabitEthernet0/0 interface configuration mode |
R1(config-if)# ipv6 traffic-filter FIREWALL in | Applies the IPv6 access list named FIREWALL to the interface in the inbound direction |
The “implicit deny” rule has changed for IPv6 access lists to take into account the importance of the Neighbor Discovery Protocol (NDP). NDP is to IPv6 what Address Resolution Protocol (ARP) is to IPv4, so naturally the protocol should not be disrupted. That is the reason two additional implicit statements have been added before the “implicit deny” statement at the end of each IPv6 ACL.
These implicit rules are as follows:
permit icmp any any nd-na permit icmp any any nd-ns deny ipv6 any any
It is important to understand that any explicit deny ipv6 any any statement overrides all three implicit statements, which can lead to problems because NDP traffic is blocked.