The rule you wrote permits one direction. The reply comes back anyway, because the firewall is keeping a table of every conversation and knows the reply belongs to a flow it already allowed.

That table is the difference between a firewall and an access list, and it is also a resource with a size, a timeout, and failure modes. When it fills up, new connections fail while existing ones keep working — one of the most confusing symptoms in networking.

What a flow is

A flow is identified by five values:

source IP : source port  ->  destination IP : destination port  (protocol)

The firewall stores the state with a timeout per protocol. A TCP flow that has completed its handshake gets a long timeout (hours); a UDP flow gets a short one (seconds to a minute), because there is no handshake to prove it is alive.

Protocol Typical state timeout Consequence
TCP established 1–24 hours (vendor) Long-lived sessions survive idle periods
TCP SYN sent 30–120 seconds Half-open connections expire
UDP 30–180 seconds Replies after the timeout are dropped
ICMP 10–60 seconds Ping replies outside the window fail

Why the return path must match

Because the state is keyed on the tuple, the reply must traverse the same firewall. If the outbound packet goes through the fiber and the return comes back through the VPN, the firewall on the VPN path has no state entry and drops the packet.

That is why asymmetric routing and stateful firewalls do not coexist. You either make the paths symmetric, or you put a stateful device in both paths (and accept that state is duplicated), or you stop being stateful for that flow.

One flow, one state entry: the reply is permitted because the request was seen.

The table has a size

Every platform has a maximum concurrent flow count, from tens of thousands on small gateways to millions on data-center hardware. At a district of a few thousand devices, the peak is usually well within limits — but the failure mode when it is not is distinctive:

  • Existing connections continue to work.
  • New connections fail, often with a timeout rather than a reset.
  • CPU may look normal; memory for the table is the constraint.
  • The table fills fastest during a scan, a DDoS, or a misconfigured client opening thousands of short-lived flows.

A single misbehaving device can do it: a camera retrying a connection in a tight loop, or a Chromebook app opening sockets per request.

Half-open connections are the cheapest attack

Flooding SYNs without completing the handshake fills the table with entries that expire slowly. Rate limiting new connections per source is the usual mitigation, and it is worth enabling before you need it.

Timeouts are a design choice

Short timeouts free table space quickly and break long idle sessions. Long timeouts are friendlier to applications and hold memory longer.

Practical settings:

  • Keep TCP established generous (several hours) for databases and long-lived SSH.
  • Keep UDP short enough to free space, long enough for DNS and voice.
  • Do not lower timeouts to "improve security." You will break something at 22:00 and not know why.

Worked example: 500 students at 08:00

A rough estimate: each device holds 20–60 concurrent flows during a class change (browser tabs, Google services, MDM check-ins). Five hundred devices × 40 flows ≈ 20,000 entries, plus servers, cameras, and voice.

That is comfortably inside a midrange gateway's table. Multiply by three for a 1,500-device campus and you are at 60,000, still fine — but a single classroom of devices reinstalling an OS image can add thousands of short-lived flows in a minute.

The lesson is not the exact number. It is that table size is a capacity you can estimate, and that the symptom of exhaustion (new connections fail, old ones work) should be on your list of known failures.

What breaks in production

  • Asymmetric return path. State exists on one device only; the reply is dropped. Ping works one way, TCP never completes.
  • Table exhaustion. New sessions time out while established ones continue. Often blamed on the ISP until you look at the flow count.
  • Aggressive timeouts. Voice calls drop after 30 seconds of silence; database connections die overnight.
  • State not synchronized in an HA pair. A failover moves traffic to a device with an empty table, and every existing session resets.
  • NAT and state disagreeing. The translation entry expires before the state entry (or vice versa), producing one-way traffic on long-lived flows.

Checklist

  1. You know the table size and the current utilization of your gateway.
  2. Timeouts match the applications you actually run.
  3. Return paths are symmetric, or stateful inspection is applied on both.
  4. New-connection rate limiting is enabled.
  5. An HA pair synchronizes state, and a failover has been tested with a live session.

Next

State decides what gets back. NAT decides what the far side sees. Continue with NAT Without the Mystique.

  • Firewall
  • Conntrack
  • Stateful
  • Troubleshooting