Everyone Can Learn Program
中文 Start learning
Specialty · SecurityLesson 9 of 9Free to read

Firewall rules · Cyber Security Basics

How does a firewall decide which traffic gets in?

Course contents

Why you need it

Every server on the internet is scanned constantly. A firewall is the first filter: it lets the traffic you expect reach the right ports and drops the rest. Reading and writing firewall rules is a core skill for security and operations, and most mistakes come from rule order and from forgetting the default.

The intuition

Picture a guard with a list of rules, checked top to bottom. The first rule that matches decides; the rest are ignored. If nothing matches, the default applies, and a safe default is "deny".

Addresses come in blocks written in CIDR notation: 192.0.2.0/24 means "every address whose first 24 bits match", which is 192.0.2.0 to 192.0.2.255 (256 addresses). 0.0.0.0/0 matches every address. Python's ipaddress module does the bit maths for you: ip_address(x) in ip_network(block).

A port says which service on the machine: 22 is SSH (remote login), 443 is HTTPS (websites).

Definition

First-match rule

Rules are checked in order and the first matching rule decides. Order changes the result.

CIDR block

An address range written as address/prefix length. A /24 block has 256 addresses; /32 is one address; /0 is all of them.

Examples

Is this address in the block?

Try it yourself

The office network is 192.0.2.0/24.

import ipaddress
office = ipaddress.ip_network("192.0.2.0/24")
for ip in ["192.0.2.10", "192.0.2.255", "192.0.3.10"]:
    print(ip, ipaddress.ip_address(ip) in office)
print(office.num_addresses)
Step by step
  1. L2A network object for the whole block.
  2. L4in checks whether the address falls in the block.192.0.2.10 True
  3. L4192.0.3.x is a different block.192.0.3.10 False
  4. L5A /24 leaves 8 bits for hosts: 2⁸ = 256.256

First match wins

Try it yourself

SSH only from the office, HTTPS from anywhere, everything else denied.

import ipaddress
rules = [
    ("allow", "192.0.2.0/24", 22),
    ("deny", "0.0.0.0/0", 22),
    ("allow", "0.0.0.0/0", 443),
]

def decide(ip, port):
    for action, net, p in rules:
        if port == p and ipaddress.ip_address(ip) in ipaddress.ip_network(net):
            return action
    return "deny"

print(decide("192.0.2.8", 22))
print(decide("203.0.113.9", 22))
print(decide("203.0.113.9", 443))
print(decide("203.0.113.9", 3306))
Step by step
  1. L9Rules are checked top to bottom.
  2. L11The first match returns at once.
  3. L12No rule matched: the default is deny.
  4. L14Office address, port 22: rule 1 allows.allow
  5. L15Outside address, port 22: rule 1 doesn't match, rule 2 denies.deny
  6. L17Port 3306 (a database) matches nothing: default deny.deny

Common mistakes

A broad rule on top

If allow 0.0.0.0/0 22 comes first, the office-only rule below it never matters: everyone gets SSH. Put specific rules before general ones.

Default allow

A firewall that allows anything not explicitly denied leaves every forgotten service open. Deny by default and allow only what you need.

Quick quiz

1. What does this print?

import ipaddress
rules = [("allow", "0.0.0.0/0", 22), ("deny", "203.0.113.0/24", 22)]

def decide(ip, port):
    for action, net, p in rules:
        if port == p and ipaddress.ip_address(ip) in ipaddress.ip_network(net):
            return action
    return "deny"

print(decide("203.0.113.66", 22), decide("203.0.113.66", 80))
  1. A
    allow deny
  2. B
    deny deny
  3. C
    allow allow
Show the answer

Answer: A

The allow-everyone rule is first, so the deny rule below it is never reached for port 22. Port 80 matches no rule: default deny.

2. How many addresses are in 10.0.0.0/30?

  1. A4
  2. B30
  3. C256
Show the answer

Answer: A

32 − 30 = 2 bits are left for hosts, and 2² = 4.

Practice

3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.

  1. PredictDecide each packet

    Type exactly what this program prints.

  2. ModifyAny port

    Two changes:

    • a rule's port can be None, meaning any port
    • when no rule matches, return "deny" (the current code returns "allow")

    The new last rule blocks the whole 198.51.100.0/24 network on every port, so it must come first to take effect: move it to the top of the list.

  3. WriteRead rules from text

    Firewall rules are often written as text. Write decide(ip, port, rules) where rules is a list of strings like:

    allow 192.0.2.0/24 22
    deny 0.0.0.0/0 *

    Each rule is action block port, and port * means any port. Check the rules in order, return the action of the first match, and "deny" if none match. port is an integer.

Practise this lesson

Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.

Interactive lessons open in order. If you have not done the earlier ones yet, you start at the course map.

Terms in this lesson

TermChineseDefinition
Firewall防火墙A filter that allows or blocks network traffic according to rules.
CIDR notationCIDR 记法Writing an address range as address/prefix, such as 192.0.2.0/24.
Port端口A number that selects a service on a machine, such as 22 for SSH or 443 for HTTPS.
Default deny默认拒绝Blocking everything that no rule explicitly allows.