Firewalls
Firewalls allow or deny traffic by rules. See why a stateful firewall needs one rule where a stateless one needs two, and how cloud security groups and network ACLs map onto those models.
🎯 What you'll learn
- What a firewall decides on
- Stateless vs stateful filtering
- Ingress vs egress and default-deny
- Security groups vs network ACLs
📚 Before you start
1What a Firewall Actually Does
A firewall inspects traffic crossing a boundary (between networks, or between a host and its network) and decides, packet by packet or connection by connection, whether to allow or deny it, based on a set of rules. It sits precisely at the kind of boundary described in the routing/subnets topic — the point where traffic crosses from one administrative zone into another, and where enforcing policy actually makes sense.
A rule is fundamentally a match on some combination of:
Source IP/subnet Destination IP/subnet Protocol (TCP/UDP/ICMP) Port Direction (in/out)ALLOW from 0.0.0.0/0 to any TCP 443 inbound (let the world reach HTTPS)
ALLOW from 10.0.0.0/16 to any TCP 22 inbound (SSH, but only from the internal network)
DENY from 0.0.0.0/0 to any TCP 22 inbound (block SSH from everywhere else)2Stateless vs Stateful Filtering
A stateless firewall evaluates every packet independently, with no memory of prior packets. This means a stateless firewall needs two rules for ordinary bidirectional traffic: one allowing the outbound request, and a separate one explicitly allowing the inbound response — because the firewall has no concept of "this inbound packet is a reply to a connection I already approved."
Stateless, allowing a client to make outbound HTTPS requests and receive replies:
ALLOW outbound TCP dst port 443 (the request leaving)
ALLOW inbound TCP src port 443 (the response coming back — separate rule!)A stateful firewall tracks active connections in a connection tracking table (source/dest IP, port, protocol, and connection state). Once an outbound packet is allowed, the firewall automatically permits the matching return traffic without needing a separate explicit rule — because it remembers the connection was initiated locally and approved.
Stateful, same scenario:
ALLOW outbound TCP dst port 443
→ return traffic for THIS SPECIFIC connection is auto-permitted; no second rule needed
→ an unsolicited inbound packet claiming to be "from port 443" that doesn't match a tracked
connection is still droppedStateful is the overwhelmingly common default today (most host firewalls, most cloud security groups) because it's both simpler to configure correctly and more secure — a stateless ruleset that's slightly too permissive on the "return traffic" rule can accidentally open inbound access far wider than intended.
3Ingress vs Egress
Ingress rules govern traffic coming into the protected boundary; egress rules govern traffic leaving it. Both directions can be filtered independently.
Ingress: what's allowed to reach this server/subnet from outside
Egress: what this server/subnet is allowed to send outwardA common oversight is configuring careful ingress rules while leaving egress wide open — but egress filtering matters too: it limits what a compromised host inside the boundary can do (e.g. exfiltrate data to an arbitrary external IP, or reach out to a command-and-control server), independent of how it got compromised in the first place.
4Default-Deny vs Default-Allow
Every firewall ruleset needs a default policy for traffic that matches no explicit rule.
Default-deny: nothing gets through unless a rule explicitly allows it
Default-allow: everything gets through unless a rule explicitly blocks itDefault-deny is the standard security posture for anything facing untrusted networks (the public internet, in particular): you enumerate exactly what should be reachable (a specific port for a web server, say) and everything else is blocked by default, including ports and services you didn't even think to block because you never opened them in the first place. Default-allow requires you to anticipate and explicitly block every bad thing in advance, which is a losing game against an evolving threat landscape — it's essentially never the right default for an internet-facing boundary, though it sometimes appears (usually accidentally) in permissive internal-network configurations.
5Security Groups vs Network ACLs (Cloud Context)
Cloud platforms typically offer two layers of network-level filtering, and the distinction trips people up constantly:
Security Group (SG) Network ACL (NACL)
------------------------------ ------------------------------
Attached to: individual Attached to: an entire subnet
instances/resources
Stateful (return traffic Stateless (must explicitly
auto-allowed) allow both directions)
Only ALLOW rules (implicit Explicit ALLOW and DENY rules,
deny for anything not evaluated in numbered order
listed) (first match wins)
Evaluates ALL rules before Evaluates rules in order,
deciding (order doesn't stops at first match
matter)A security group is the fine-grained, per-resource layer ("this specific database instance only accepts port 5432 from this specific application security group"). A network ACL is the coarser, per-subnet layer, often used as a blunt backstop — e.g. explicitly denying a known-bad IP range at the subnet boundary regardless of what any individual instance's security group says, or as defense-in-depth in case a security group gets misconfigured.
Traffic into a resource inside a subnet must pass both layers: the NACL first (subnet boundary), then the security group (resource boundary) — either one denying it is enough to block the packet.
⚠️ Common Pitfalls
- Forgetting stateless firewalls need explicit return-traffic rules — a NACL-style stateless ruleset that only allows outbound traffic, with no matching inbound allow for the response, silently breaks every connection; this is one of the most common cloud networking debugging traps.
- Leaving egress wide open while locking down ingress tightly — a compromised host with unrestricted egress can exfiltrate data or reach a C2 server freely, even if nothing can get in to it directly.
- Defaulting to allow-all "just to get it working," then forgetting to lock it down — a temporary default-allow rule added during debugging is one of the most common ways an internet-facing resource ends up unintentionally exposed.
- Confusing security group statefulness with NACL statelessness — assuming a NACL will auto-permit return traffic the way a security group does leads to rulesets that mysteriously block traffic that "should" work.
- Over-scoping a rule's source — writing
0.0.0.0/0for a rule that should really be scoped to a specific internal subnet or a known partner IP range, because it's the fastest way to "make the error go away," is one of the most common causes of unintended public exposure.
📋 Quick Reference
Rule = source + destination + protocol + port + direction → ALLOW or DENY
Stateless: no memory of connections — needs explicit rules for BOTH directions
Stateful: tracks connections — return traffic auto-permitted once outbound is allowed
Ingress = inbound traffic filtering Egress = outbound traffic filtering
Default-deny (standard for internet-facing) vs default-allow (rarely correct there)
Cloud:
Security Group = per-resource, stateful, ALLOW-only (implicit deny)
Network ACL = per-subnet, stateless, explicit ALLOW+DENY, ordered, first-match-wins
Traffic must pass BOTH layers to reach a resource🧠 Key takeaways
- Firewalls filter on IP, port, protocol (and state; L7 firewalls inspect content).
- Stateful tracks connections, so return traffic is automatic; stateless judges each packet and needs rules both ways.
- Start default-deny, open the minimum; filter egress too (limits exfiltration).
- AWS: security groups = stateful, per-ENI, allow-only; NACLs = stateless, per-subnet, ordered allow/deny.
🎤 Interview Q&A
Q1Stateful vs stateless firewalls?core▾
Stateful firewalls track connections and automatically allow return traffic (AWS security groups). Stateless ones evaluate each packet independently, so you must allow both directions explicitly, including ephemeral ports (AWS network ACLs).
- Which is more convenient? Stateful.
Q2What's the principle of least privilege for network rules?core▾
Deny by default and allow only required sources, ports and protocols: the load balancer to app instances on the app port, app instances to the database on 5432, SSH only via a bastion or SSM, never 0.0.0.0/0 to databases.
- How do you reference other tiers in AWS? Security group references instead of IP ranges.
Q3What's a WAF and how is it different from a network firewall?senior▾
A Web Application Firewall inspects HTTP (layer 7) to block attacks like SQL injection, XSS, bad bots and request floods, using managed rule sets and rate limits. Network firewalls filter by IP/port (L3/L4).
- Is a WAF a substitute for secure code? No; it's defence in depth.
Q4What is egress filtering and why do it?core▾
Restricting outbound traffic to known destinations. It limits data exfiltration and command-and-control if a server is compromised, and blocks SSRF to internal endpoints.
- How in Kubernetes? NetworkPolicies with egress rules.
Q5How do you debug 'connection timed out' vs 'connection refused'?core▾
Refused: the host is reachable but nothing listens on the port (or it actively rejects). Timed out: packets are dropped, typically by a firewall/security group, routing problem, or the host is down.
- Next steps for a timeout? Check security groups, NACLs, route tables and the host's local firewall.
🛠️ Practice exercises
Each exercise is a file in this topic folder. Code exercises are self-checking: run them and make the checks pass.
✅ Check yourself
Answer the questions — feedback is instant.