Firewalls (Stateful vs Stateless)

intermediate firewall iptables nftables waf security networking

A firewall is a piece of software (or hardware) that decides which packets get through and which get dropped. It sits between two networks and applies a set of rules.

In simple language: a bouncer at the door. Has a guest list (the rules). Anyone not on the list, denied.

Stateless (Packet Filter)

Looks at each packet in isolation. No memory of past packets. Rules match on headers only — source IP, destination IP, source port, destination port, protocol.

ALLOW any -> 1.2.3.4 port 443 (TCP)
DENY any -> any port 22 (TCP)

Pros: very fast, low memory. Cons: can’t distinguish a reply from a fresh attack. To allow returning traffic, we have to open ephemeral ports both ways, which is loose.

Stateful (Connection Tracking)

Keeps a table of active connections. When packet comes in, the firewall checks: “is this part of an existing connection I already approved?”

If yes, the packet is allowed without re-checking rules. If no, the rules are evaluated.

This is how almost every modern firewall works (iptables conntrack, pf, Windows Firewall, AWS Security Groups).

# iptables stateful rule — allow return traffic for established connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow new SSH connections
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# Drop everything else
iptables -A INPUT -j DROP

Pros: smart enough to handle replies automatically, less rule writing, more secure default. Cons: uses memory per connection (state table can be exhausted by SYN floods).

Application / Layer 7 / WAF

A Web Application Firewall reads inside the HTTP request — headers, URL, body, cookies — and matches against rules like “block if path contains ../” or “block requests with SQL injection patterns.”

WAFs sit in front of web servers (Cloudflare, AWS WAF, ModSecurity). They’re the only firewall that can stop application-layer attacks like SQLi, XSS, or attacks on /login endpoints.

Default-Deny vs Default-Allow

Two philosophies for the catch-all rule at the end:

  • Default-deny — deny anything not explicitly allowed. Always preferred for production. Adding a service is an explicit decision.
  • Default-allow — allow anything not explicitly denied. Easier to start with but unsafe — every new service is exposed unless someone remembers to block it.
# Default-deny on iptables INPUT chain
iptables -P INPUT DROP
# Now nothing comes in unless we explicitly ALLOW it above this point

iptables vs nftables

  • iptables — the classic Linux firewall tool. Five tables (filter, nat, mangle, raw, security), chains (INPUT, OUTPUT, FORWARD), rules.
  • nftables — the modern replacement. Single tool (nft), unified syntax, faster rule evaluation. Default on most modern Linux distros.
# nftables example — allow SSH and HTTP
nft add rule inet filter input tcp dport { 22, 80, 443 } accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input drop

AWS — Security Groups vs NACLs

A common interview question. Both filter traffic, both work in the cloud, but they’re different:

  • Security Group — stateful, attached to instances/ENIs, only allow rules. Reply traffic is automatic.
  • Network ACL — stateless, attached to subnets, allow + deny rules with order. Reply traffic needs explicit rules.

Use Security Groups for normal app rules. Use NACLs for blanket subnet-level blocks (e.g., block a known bad IP range).

Common Gotcha

Stateless ≠ slow. Stateful ≠ smart enough. A SYN flood fills up the conntrack table of a stateful firewall. The fix is nf_conntrack_max tuning, SYN cookies, and SYN proxy in front of the firewall — not switching to stateless.

Interview Tip

When asked about firewalls, structure the answer by layer. L3/L4 packet filter (stateless) → L4 stateful firewall → L7 WAF. Each layer catches different attacks. A real production stack uses all three.