First-match rule evaluation

Firewall rules

Lesson 18 of 20 · 12 min · Module 6: Policies and audits

A firewall checks each connection against an ordered list of rules. The first rule that matches decides, and anything unmatched is denied.

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Evaluate ordered rules
  • Treat None as a wildcard
  • Apply a default-deny policy

The idea

Each rule has an action ("allow" or "deny"), a source network, and a port, where None means any port. Order matters: a broad deny placed before a specific allow blocks it.

rules = [
    {"action": "allow", "source": "10.0.0.0/8", "port": 22},
    {"action": "deny", "source": "0.0.0.0/0", "port": None},
]

01Order is policy

Firewalls read rules from top to bottom and stop at the first match. Specific exceptions go first; broad rules go last.

02Wildcards

port: None means "any port". The test rule["port"] in (None, port) is true for the wildcard and for an exact match.

print(None in (None, 22), 80 in (None, 22))
Output
True False

03Default deny

When no rule matches, the safe answer is no. Allowing only what you explicitly listed is the foundation of good firewall design.

Your turn

Write allowed(rules, source_ip, port) that returns True if the first matching rule allows the connection and False if it denies it. With no matching rule, return False (default deny).

What the checks look for

  • Allows SSH from the internal network
  • Denies SSH from the internet
  • The first matching rule wins
  • Denies by default when nothing matches
Try it in the editor →

Take this with you

First match wins; nothing matched means denied.

Go a little further

Return the index of the rule that decided, which helps when explaining a blocked connection.

Learn Networking Foundations for free

20 short lessons with real code and instant checks.

See the whole course →