26.7 Connection Tracking: ESTABLISHED, RELATED, NEW, INVALID States
Right, let’s talk about the magic trick that makes stateful firewalls not just bearable, but actually useful: connection tracking (conntrack). Without this, you’d be trying to write a coherent novel by individually approving or rejecting every single letter someone tries to type. It would be a nightmare. Connection tracking is the firewall’s memory—it remembers conversations so you can write rules about what is being said, not just the raw packets.
The kernel keeps a table of all the connections it sees (you can peek at it with conntrack -L). For each one, it slaps on a label: NEW, ESTABLISHED, RELATED, or the dreaded INVALID. Your firewall rules can then key off these states instead of getting bogged down in the minutiae of ports and flags. This is why you can have a simple rule like “allow outgoing web traffic and the responses,” which is infinitely smarter than trying to manually allow the return packets for every single new outbound connection.
The Four States of Packet Grief
Let’s break down what these labels actually mean. It’s more nuanced than it first appears, and getting it wrong is a classic way to lock yourself out of your own server.
NEW: This isn’t “a new packet.” It’s the first packet of a new conversation that the connection tracker doesn’t already know about. For a classic TCP SYN packet, this is straightforward. For UDP, it’s… fuzzier. Since UDP is connectionless, the first UDP packet the firewall sees for a flow is labelled
NEW. The key thing to remember:NEWrefers to the connection, not the packet. You’ll typically allowNEWpackets on the input chain only for services you want to offer to the world.ESTABLISHED: This is the easy one. If a packet is part of a connection that’s already been seen and tracked (i.e., it successfully got through the
NEWstage), it’sESTABLISHED. The beauty is that this works bidirectionally. Once an outgoing SSH connection is established, the returning packets—even though they’re coming into your machine—are markedESTABLISHED. This is why your “allow outbound” rule needs--state ESTABLISHED,RELATEDon theINPUTchain to let the responses back in. It’s non-negotiable.RELATED: This is the cool one. A
RELATEDpacket is starting a new connection, but that new connection is intrinsically related to an existing one. The textbook example is FTP. When you connect to an FTP server on port 21 (control connection), the server will later try to open a new connection back to you on a random high port (the data connection). Without theRELATEDstate, you’d have to allow all incomingNEWconnections on ports 1024-65535, which is… a bad idea. Theconntrackmodule understands the FTP protocol and can see that the data connection request is related to the established control connection, so it labels itRELATED. The same logic applies to ICMP error messages (like “Fragmentation Needed”) related to a TCP connection.INVALID: This is the kernel’s way of throwing a packet into the bin because it makes no sense in the context of its connection tracking table. It could be a TCP packet with nonsense flags, a packet that looks like a response to a connection that never existed, or just general corruption. Your default policy for this should almost always be
DROP. Don’t even acknowledge this garbage exists.
The Classic, Essential Rule You Cannot Live Without
This is the cornerstone of any stateful firewall. It’s the rule that lets the internet talk back to you. You’ll see it (or a variant using conntrack modules) in every sane configuration.
# iptables (the legacy but still pervasive king)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# nftables (the sleek new successor)
nft add rule ip filter input ct state established,related accept
This rule says: “If a packet is part of an ongoing conversation, or is starting a new one related to an existing conversation, just accept it immediately.” You put this rule high up in your INPUT chain, often right after allowing loopback traffic. It’s your first line of defense against having to write countless allow rules for return traffic.
The nftables vs. iptables Syntax Shift
This is where the designers of nftables clearly decided to fix some of the jank of iptables. The -m conntrack --ctstate incantation is a mouthful. nftables simplifies it into a much cleaner native syntax.
# iptables: Feels like you're assembling a ritual from ancient fragments
iptables -A INPUT -m conntrack --ctstate NEW -p tcp --dport 22 -j ACCEPT
# nftables: Clean, readable, and logical
nft add rule ip filter input tcp dport 22 ct state new accept
See? No more manually loading match (-m) modules for core functionality. It’s a small but meaningful quality-of-life improvement.
The UDP Conundrum and Pitfalls
Here’s the rough edge: UDP. Since it’s stateless, connection tracking has to fake it. The first packet is NEW. The next packet from the same source:port to the same dest:port is ESTABLISHED. This works… until it doesn’t.
The big gotcha is with protocols that have long pauses between requests. The conntrack table has a timeout. For UDP, it’s usually 30 seconds. If a packet arrives after the timeout has expired, it’s considered NEW again. If your firewall rules are overly strict and only allow NEW packets from specific sources, a UDP response that’s just a bit too slow might get dropped because it’s no longer part of the tracked flow. It’s a pain. This is why for some UDP-based protocols (like VoIP), you might need to tweak conntrack timeouts or be more liberal with your rules.
Peeking Under the Hood
When things go weird—and they will—you need to be able to see what the kernel sees. The conntrack tool is your debugger.
# Watch the connection tracking table in real-time
conntrack -E
# List all current tracked connections
conntrack -L
# See the exact timeout for a specific UDP flow
conntrack -L -p udp --dport 5060
# Delete a specific stuck connection (a lifesaver for debugging)
conntrack -D -p tcp --dport 80 --orig-src 192.168.1.10
The takeaway? Stop thinking about packets and start thinking about conversations. Your rules become simpler, more secure, and infinitely more powerful. The ESTABLISHED,RELATED rule is the most important rule in your entire config. Never leave home without it.