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.