← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

iptables and netfilter

linux Advanced
debt(d9/e3/b5/t9)
d9 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'silent in production until users hit it' (d9). detection_hints.automated is 'no'; the listed tools (iptables-save, conntrack, nft) only let you inspect state manually — there is no automated linter for rule-order or missing ESTABLISHED,RELATED logic. A misordered rule produces no error; traffic is silently dropped or silently allowed until someone is locked out or the host is found exposed.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is a known pattern: insert loopback + conntrack ESTABLISHED,RELATED rules before the DROP policy and reorder specific-before-broad, then iptables-save. It's more than a one-line swap (multiple rules in correct order) but stays within the firewall ruleset of one host.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). applies_to is cli-only, but the firewall is load-bearing for all network traffic to/through the host; every new service, container, or gateway change must reckon with chain order and state handling, slowing many operational work streams that touch connectivity.

t9 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'catastrophic trap' (t9). The misconception states the canonical wrong belief exactly: developers assume adding an ALLOW rule opens a port, but first-match-wins ordering plus default DROP and missing ESTABLISHED,RELATED means the 'obvious' approach is reliably wrong — and a misstep over SSH locks you out of the server entirely.

About DEBT scoring →

Also Known As

iptables netfilter linux firewall iptables rules

TL;DR

Kernel packet-filtering framework (netfilter) and its classic userspace tool (iptables) for firewalling, NAT, and packet mangling.

Explanation

netfilter is the in-kernel framework that hooks into the Linux network stack at fixed points, and iptables is the traditional userspace tool that programs its rules. Packets traverse a set of tables, each containing chains of rules evaluated in order. The filter table (chains INPUT, OUTPUT, FORWARD) accepts or drops traffic. The nat table (PREROUTING, POSTROUTING, OUTPUT) rewrites source/destination addresses for SNAT, DNAT, and masquerading. The mangle table alters packet fields like TOS or TTL, and the raw table can mark packets to skip connection tracking. Each chain has a default policy (ACCEPT or DROP) applied when no rule matches. Rules match on interface, protocol, source/destination address and port, connection state, and more, then jump to a target: ACCEPT, DROP, REJECT, LOG, DNAT, SNAT, MASQUERADE, or a user-defined chain. The order of packet flow matters: an incoming packet hits PREROUTING (raw, mangle, nat), then a routing decision sends it to INPUT (for local delivery) or FORWARD (for routing), and outgoing packets traverse OUTPUT and POSTROUTING. Connection tracking (conntrack) lets you write stateful rules with -m state or -m conntrack, so you allow ESTABLISHED,RELATED traffic without opening every return port. Rules are not persistent across reboots unless you save them (iptables-save / iptables-restore, or a service like netfilter-persistent). On modern systems iptables is increasingly a compatibility shim over nftables (the iptables-nft backend), and firewalld or ufw often manage the rules for you. Understanding the table and chain model is essential for debugging dropped connections, building NAT gateways, securing containers, and reasoning about why traffic arrives or vanishes.

Common Misconception

Adding an ALLOW rule is enough to open a port. In reality rules are evaluated in order and the first match wins, so an earlier DROP or a default DROP policy combined with missing ESTABLISHED,RELATED handling can block your traffic regardless of a later ACCEPT rule.

Why It Matters

Firewall misconfiguration either locks you out of a server or silently leaves it wide open; understanding chain order and connection state is the difference between a secure host and a broken or exposed one.

Common Mistakes

  • Setting a default DROP policy on INPUT without first allowing loopback and ESTABLISHED,RELATED traffic, breaking all responses.
  • Forgetting to save rules, so a carefully built firewall vanishes on reboot.
  • Putting a broad ACCEPT rule before specific DROP rules, since the first match wins and later rules never run.
  • Locking yourself out of SSH by applying a DROP policy over a remote session before adding the allow rule.
  • Confusing the INPUT chain (traffic to the host) with the FORWARD chain (routed traffic), so container or gateway traffic is filtered in the wrong place.

Avoid When

  • You only need simple host firewalling and a higher-level tool like ufw or firewalld already manages rules cleanly.
  • The system uses nftables natively and hand-written iptables rules would conflict with the nft ruleset.
  • Container or orchestration runtimes (Docker, Kubernetes) are already managing the netfilter rules and manual edits would be overwritten.
  • You need per-application policy that is better expressed with cgroups, eBPF, or a service mesh.

When To Use

  • Building a stateful host firewall on a server where you control the rule order precisely.
  • Setting up NAT or masquerading on a gateway or router.
  • Filtering forwarded traffic between network namespaces or containers.
  • Debugging dropped or rewritten packets where you need to inspect chains, counters, and connection state.

Code Examples

✗ Vulnerable
# Lock yourself out and break everything:
# Set default DROP first, over an SSH session, with no allow rules yet.
iptables -P INPUT DROP
# Connection freezes immediately - no loopback, no ESTABLISHED allowed.

# Or: ACCEPT before the DROP, so the DROP never runs.
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -j ACCEPT          # matches everything first
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.5 -j DROP  # never reached

# And rules are gone after reboot because nothing was saved.
✓ Fixed
# Build a stateful firewall in the right order:
# 1. Allow loopback and existing connections BEFORE any DROP.
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 2. Allow SSH from a trusted subnet (specific rule first).
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/24 -j ACCEPT

# 3. Allow HTTP/HTTPS.
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# 4. Only now set the restrictive default policy.
iptables -P INPUT DROP
iptables -P FORWARD DROP

# 5. Persist across reboots.
iptables-save > /etc/iptables/rules.v4
# (or: netfilter-persistent save)

# Inspect what is active, with rule numbers and counters:
iptables -L INPUT -n -v --line-numbers

Added 7 Jun 2026
Views 5
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 2 pings S 0 pings M 2 pings T 1 ping W
Ahrefs 1
Scrapy 2
Google 2 Scrapy 2 Ahrefs 1
crawler 5
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Always allow loopback and 'conntrack --ctstate ESTABLISHED,RELATED' before setting a DROP policy, order specific rules before broad ones, and save with iptables-save so rules survive reboot.
📦 Applies To
bash cli firewalld ufw nftables docker
🔗 Prerequisites
🔍 Detection Hints
iptables -P (INPUT|FORWARD) DROP without preceding ESTABLISHED,RELATED or loopback ACCEPT; broad '-j ACCEPT' before specific DROP rules; missing iptables-save
Auto-detectable: ✗ No iptables iptables-save nft conntrack firewalld
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: High Context: File Tests: Regenerate

✓ schema.org compliant