I configured standard and extended ACLs on Cisco IOS to enforce least-privilege traffic flow between segments, ordering rules so specific permits precede the implicit deny. Correct sequencing turned ACLs into a precise filter rather than an accidental black hole.

Objective & Context

ACLs filter by matching packets top-down against ordered entries with an implicit deny at the end. This lab uses standard ACLs (source only) and extended ACLs (source, destination, protocol, port) to enforce segment policy, mirroring host firewall intent at the network layer.

Learning Objectives

  • Write standard and extended Cisco ACLs with correct syntax and wildcard masks.
  • Order ACL entries so specific permits precede general denies.
  • Apply ACLs to interfaces in the correct direction (inbound vs outbound).
  • Verify enforcement with per-entry hit counters and deny logging.
  • Diagnose common ACL misconfigurations such as accidental black holes.

Environment & Prerequisites

Prerequisites

  • Cisco router/L3 switch (or emulator) with multiple subnets.
  • Defined allow/deny policy between segments.
  • Understanding of wildcard masks.
  • Cisco IOS router or Layer 3 switch, physical or emulated (Cisco Packet Tracer, EVE-NG, or GNS3).
  • Two or more subnets to filter between, for example 192.168.20.0/24 and 192.168.30.0/24.
  • A written allow/deny policy: which flows are permitted between segments.
  • Understanding of wildcard masks (the inverse of subnet masks).
  • Privileged EXEC access to the device.

Step-by-Step Execution

1. Define an extended ACL

ip access-list extended SEG-POLICY ; permit tcp 192.168.20.0 0.0.0.255 host 192.168.30.10 eq 443 ; deny ip any any log

Expected output:

R1(config)# ip access-list extended SEG-POLICY
R1(config-ext-nacl)# permit tcp 192.168.20.0 0.0.0.255 host 192.168.30.10 eq 443
R1(config-ext-nacl)# deny ip any any log
R1(config-ext-nacl)# exit
R1(config)#

What this teaches: the named extended ACL matches on protocol, source, destination, and port, and rule order decides which packets reach the implicit deny.

Note: eq 443 matches the destination port by default (the port after the destination address). A standard ACL example for comparison matches source only:

ip access-list standard MGMT-ONLY ; permit 192.168.10.0 0.0.0.255 ; deny any log

Standard ACLs belong closest to the destination (they only see the source), while extended ACLs belong closest to the source (they see the full 5-tuple). Applying them backwards is the classic placement error.

2. Apply it to an interface direction

interface Gi0/1 ; ip access-group SEG-POLICY in

Expected output:

R1(config)# interface Gi0/1
R1(config-if)# ip access-group SEG-POLICY in
R1(config-if)# exit
R1(config)#

What this teaches: an ACL filters nothing until it is attached, and the direction (in vs out) decides which packets it inspects.

3. Verify hit counts

show access-lists SEG-POLICY

Expected output:

10 permit tcp 192.168.20.0 0.0.0.255 host 192.168.30.10 eq 443 (142 matches)
20 deny ip any any log (37 matches)

What this teaches: per-entry match counters prove which rule handled each packet, turning policy review into verifiable evidence.

How It Works

An access control list is an ordered set of match criteria evaluated top-down against every packet. The first entry whose criteria match decides the packet's fate: permit forwards it, deny drops it. Because evaluation stops at the first match, a broad deny placed above a narrow permit silently blocks traffic the permit was meant to allow.

Every ACL ends with an implicit deny that matches everything, so an ACL with no explicit permit blocks all traffic. Extended ACLs match on protocol, source and destination addresses, and optionally source and destination ports, while standard ACLs match only on the source address. Wildcard masks invert subnet masks: a 0 bit means the address bit must match, a 1 bit means it is ignored.

Direction determines which packets the ACL sees. An inbound ACL on Gi0/1 inspects packets arriving on that interface before routing; an outbound ACL inspects packets leaving after the routing decision. The same rule set can behave completely differently depending on where and in which direction it is applied, which is why verification with counters matters more than intent.

Validation & Testing

Send permitted and denied flows and confirm hit counters increment on the expected entries, with denied traffic logged. Pass criteria: only the explicitly permitted flow passes and the implicit deny catches everything else.

Troubleshooting

SymptomLikely causeFix
All traffic blocked after applying the ACLThe implicit deny is catching traffic with no matching permit above itAdd explicit permit entries for required flows before the deny, then re-apply the ACL
A permitted flow is still blockedThe ACL is applied in the wrong direction on the interfaceRun show ip interface to check the access-group direction and move the ACL to the correct one
Hit counters stay at zero on every entryThe ACL is on the wrong interface or traffic takes a different pathTrace the actual packet path and confirm the ACL sits on an interface the traffic crosses
Deny log floods the consoleThe log keyword on a high-volume deny entry generates a message per packetRemove log from the busy deny entry or redirect logging to a syslog server
Wildcard mask matches the wrong hostsWildcard masks are confused with subnet masks (they are inverses)Recompute the mask as 255.255.255.255 minus the subnet mask
Advanced: Troubleshooting
  • Everything blocked: a too-early deny or missing permit before the implicit deny; reorder entries.
  • Wrong direction: apply inbound vs outbound on the correct interface relative to traffic.
  • Wildcard mask errors: remember masks are inverse of subnet masks.

Key Results

  • Enforced least-privilege flow with a single permitted service path.
  • Logged 100% of denied traffic for audit via the deny-log entry.
  • Validated rule ordering through per-entry hit counters.
  • Aligned network-layer filtering with host firewall policy.

Key Takeaways

  • Order rules from most specific to most general, ending with an explicit deny for visibility.
  • Direction and placement matter as much as the rules themselves: test from both sides.
  • Log denies during testing, then tune logging so it does not flood the console.
  • Verify with per-entry counters rather than assuming the policy works.

Practice Challenges

Challenge 1: Add a time-based restriction

Goal: Permit the HTTPS flow only during business hours (08:00 to 18:00, weekdays) while keeping the deny-log entry.

Hint: Create a time-range with the time-range command and reference it in the permit entry.

Challenge 2: Block one compromised host

Goal: Deny all traffic from a single compromised host (192.168.20.44) without breaking the existing HTTPS permit for the rest of the subnet.

Hint: Place a host-specific deny entry above the permit entry and confirm the ordering with show access-lists.