ACL & Firewall Rules

Control which traffic is allowed through your network, and in which direction.

What Is an ACL?

An Access Control List is an ordered list of permit and deny statements. A router or switch checks each packet against the list. ACLs can match on:

Besides filtering traffic, ACLs also pick out traffic for NAT, QoS, route maps, VPNs, and limiting who can reach VTY (SSH) lines.

How ACLs Are Processed

  1. Top-down: statements are checked in order (by sequence number).
  2. First match wins: once a packet matches, the action is taken and no more lines are checked.
  3. Implicit deny: every ACL ends with an invisible deny any. A packet that matches nothing is dropped.
  4. One ACL per interface, per direction, per protocol (for example, one inbound IPv4 ACL on Gi0/0).

Order matters. Put the most specific rules first. A broad permit ip any any near the top makes every line below it useless.

Wildcard Masks

Cisco ACLs use wildcard masks, which work like an inverted subnet mask. A 0 bit means "must match" and a 1 bit means "don't care." A quick way to get one: subtract the subnet mask from 255.255.255.255.

MatchSubnet maskWildcardShortcut
One host 10.1.1.5255.255.255.2550.0.0.0host 10.1.1.5
192.168.10.0/24255.255.255.00.0.0.255—
172.16.0.0/16255.255.0.00.0.255.255—
10.0.0.0/30255.255.255.2520.0.0.3—
Everything0.0.0.0255.255.255.255any

Standard ACLs

Standard ACLs match on the source IP only. Numbered ranges: 1–99 and 1300–1999.

Example: only 192.168.10.0/24 may reach the server LAN
Router(config)# access-list 10 remark ALLOW USERS TO SERVERS
Router(config)# access-list 10 permit 192.168.10.0 0.0.0.255
! implicit deny any

Router(config)# interface gigabitEthernet0/2       ! server LAN interface
Router(config-if)# ip access-group 10 out
Example: allow SSH to the router only from the admin subnet
Router(config)# ip access-list standard MGMT-ONLY
Router(config-std-nacl)# permit 192.168.99.0 0.0.0.255
Router(config-std-nacl)# deny any log

Router(config)# line vty 0 15
Router(config-line)# access-class MGMT-ONLY in
Router(config-line)# transport input ssh

Extended ACLs

Extended ACLs match on source, destination, protocol and ports. Numbered ranges: 100–199 and 2000–2699. Named ACLs are easier to read and edit, so prefer those.

Syntax: permit|deny protocol source [port] destination [port]

Example: protect a web server at 203.0.113.10
Router(config)# ip access-list extended WEB-IN
Router(config-ext-nacl)# 10 permit tcp any host 203.0.113.10 eq 443
Router(config-ext-nacl)# 20 permit tcp any host 203.0.113.10 eq 80
Router(config-ext-nacl)# 30 permit tcp 198.51.100.0 0.0.0.255 host 203.0.113.10 eq 22
Router(config-ext-nacl)# 40 permit icmp any host 203.0.113.10 echo
Router(config-ext-nacl)# 50 permit tcp any any established
Router(config-ext-nacl)# 1000 deny ip any any log

Router(config)# interface gigabitEthernet0/0       ! Internet-facing
Router(config-if)# ip access-group WEB-IN in

Editing named ACLs: sequence numbers let you insert a line without retyping the whole list, for example 15 permit tcp any host 203.0.113.10 eq 8443. Remove a line with no 15.

Common port keywords
eq 22 (ssh)   eq 23 (telnet)   eq 25 (smtp)   eq 53 (domain)
eq 80 (www)   eq 443           eq 3389        range 49152 65535
gt 1023       lt 1024          neq 23

Placement and Direction

ACL typePlace itWhy
ExtendedAs close to the source as possibleIt's specific enough to drop unwanted traffic early without affecting other traffic.
StandardAs close to the destination as possibleIt only knows the source, so placing it near the source would block that host from everything.

Stateless vs Stateful Firewalls

Stateless (router ACL)Stateful firewall
Tracks connections?No. Each packet is judged on its own.Yes, through a session/state table.
Return trafficNeeds its own rule (for example established)Allowed automatically if the session started from the inside
ExamplesCisco IOS ACLs, Junos firewall filters, AWS Network ACLsCisco ASA/FTD, Juniper SRX, Palo Alto, Fortinet, Linux nftables/firewalld, AWS Security Groups

Next-generation firewalls (NGFW) add Layer 7 awareness on top of state tracking: they can identify applications, inspect TLS, prevent intrusions (IPS), and write rules based on users.

Junos Firewall Filters

Junos uses firewall filters made of named terms. Each term has from (match conditions) and then (action). Like Cisco ACLs, terms are checked in order and there's an implicit discard at the end.

Protect the routing engine: allow SSH from admins, OSPF and ICMP
set firewall family inet filter PROTECT-RE term SSH from source-address 192.168.99.0/24
set firewall family inet filter PROTECT-RE term SSH from protocol tcp
set firewall family inet filter PROTECT-RE term SSH from destination-port ssh
set firewall family inet filter PROTECT-RE term SSH then accept

set firewall family inet filter PROTECT-RE term OSPF from protocol ospf
set firewall family inet filter PROTECT-RE term OSPF then accept

set firewall family inet filter PROTECT-RE term ICMP from protocol icmp
set firewall family inet filter PROTECT-RE term ICMP then policer ICMP-1M
set firewall family inet filter PROTECT-RE term ICMP then accept

set firewall family inet filter PROTECT-RE term DENY-ALL then count DENIED
set firewall family inet filter PROTECT-RE term DENY-ALL then log
set firewall family inet filter PROTECT-RE term DENY-ALL then discard

set firewall policer ICMP-1M if-exceeding bandwidth-limit 1m burst-size-limit 15k
set firewall policer ICMP-1M then discard

set interfaces lo0 unit 0 family inet filter input PROTECT-RE

Careful: a filter on lo0 affects all traffic to the router itself. Allow every protocol you use (BGP, BFD, NTP, DNS, SNMP, and so on) before you commit, and use commit confirmed 5 so the change rolls back automatically if you lock yourself out.

Linux firewalld and Cloud Firewalls

On RHEL, Rocky and Fedora servers, firewalld manages the kernel's nftables firewall. It's stateful, organized into zones, and denies inbound traffic by default.

# Allow web traffic
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# Allow SSH only from the admin subnet (rich rule)
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.99.0/24" service name="ssh" accept'

# Open a custom port
sudo firewall-cmd --permanent --add-port=8443/tcp

# Apply and review
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

AWS: Security Groups vs Network ACLs

Security GroupNetwork ACL
Applies toInstance / ENISubnet
StateStatefulStateless
RulesAllow onlyAllow and deny
EvaluationAll rules are evaluatedIn number order, first match wins

Best Practices

Check Yourself

1. What happens to a packet that doesn't match any line in an ACL?It's dropped by the implicit deny any at the end.
2. What's the wildcard mask for 10.20.0.0/22?0.0.3.255 (255.255.255.255 − 255.255.252.0).
3. Where should you place an extended ACL? A standard ACL?Extended: close to the source. Standard: close to the destination.
4. Line 10 is permit ip any any and line 20 is deny tcp any any eq 23. Is Telnet blocked?No. Line 10 matches first and permits everything, so line 20 is never reached.
5. Why don't you need a return-traffic rule on an AWS Security Group?Security Groups are stateful, so return traffic for allowed connections is permitted automatically.
← Routing & Switching Back to Home