๐ 05-03: Stateful Firewalls¶
๐ What Does "Stateful" Mean?¶
A stateful firewall adds the one thing packet filters were missing: memory. Instead of judging every packet in isolation, a stateful firewall keeps a connection tracking table that records every connection it has already approved. When a new packet arrives, the firewall first checks: "is this packet part of a connection I already know about?"
This single idea โ remembering ongoing conversations โ is why stateful inspection is considered one of the biggest leaps forward in firewall design.
๐ก On Linux, this connection tracking system is called conntrack, and it's built into the kernel's Netfilter framework (the same framework iptables configures โ see 05-05: iptables Fundamentals).
๐ท๏ธ Connection States¶
Every tracked connection is labeled with a state. The four states used by Linux's conntrack (and conceptually by every stateful firewall) are:
| State | Meaning |
|---|---|
| NEW | The first packet of a connection the firewall hasn't seen before (e.g., a TCP SYN, or the first UDP packet in a flow) |
| ESTABLISHED | A packet that belongs to a connection where traffic has already flowed in both directions |
| RELATED | A new connection that is logically tied to an existing one (e.g., an FTP data connection opened because of an existing FTP control connection) |
| INVALID | A packet that doesn't fit any known connection and doesn't look like a valid new connection either (e.g., a lone TCP ACK with no matching SYN) |
Example: Why RELATED Matters¶
FTP is the classic example. The client opens a control connection to the server on port 21. To transfer a file, the server (in active mode) opens a separate data connection back to the client on a random high port. A plain stateful firewall wouldn't know this second connection is legitimate โ it looks like an unsolicited inbound connection. But a firewall with protocol-aware connection tracking (an FTP "conntrack helper") recognizes that this new connection is related to the already-approved control connection, and allows it automatically.
โ๏ธ Why This Is a Major Improvement Over Stateless Filtering¶
Recall the core weakness of packet filters from 05-02: Packet-Filtering Firewalls: to allow return traffic for an outbound connection, an administrator had to write a blind standing rule like "allow any inbound TCP packet with the ACK flag set," which an attacker could exploit by simply forging a packet with the ACK flag set.
A stateful firewall replaces that entire class of blind rules with one precise rule:
This rule only matches packets that the firewall's own connection table recognizes as belonging to a connection it already approved. A forged packet claiming to be part of a connection โ but that doesn't match an actual tracked entry (source IP, destination IP, source port, destination port, sequence numbers, protocol) โ is not ESTABLISHED or RELATED. It falls through to INVALID or NEW, where the default-deny policy catches it.
| Aspect | Stateless Filter | Stateful Firewall |
|---|---|---|
| Decision basis | This packet's headers only | This packet + the connection's history |
| Return traffic rule | Manual, broad, exploitable | Automatic, precise, tied to real state |
| Spoofed "reply" packets | Often accepted | Rejected (no matching table entry) |
| Rule set size | Large (one rule per direction per service) | Small (one ESTABLISHED/RELATED rule covers all approved connections) |
| Resource cost | Very low | Higher โ must maintain a connection table in memory |
๐งช Worked Example: Outbound Connection, Automatic Return Traffic¶
Suppose an internal host 192.168.1.50 opens an HTTPS connection to 93.184.216.34:443.
Step 1 โ Outbound SYN packet leaves the network:
The firewall matches this against an outbound rule, allows it, and โ critically โ creates a new entry in the connection tracking table:
Step 2 โ Server's SYN-ACK reply arrives inbound:
The firewall checks this packet against its conntrack table. It finds a matching entry (same 4-tuple, reversed direction) and reclassifies the connection as ESTABLISHED. A single rule โ
โ allows this packet through without the administrator ever having to write a rule that explicitly opens port 51000 inbound. No attacker on the internet can send a packet claiming dst=192.168.1.50:51000 and have it accepted this way, because unless it matches the exact tracked 4-tuple and expected sequence numbers, it won't be recognized as ESTABLISHED.
Step 3 โ Rest of the conversation:
Every subsequent packet in both directions matches the same conntrack entry as ESTABLISHED and flows through under that one rule, until the connection closes (TCP FIN/RST) or the table entry times out.
๐ก This is why a typical, secure iptables INPUT chain is often just three rules: allow loopback, allow ESTABLISHED/RELATED, allow a short list of specific NEW services (like SSH) โ then drop everything else. See the full worked rule set in 05-06: Writing iptables Rules.
โฑ๏ธ A Note on Connectionless Protocols (UDP/ICMP)¶
UDP and ICMP have no formal "connection" the way TCP does (no SYN/ACK handshake) โ yet Linux's conntrack still tracks them. For these protocols, "connection" is a pragmatic approximation: the tracker remembers the source/destination pair and a short timeout window, and treats a reply arriving within that window (e.g., a DNS response coming back from the server you just queried) as ESTABLISHED. Once the timeout expires with no reply, the entry is dropped.
| Protocol | Tracked By | Typical Timeout |
|---|---|---|
| TCP | Full connection state machine (SYN, ESTABLISHED, FIN, etc.) | Hours (for ESTABLISHED) |
| UDP | Source/destination pair + short timeout window | Seconds (tens of seconds, typically) |
| ICMP | Request/reply pairing (e.g., echo-request โ echo-reply) matched by ID | Seconds |
๐ Key Takeaways¶
- A stateful firewall tracks ongoing connections instead of judging every packet in isolation.
- The four connection states are NEW, ESTABLISHED, RELATED, and INVALID.
- RELATED exists to handle protocols like FTP where a second connection is legitimately spawned by an already-approved one.
- Stateful inspection closes the exact hole that stateless filters had: it can tell a genuine reply from a spoofed packet, because it checks against a real tracked connection, not just header values.
- A single
ctstate ESTABLISHED,RELATEDrule replaces dozens of blind "allow return traffic" rules from the stateless world. - Even connectionless protocols like UDP and ICMP get an approximate "connection" tracked, using timeouts instead of a handshake.
- Stateful firewalls cost more memory/CPU than stateless filters (they must maintain a live table), but the security benefit is well worth it for almost any modern deployment.
- On Linux, this is implemented by conntrack, part of the Netfilter framework that also powers
iptables.