In Firewalls you met the firewall as a device: the security desk between your network and the internet. This lesson opens the security desk's rule book. You will learn how rules are written, how the firewall checks a packet against them, and the most important idea of all: how a stateful firewall lets replies back in without letting strangers in.
💡 In simple terms: the firewall has a list of "who may go where". It reads the list from the top, does what the first matching line says, and turns away anyone who is not on the list. It also keeps a guest book of conversations already in progress, so people coming back to a conversation don't need to be checked again.
What a firewall policy is
A firewall policy (also called a rule base or rule table) is the ordered list of rules a firewall follows. Each rule describes some traffic and says what to do with it. A rule normally has these parts:
Source
Where the traffic comes from: an IP address, a subnet, a zone or “any”.
Destination
Where it is going: an address, subnet, zone or “any”.
Service
The protocol and destination port, e.g. TCP 443 for HTTPS or UDP 53 for DNS.
Action
Allow (also called permit or accept) or deny (drop or reject).
Logging
Whether to write a log entry each time the rule is used.
Name / comment
Why the rule exists and who asked for it. Rules without a reason are hard to clean up later.
The firewall takes these facts from the packet's headers: the addresses from the IP header and the ports from the TCP or UDP header (see Port numbers and sockets).
Why rules are needed
A router forwards any packet it has a route for. It never asks whether the packet should be delivered. Rules add that question. They let an organisation write down, in a form a machine can enforce, which conversations are part of normal business and which are not. The goal is to allow the traffic people need and nothing more. This is the idea of least privilege, explained in Basic network security.
An example rule table
Here is a small office firewall. The inside network is 192.168.10.0/24, and a public web server sits in a DMZ (a separate zone for public-facing servers) at 172.16.1.10. Remember it: every example below uses it.
| # | Source | Destination | Service | Action | Log | Reason |
|---|---|---|---|---|---|---|
| 1 | Inside 192.168.10.0/24 | Any (internet) | TCP 80, 443 | Allow | No | Staff can browse the web |
| 2 | Inside 192.168.10.0/24 | DNS server 198.51.100.53 | UDP/TCP 53 | Allow | No | Name lookups |
| 3 | Any (internet) | Web server 172.16.1.10 (DMZ) | TCP 443 | Allow | Yes | Customers reach the public website |
| 4 | IT PC 192.168.10.5 | Web server 172.16.1.10 (DMZ) | TCP 22 (SSH) | Allow | Yes | Only IT may manage the web server |
| 5 | Inside 192.168.10.0/24 | Any (internet) | TCP 25 (SMTP) | Deny | Yes | PCs must not send email directly; stops spam from infected PCs |
| — | Any | Any | Any | Deny | Often | Implicit deny: everything not allowed above |
Notice there is no rule for the replies from websites or from the DNS server. On a stateful firewall you don't need one. That is the subject of the second half of this lesson.
How a firewall checks a packet, step by step
First match wins
Most firewalls stop at the first rule that matches, not the best or most specific one. So the order of rules is part of the policy. Imagine someone adds "Deny inside → any, any service" as a new rule at the top of the table. Rules 1 and 2 are still there, but no packet ever reaches them. Every user loses the internet, even though the "allow web" rule looks fine.
💡 A good habit: specific rules at the top, broad rules at the bottom, and the implicit deny last of all.
Implicit deny
Below the last rule you wrote is one you didn't write: deny everything. It is called the implicit deny (or default deny). It means a firewall starts from "nothing is allowed", and every rule is an exception. This is much safer than the opposite approach ("allow everything, block the bad things"), because nobody can list every bad thing in advance.
⚠️ Some firewalls hide the implicit deny from the rule list, and many don't log it unless you ask. If you can't find the rule that blocked something, it was probably the implicit deny. Many administrators add an explicit "deny any any, log" as their last rule just to see these drops.
Allowed and denied traffic: worked examples
Run some packets through the rule table above. Each line is the first packet of a new conversation.
| New packet | Matches | Result |
|---|---|---|
192.168.10.11:51514 → 203.0.113.10:443 (staff PC opens a website) | Rule 1 | ✅ Allowed |
192.168.10.11:60202 → 198.51.100.53:53 UDP (DNS lookup) | Rule 2 | ✅ Allowed |
198.51.100.25:49001 → 172.16.1.10:443 (customer visits the website) | Rule 3 | ✅ Allowed, logged |
198.51.100.25:49002 → 172.16.1.10:22 (customer tries SSH) | Nothing; rule 4 is only for the IT PC | ❌ Implicit deny |
192.168.10.5:50110 → 172.16.1.10:22 (IT manages the server) | Rule 4 | ✅ Allowed, logged |
192.168.10.33:51000 → 192.0.2.25:25 (infected PC sends spam) | Rule 5 | ❌ Denied, logged |
192.168.10.11:52000 → 203.0.113.20:3389 (Remote Desktop to the internet) | Nothing | ❌ Implicit deny |
198.51.100.66:50122 → 192.168.10.20:445 (scanner tries file sharing) | Nothing | ❌ Implicit deny |
Rule 5 is interesting. Without it, SMTP would still be blocked by the implicit deny. The explicit deny exists so that every attempt is logged: a PC trying to send email directly is a strong hint that it is infected.
Sessions: the firewall's memory
A session (or connection) is one conversation between two programs, such as your browser talking to a web server. It is identified by five facts, the 5-tuple: source IP, destination IP, protocol, source port and destination port. A stateful firewall keeps a state table (also called a session table or connection table) with one line per session it has allowed.
| Protocol | Inside socket | Outside socket | State | Idle timeout |
|---|---|---|---|---|
| TCP | 192.168.10.11:51514 | 203.0.113.10:443 | ESTABLISHED | 1 hour |
| UDP | 192.168.10.11:60202 | 198.51.100.53:53 | (reply seen) | 30 seconds |
| TCP | 192.168.10.5:50110 | 172.16.1.10:22 | ESTABLISHED | 1 hour |
For TCP, the firewall follows the real connection states: it sees the SYN, SYN-ACK and ACK, and removes the entry after the FIN or RST that closes the connection. UDP has no connection, so the firewall pretends it does: it pairs a request with its reply by address and port, and forgets the pair after a short idle timeout. Timeouts above are typical values; every vendor picks its own.
Stateless vs. stateful inspection
This is the key difference between an old-style packet filter and a modern firewall. Both use rule tables. What differs is how they deal with return traffic: the replies to a conversation that started inside.
Stateless (packet filtering)
A stateless firewall has no memory. It checks every packet against the rules as if it had never seen anything before. A reply from a web server is just another packet arriving from the internet, so it is blocked unless a rule allows it.
- The PC
192.168.10.11sends a SYN from port51514to203.0.113.10:443. Rule 1 allows it. - The web server replies from
203.0.113.10:443to192.168.10.11:51514. - The firewall checks the reply against the rules. No rule allows traffic from the internet to the inside. The implicit deny drops it.
- The website never loads.
To fix this, the administrator must add a reverse rule like "allow TCP from any address, source port 443, to the inside, ports 1024–65535". That is the range the PC might pick its temporary source port from. Now the reply gets in, but so does any packet an attacker sends from source port 443 to almost any port on any inside PC. The firewall can't tell a real reply from a fake one, because it doesn't remember what was sent.
Stateless filters are still used where speed matters more than detail, for example simple access lists on routers and switches. Some can check the TCP flags ("only allow inbound packets with the ACK flag set"), which helps a little, but they still cannot match a reply to a real request.
Stateful inspection
A stateful firewall remembers. When it allows the first packet of a conversation, it writes a line in its state table. Every later packet is checked against that table first.
- Session:
- TCP 192.168.10.11:51514 ↔ 203.0.113.10:443
- State:
- ESTABLISHED, removed after FIN/RST or idle timeout
Putting the two side by side:
| Stateless filter | Stateful firewall | |
|---|---|---|
| Memory | None; each packet judged alone | State table of active sessions |
| Return traffic | Needs its own (often very broad) rule | Allowed automatically if it matches a session |
| Fake replies | Often let through | Dropped: no matching session |
| Rules to write | About twice as many | One per conversation direction you want to start |
| Speed and memory use | Very fast, almost no memory | Needs memory for every session; a flood of sessions can fill the table |
| Where you see it | Router and switch access lists, some cloud network ACLs | Almost every firewall today, home routers, host firewalls, cloud security groups |
Zones: inside, outside and DMZ
Writing rules for individual interfaces gets messy. Most firewalls group interfaces into zones and write rules between zones. Each zone has a trust level, and a sensible default policy for each direction:
| From → To | Typical default | Why |
|---|---|---|
| Inside → Outside | Allow the services staff need (web, DNS…) | Staff start conversations; replies come back statefully |
| Outside → Inside | Deny everything | Strangers must never start a conversation with an inside PC |
| Outside → DMZ | Allow only the public service, e.g. TCP 443 | The website must be reachable, nothing else on the server |
| DMZ → Inside | Deny, with tiny exceptions (e.g. one database port) | If the web server is hacked, the attacker is stuck in the DMZ |
| Inside → DMZ | Allow management from IT only | Least privilege: not every PC needs SSH to the server |
- 1. Outside → DMZ, HTTPS: rule 3 allows it. Customers reach the website. The firewall logs the connection.
- 2. Outside → DMZ, SSH: implicit deny. Nobody on the internet may manage the server.
- 3. IT PC → DMZ, SSH: rule 4 allows it. Only one named inside address gets management access.
- 4. Staff PC → DMZ, SSH: implicit deny. Least privilege: ordinary staff don't need it.
- 5. Inside → outside, web: rule 1 allows it. The replies return through the state table.
Zones are the firewall's side of a wider design idea: splitting a network into parts with different trust levels. That is covered fully in Network segmentation.
Host firewalls and network firewalls
Everything above applies to both kinds. A network firewall is a device on the path that protects everything behind it. A host firewall is software on one computer (Windows Defender Firewall, ufw or nftables on Linux, the macOS application firewall) that protects only that computer, but does so wherever it goes. Host firewalls are stateful too, and most default to "deny incoming, allow outgoing".
Network firewall rule
"Allow any → 172.16.1.10, TCP 443." Protects the whole DMZ from the internet.
Host firewall rule
"On this server, allow TCP 22 only from 192.168.10.5." Still protects the server if the network rule is wrong.
A packet must be allowed by every firewall on its path. That is a common cause of confusion: the network team opens a port, and it still fails because of the host firewall on the server.
Drop or reject?
A deny rule can do one of two things:
- Drop: silently throw the packet away. The sender waits, retries and finally times out. Scanners learn nothing.
- Reject: throw it away and answer: a TCP RST, or an ICMP "destination unreachable (administratively prohibited)" message (see ICMP). The sender fails at once.
Internet-facing rules usually drop. Internal rules sometimes reject, so that users get a quick error instead of a long wait.
Logging
A firewall can write a log entry for allowed connections, denied packets, or both. Logs answer two questions: "why doesn't this work?" and "who tried to get in?". A log entry normally holds the time, the action, the 5-tuple, the interface or zone, and the rule that matched.
$ sudo grep 'UFW BLOCK' /var/log/ufw.log | tail -2 Oct 5 09:14:02 web1 kernel: [86412.553201] [UFW BLOCK] IN=eth0 OUT= MAC=02:00:00:00:00:aa:02:00:00:00:00:01:08:00 SRC=198.51.100.66 DST=172.16.1.10 LEN=60 TOS=0x00 PREC=0x00 TTL=52 ID=40312 DF PROTO=TCP SPT=50122 DPT=22 WINDOW=64240 RES=0x00 SYN URGP=0 Oct 5 09:14:05 web1 kernel: [86415.561877] [UFW BLOCK] IN=eth0 OUT= MAC=02:00:00:00:00:aa:02:00:00:00:00:01:08:00 SRC=198.51.100.66 DST=172.16.1.10 LEN=60 TOS=0x00 PREC=0x00 TTL=52 ID=40313 DF PROTO=TCP SPT=50123 DPT=3389 WINDOW=64240 RES=0x00 SYN URGP=0
Read it as: a SYN (a new TCP connection) from 198.51.100.66 to this server on port 22, then port 3389, both blocked. Someone is trying one door after another: a port scan.
💡 Logging every allowed packet would fill the disk quickly. A common balance is: log denied traffic, log new connections on important rules (like rule 3 and rule 4), and send the logs to a central server with Syslog so they survive if the firewall is attacked. Correct time from NTP matters too: logs from different devices can only be compared if their clocks agree.
What happens when the firewall gets it wrong
| Problem | What users see | Typical cause |
|---|---|---|
| Rule too strict | A new application times out | No allow rule, so the implicit deny catches it |
| Rule too loose | Nothing, until an attacker finds it | "Any any allow" added during testing and never removed |
| Wrong order | Some traffic blocked that "should" work | A broad deny above a specific allow |
| State table full | New connections fail; existing ones keep working | A flood of connections (attack or a broken program) |
| Session timed out | A long idle connection (e.g. SSH) suddenly freezes | The firewall forgot the session; later packets look unsolicited |
| Asymmetric path | Connections fail in odd ways | Replies return through a different firewall that never saw the SYN |
Troubleshooting and useful commands
- Test the exact port, not just ping. Ping uses ICMP and tells you nothing about TCP 443.
- Check the logs on every firewall on the path, including the host firewall on the destination.
- Find the rule that should match, and check nothing above it matches first.
- Look at the state table to see whether the session was created at all.
PS C:\> Test-NetConnection 172.16.1.10 -Port 443 ComputerName : 172.16.1.10 RemoteAddress : 172.16.1.10 RemotePort : 443 InterfaceAlias : Ethernet SourceAddress : 192.168.10.11 TcpTestSucceeded : True
C:\> netsh advfirewall firewall show rule name="Remote Desktop - User Mode (TCP-In)" Rule Name: Remote Desktop - User Mode (TCP-In) ---------------------------------------------------------------------- Enabled: No Direction: In Profiles: Domain,Private,Public Grouping: Remote Desktop LocalIP: Any RemoteIP: Any Protocol: TCP LocalPort: 3389 RemotePort: Any Edge traversal: No Action: Allow Ok.
The rule exists but Enabled: No, so inbound Remote Desktop falls through to Windows Firewall's default: block incoming.
$ sudo conntrack -L -p tcp --dport 443 tcp 6 431987 ESTABLISHED src=192.168.10.11 dst=203.0.113.10 sport=51514 dport=443 src=203.0.113.10 dst=192.168.10.11 sport=443 dport=51514 [ASSURED] mark=0 use=1 conntrack v1.4.6 (conntrack-tools): 1 flow entries have been shown.
This is a real state table entry. The first half is the original direction; the second half is the reply the firewall expects. The number 431987 is the seconds left before the idle entry is forgotten.
From outside your network, the Port Checker shows whether a public port is reachable through your edge firewall.
Common mistakes
- Writing return rules on a stateful firewall. They aren't needed, and a broad "allow inbound from port 443" rule opens a real hole.
- Using "any" when you mean one address. Rule 4 names one IT PC, not the whole inside network.
- Forgetting rule order. A new rule added at the top can silently override everything below it.
- Not logging denies. Then nobody can tell what the implicit deny is blocking.
- Never cleaning up. Old rules for retired servers pile up; every one is a door someone might reuse.
- Assuming outbound is harmless. Malware "phones home" with outbound connections; outbound rules (like rule 5) catch some of it.
- A firewall policy is an ordered list of rules: source, destination, service, action, logging.
- Rules are checked top to bottom and the first match wins.
- The implicit deny at the bottom blocks everything you didn't allow.
- A stateful firewall records each allowed session and lets its replies back in automatically; unsolicited packets from outside are treated as new and usually denied.
- A stateless filter judges each packet alone, so return traffic needs broad rules that attackers can abuse.
- Zones (inside, outside, DMZ) make policies simpler; logs make them understandable.
Knowledge check
Using the lesson's rule table: a customer at 198.51.100.25 tries to SSH (TCP 22) to the web server 172.16.1.10. What happens?
A stateful firewall allows inside → internet TCP 443. A staff PC opens https://203.0.113.10. There is no inbound rule at all. Does the web page load?
An administrator adds 'Deny inside → any, all services' as the new rule 1, above 'Allow inside → any, TCP 443'. What happens to web browsing?
An SSH session through the firewall freezes after the user leaves it idle over lunch. Typing does nothing. What is the most likely cause?
Where to go next
Firewalls control who can connect. To protect data as it crosses networks you don't control, the next tool is encryption in a tunnel: VPN basics. For how zones grow into a whole network design, read Network segmentation. Edge firewalls almost always perform NAT as well, which changes the addresses you see in their logs.