Firewalls & Network Security
Firewalls & Network Security
A firewall is the first line of defence for every host and every network segment in your infrastructure. As a DevOps engineer you will configure and debug firewalls daily — on bare-metal servers, inside Kubernetes nodes, and through cloud-provider abstractions. Understanding what sits behind the GUI checkbox is the difference between shipping a working ruleset and opening an accidental hole in production.
Packet Filtering — The Core Mental Model
Every firewall applies a decision to each packet: ACCEPT, DROP, or REJECT. Rules are evaluated in order; the first match wins. At the end of every chain sits a default policy. The only production-safe defaults are DROP on INPUT and FORWARD, ACCEPT on OUTPUT. Starting from deny-all and allowing only what is needed is a security fundamental — it is the principle of least privilege applied to traffic.
Firewalls operate at different layers. A pure packet filter (Layer 3/4) inspects only source IP, destination IP, protocol, and port. A stateful firewall also tracks the state of connections — whether a packet is part of an established session, a new connection request, or an invalid out-of-context packet. Stateful filtering is what makes it safe to have a permissive OUTPUT policy: the firewall automatically allows return traffic for connections your host initiated without requiring explicit inbound rules.
iptables — Linux Packet Filtering from First Principles
iptables is the traditional Linux firewall interface, still running on the majority of production Linux systems including Docker hosts and pre-1.29 Kubernetes nodes. It organises rules into tables (filter, nat, mangle, raw) and chains (INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING). For host security the filter table is all you need.
DROP silently discards the packet; the sender waits until it times out. REJECT sends an ICMP "port unreachable" immediately. On the internet, DROP is preferred for inbound because it gives attackers no confirmation that the port exists. Inside a trusted network, REJECT speeds up debugging by failing fast. Use REJECT in the FORWARD chain between internal segments so your developers get quick feedback on misconfigured service calls.
nftables — The Modern Replacement
nftables ships as the default on Debian 10+, RHEL 8+, and Ubuntu 22.04+. It replaces iptables, ip6tables, arptables, and ebtables with a single unified framework. The rule language is more expressive, evaluates faster using kernel-side maps and sets (no linear scan for IP allowlists), and the configuration is a single coherent file rather than a sequence of CLI commands.
nft add element inet filter blocklist { 1.2.3.4 } command adds an IP to a set atomically with no rule flush — zero downtime, sub-millisecond effect.
Cloud Security Groups — Stateful Filtering as a Service
AWS Security Groups, GCP Firewall Rules, and Azure NSGs are the cloud-native equivalent of a stateful firewall. They are enforced at the hypervisor level — traffic that the security group blocks never reaches the instance, not even the NIC. This means they cannot be bypassed by misconfiguring iptables inside the VM.
Key properties of AWS Security Groups that trip up engineers:
- Stateful by default. If you allow port 443 inbound, the return traffic is automatically permitted — you do not need an outbound rule for port 443 responses.
- Allow-only. There is no deny rule in a security group. To block specific traffic you must use a Network ACL (NACL), which is stateless and does have explicit deny rules.
- Attached to ENIs, not instances. An instance with two network interfaces can have different security groups on each interface — important for multi-homed bastion or proxy designs.
- Source can be another security group ID. Instead of hard-coding IP ranges that change as you scale, reference the security group of the calling tier directly:
sg-0abc123 (app-servers)→sg-0def456 (rds-mysql)on port 3306. Auto-scales correctly.
Stateful vs. Stateless Filtering — When Each Applies
Network ACLs (NACLs) in AWS are stateless: you must write explicit rules for both directions of a flow. They also evaluate rules in numeric order (100, 200, 300…) and stop at the first match, including explicit DENYs. NACLs are your last-resort blocklist — use them to deny specific CIDR ranges at the subnet boundary when a security group cannot express a deny. In practice, most teams use Security Groups for allow-list logic and NACLs only for broad IP-range blocking (known bad actor ASNs, geographic blocks).
Common Failure Modes and How to Debug Them
- Rule order error: A broad ACCEPT before a specific DROP means the DROP is never reached. Always put specific rules before general ones. On
iptables, useiptables -L -n -v --line-numbersto inspect order and hit counters. - New chain never linked: Creating a custom chain with
iptables -N my-chaindoes nothing unless you jump to it from INPUT with-j my-chain. Forgetting the jump is a silent no-op. - Security group too permissive:
0.0.0.0/0on port 22 is the single most common cloud misconfiguration found in production breach post-mortems. Replace with the CIDR of your VPN or bastion host. - Docker overwriting iptables: Docker inserts rules into the FORWARD chain and the
DOCKERandDOCKER-USERchains. If you flush iptables manually, Docker-managed containers lose network connectivity. Add your custom rules to theDOCKER-USERchain, which Docker never overwrites.
nftables.conf or Terraform security group resources in version control, enforce peer review on changes, and run automated compliance checks (AWS Config rules, opa policies) that alert when 0.0.0.0/0 appears on sensitive ports. Manual firewall changes in production are a change-management anti-pattern.