An application connects successfully, a firewall rule changes, and the existing connection keeps behaving as it did before. That can be correct: stateful NAT usually selects a binding when a flow is first processed and reuses it for later packets.
To reason about that behavior, separate three jobs: identifying the flow, deciding whether traffic is allowed, and translating addresses or ports. Conntrack, filtering, and NAT cooperate, but none is a synonym for the others.
A flow has two directions
For a simple TCP flow, a tuple includes source and destination addresses, source and destination ports, and the transport protocol. Conntrack maintains information for the original and reply directions. Network namespaces and conntrack zones can distinguish traffic that would otherwise have identical tuples.
- Identify flow
- Associate conntrack entry
- Apply policy
- Use NAT binding
- Recognize reply
Consider an illustrative client 10.0.0.24:42100 connecting to 203.0.113.10:443. Source NAT might make the peer observe 198.51.100.20:42100. The return packet addresses the translated endpoint; the tracked mapping lets the host restore the original destination before delivery. These are documentation addresses, not live hosts.
NAT is a binding, not a per-packet search through every rule
With stateful NAT, the first packet establishes a mapping using the NAT rules. Subsequent packets use the stored binding. Changing a rule therefore does not necessarily rewrite an existing connection’s behavior.
SNAT changes the source; DNAT changes the destination. The reverse-direction transformation follows the connection state. That does not imply arbitrary packets can be forwarded: routing, filter policy, reverse-path checks, and the destination service still have to cooperate.
Conntrack state such as new, established, or related is a classification for policy. It should not be confused with a complete description of the TCP state machine, nor with an application’s authenticated session. A matching conntrack entry proves neither authorization nor successful application processing.
Inspect before changing state
On an authorized Linux lab host with the relevant utilities, begin with read-only observations:
sudo conntrack -L -p tcp
sudo conntrack -S
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
sudo nft list ruleset
Privileges, namespaces, and kernel configuration affect what you can see. Run the commands in the namespace containing the workload. The listing can contain sensitive endpoint information; do not post an unredacted dump.
Correlate both directions of a specific connection with the applicable rules and routes. A table-wide count is not a per-application diagnosis. An empty entry listing may mean the wrong namespace, untracked traffic, or that the flow already expired.
Avoid flushing conntrack to “refresh NAT” on a shared system. That can disrupt unrelated connections and destroy the evidence you are investigating.
Diagnose exhaustion without treating the maximum as a magic knob
When tracking capacity is exhausted, new flows can fail even while established ones continue. Useful evidence includes count relative to the configured limit, insertion-failure or drop counters, connection churn, and logs. Interpret counters over an interval rather than comparing old cumulative totals.
Increasing capacity costs memory and may not fix the cause. Very short-lived connections, inappropriate timeouts, or a workload leak can consume the new headroom too. Record flow arrival rate, lifetimes, memory pressure, and whether the tracking state is actually required.
Recovery has more than one dependency
An endpoint change does not transparently move an established TCP session to an unrelated server. Even if addresses are translated, the remote TCP state, application state, and protocol recovery rules still matter. This is particularly important for NFS client behavior.
Use the outbound packet model to inspect a simplified SNAT and reply path. It is a conceptual demonstration, not evidence about your firewall’s live state. This article reports no throughput improvement from changing tracking or timeout settings.
Further reading
Primary references behind this explanation. Consult documentation for the version and environment you actually run.