NAT, conntrack, and UDP shred delivery
UDP has no connection state, but NAT and firewalls create timed conntrack entries for each flow tuple. Inbound shred delivery needs a stable public mapping and an explicit rule for source IP 64.130.40.90 and the destination UDP port. Monitor table occupancy, conntrack failures, firewall counters, socket delivery, and feed progress across timeout and restart tests.
operations desk · updated 2026-08-31
UDP is stateless, network devices are not
UDP has no handshake, established session, FIN, or reset. A sender emits datagrams to an address and port. Firewalls and NAT devices still create state-like entries so they can apply return-path policy and translate subsequent packets consistently. Linux calls this connection tracking, or conntrack.
A tracked UDP flow is normally keyed by protocol, source address and port, and destination address and port, with a reply tuple stored beside it. The entry expires on a timer because UDP never closes it. Traffic refreshes the timer according to the implementation and state.
This pseudo-state creates failure modes that do not appear in the socket API. A NAT mapping can expire during silence. A conntrack table can fill. A firewall can classify the first inbound packet as new and drop it before the receiver starts. The UDP application sees only silence unless network counters and control-plane state are monitored.
Inbound delivery needs a stable public mapping
A receiver with a directly assigned public IP can bind the intended UDP port and permit the source in its host and provider firewalls. A receiver behind NAT needs a static port-forwarding rule or an outbound-created mapping whose behavior the service understands. Consumer NAT behavior is rarely an appropriate foundation for a continuous market-data feed.
Endpoint-dependent mappings may use different public ports for different destinations. Carrier-grade NAT may not permit inbound unsolicited traffic at all. Cloud load balancers and public-IP objects have their own UDP idle timeouts and health semantics. Verify the exact product rather than reasoning from the word NAT.
The destination registered with the provider must be the externally reachable address and port. The internal process can still bind 0.0.0.0:9000 or a private address, but DNAT must translate the public tuple consistently to it. Return traffic, if any, should follow the same stateful path.
The first packet is usually NEW
Linux conntrack marks a previously unseen UDP tuple as NEW even though no handshake exists. After packets appear in both directions, conntrack can mark the flow as assured and use the longer UDP stream timeout. The words NEW and ESTABLISHED describe tracked state, not TCP protocol state.
A one-way feed may never produce reply traffic. It can remain unassured and use net.netfilter.nf_conntrack_udp_timeout rather than net.netfilter.nf_conntrack_udp_timeout_stream. Common distributions often set these to tens of seconds and a few minutes, but deployed values are the only authority.
An input firewall rule accepting only ct state established,related can therefore reject the first feed packet and every subsequent packet if no permitted NEW packet creates state. Add an explicit source, protocol, and destination-port allow rule before a generic deny. Count it so packet arrival at the firewall is observable.
Source filtering is concrete and limited
shredstream.sh publishes 64.130.40.90 as the source IP for verification and the shred stream. A host firewall can restrict UDP port 9000 to that source. This reduces scanning, accidental traffic, and packet-processing work from unrelated senders.
The rule does not cryptographically authenticate a packet. Source addresses can be spoofed where upstream networks permit it, and a compromised authorized sender remains authorized at the IP layer. Shred signature and protocol validation still belong in the receiver.
Filtering only by source IP may be necessary if the source port is not a documented product constant. Do not lock a firewall to a port observed in one capture unless the provider guarantees it. Destination port and source IP are stable facts in the customer's activation configuration.
Linux exposes table capacity and use
net.netfilter.nf_conntrack_max is the maximum number of tracked entries. net.netfilter.nf_conntrack_count reports current use. These sysctls appear when conntrack support is loaded and visible in the network namespace. A table near capacity can drop new flows and log table-full messages subject to rate limiting.
The conntrack command from the conntrack-tools package lists and filters entries. conntrack -L -p udp --dport 9000 shows tracked UDP entries targeting the example port. conntrack -S prints subsystem statistics such as insert_failed, drop, early_drop, and search_restart where the kernel exports them.
One stable feed tuple consumes roughly one entry, regardless of 5,585 packets/sec. Conntrack capacity becomes a concern when the host also serves many clients, receives spoofed tuples, uses many network namespaces, or runs Kubernetes and NAT-heavy workloads. Packet rate drives per-packet lookup cost, while flow count drives table occupancy.
UDP timeouts define silence tolerance
net.netfilter.nf_conntrack_udp_timeout controls the timeout for ordinary UDP entries. net.netfilter.nf_conntrack_udp_timeout_stream controls entries considered bidirectional streams. Read both with sysctl on the target host. Do not assume distribution defaults.
A timeout expiring is harmless for an inbound flow when the firewall permits a fresh NEW packet and no NAT mapping is required. The next packet creates a new entry. Expiry is disruptive when an upstream NAT mapping is the only route for inbound traffic or a firewall policy permits only existing state.
Keepalives can refresh mappings, but they need a sender and an agreed message. A receiver cannot force a remote one-way publisher to honor an arbitrary keepalive. Static destination forwarding is clearer. If the feed naturally emits continuously, normal traffic refreshes state, but planned feed silence and provider maintenance should still be tested.
Table exhaustion drops unrelated new flows
Conntrack allocates state for new tuples before later filter decisions in the normal tracked path. A flood of spoofed UDP packets can therefore consume table capacity even if a filter eventually drops them. Workloads such as DNS, Kubernetes services, and outbound client traffic also create many short-lived entries.
When the table is full, Linux cannot track a new flow. Kernel logs may contain a message that the nf_conntrack table is full and a packet was dropped. conntrack -S counters and the count-to-max ratio provide a more dependable continuous signal than logs alone.
Raising nf_conntrack_max increases possible memory use and hash-chain work. It may be correct on a NAT gateway sized for many flows. On a dedicated one-flow receiver, a full table indicates unrelated traffic or architecture. Removing that pressure is better than giving it more memory without a flow budget.
NOTRACK removes state for selected packets
The nftables notrack statement in a raw-priority prerouting chain can mark matching packets untracked before conntrack creates an entry. This reduces table work and makes capacity independent of that flow. A dedicated, strictly filtered one-way UDP feed is a plausible candidate.
NOTRACK changes later firewall semantics. ct state established rules no longer match, conntrack-based NAT cannot operate on untracked traffic, and tools such as conntrack -L cannot show the flow. The filter must explicitly accept ct state untracked or match the packet tuple without relying on tracked state.
At 5,585 packets/sec and one flow, conntrack lookup is unlikely to be the first bottleneck on a dedicated modern host. NOTRACK is not automatically worth the semantic and diagnostic change. Measure conntrack CPU or table pressure before adding it.
NAT and NOTRACK are usually incompatible
Source NAT and destination NAT use conntrack to maintain bidirectional translation. Marking traffic untracked before a DNAT port forward prevents the ordinary stateful NAT mechanism from translating it. A receiver behind Linux NAT should keep the forwarded flow tracked unless it uses a separate stateless mechanism with fully understood routing.
This is why a notrack rule copied from a bare-metal receiver can break a gateway deployment. Packet traversal order matters. Raw-priority hooks run before conntrack, destination NAT occurs later, and filter policy sees either tracked translated state or untracked original traffic according to rules.
Keep packet forwarding and ingestion on separate hosts when practical. The gateway owns NAT and connection state. The receiver owns low-latency socket processing. Separation simplifies both performance and security analysis.
Route symmetry also matters on a multihomed gateway. Linux conntrack records the reply tuple and NAT decision against the observed flow. Policy routing that returns replies through another gateway can create a second untranslated path or fail reverse-path checks. Inspect ip rule, ip route get for both endpoints, and rp_filter settings when challenge traffic succeeds only intermittently.
Cloud firewalls add another state table
Security groups, network ACLs, managed firewalls, load balancers, and public-IP gateways can evaluate traffic before the Linux NIC. Host nftables counters remain zero when an upstream control drops the packet. Cloud flow logs may show accepted or rejected tuples, but capture timing and sampling differ by provider.
Stateful security groups often treat return traffic differently from unsolicited inbound traffic. A raw inbound feed needs an explicit UDP ingress rule for the destination port and source address. A network ACL may need corresponding egress rules for challenge responses or ICMP, depending on stateless policy.
Document every enforcement point in order: provider edge, load balancer or NAT, subnet policy, host nftables, container network policy, and application socket. During an outage, find the first counter or capture that sees the expected packet.
Containers multiply conntrack boundaries
Docker and Kubernetes commonly program netfilter rules for service translation, pod networking, and masquerade. A packet can traverse host conntrack, DNAT to a container, virtual Ethernet queues, and another namespace's filter. kube-proxy mode and CNI determine the exact path.
HostNetwork can shorten the route but changes isolation. A dedicated host process avoids service translation, although operational requirements may favor containers. If a container is used, expose the exact UDP port directly, inspect host and namespace sockets, and collect conntrack plus interface counters at both layers.
The conntrack table may be host-wide while sysctl visibility or limits appear per namespace in confusing ways. Use nsenter with the target network namespace for ss, nft, and proc inspection. A clean container view does not exclude host-level drops.
nftables counters prove rule traversal
An nftables rule with counter records packets and bytes matching it. Place an explicit allow for source 64.130.40.90 and UDP destination port 9000, then inspect nft list ruleset during a test. A rising rule counter with no socket delivery moves the investigation after the firewall. A flat counter moves it earlier.
Rule order matters. A prior drop can prevent the allow counter from increasing. Use nft monitor trace only in a controlled, filtered diagnostic because trace output at packet rate can be large. Rule handles from nft -a list ruleset make specific updates possible through configuration management.
iptables compatibility layers can coexist with native nftables and confuse inspection. Determine whether iptables commands program nftables or legacy tables. One source of truth is safer than parallel rule systems.
Monitor both state and feed progress
Collect nf_conntrack_count, nf_conntrack_max, conntrack insert_failed and drop deltas, nft rule counters, NIC receive counters, UdpInDatagrams, UdpRcvbufErrors, socket drops, last-packet age, and newest slot. Each answers a different question.
A present conntrack entry does not prove recent packets. An entry can remain until timeout after the path fails. A rising nft allow counter does not prove the application keeps up. A receiver health check should require protocol-valid feed progress as the final signal.
Test cold start, timeout expiry, process restart, host reboot, public-IP reassociation, NAT failover, firewall reload, and provider silence. UDP has no connection event to cover these transitions, so operations must create explicit evidence.
Store the effective ruleset and sysctl values with each test result. A container image update, firewall controller, or cloud policy rollout can change reachability without touching receiver code. Configuration provenance shortens the gap between a flat last-packet timestamp and the network control that caused it.
In practice
A public Linux receiver listens on UDP port 9000 and should accept feed traffic only from 64.130.40.90. Inspect conntrack and add a counted nftables rule in an existing inet filter input chain:
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max sysctl net.netfilter.nf_conntrack_udp_timeout net.netfilter.nf_conntrack_udp_timeout_stream sudo conntrack -L -p udp --dport 9000 sudo conntrack -S sudo nft add rule inet filter input ip saddr 64.130.40.90 udp dport 9000 counter accept comment "shred feed" sudo nft -a list chain inet filter input
A representative conntrack row has this shape:
udp 17 28 src=64.130.40.90 dst=203.0.113.20 sport=41000 dport=9000 [UNREPLIED] src=203.0.113.20 dst=64.130.40.90 sport=9000 dport=41000 mark=0 use=1
The source port 41000 is illustrative and must not become a firewall requirement. The 28 is remaining timeout seconds in this example. UNREPLIED is expected for a strictly one-way flow.
After 60 seconds at 5,585 packets/sec, the nft rule should rise by about 335,100 packets, while nf_conntrack_count rises by one for one stable tuple. Compare:
sudo nft list chain inet filter input sudo conntrack -L -p udp --dport 9000 nstat -az UdpInDatagrams UdpInErrors UdpRcvbufErrors ss -u -a -n -m '( sport = :9000 )'
If the nft counter rises and UdpInDatagrams does not, inspect later host routing, namespace, and socket binding. If neither rises, inspect upstream security policy, NAT, and NIC capture. Do not add NOTRACK on a DNAT receiver. On a direct dedicated host, consider it only after conntrack counters or profiling show a real constraint.
What this does not cover
Conntrack defaults, counter availability, nftables hook behavior, and namespace scope vary by Linux kernel and distribution. Cloud NAT, firewall, and UDP idle policies are provider-specific and can change independently of host configuration. Read the deployed values and service documentation.
The nft add command assumes an existing inet filter table and input base chain. Production firewall changes should be made through the host's persistent configuration with rollback. The example source port and public documentation address are not shredstream.sh product facts and must not be used as a fixed source-port contract.
Related questions
- Does Linux conntrack track UDP traffic?
- Yes. Linux creates timed conntrack entries for UDP tuples even though UDP has no session handshake. The entry stores original and reply directions and expires according to UDP timeout sysctls. Bidirectional traffic may be treated as an assured stream and receive a longer timeout.
- Why does an established-only firewall block a UDP feed?
- The first packet of an unseen UDP tuple is classified as NEW by conntrack. A one-way feed may never create bidirectional assured state. Add an explicit allow for the documented source IP, UDP protocol, and destination port before the deny policy, then verify its packet counter.
- Does 5,585 packets per second create 5,585 conntrack entries?
- No. Conntrack entries are created per flow tuple, not per packet. One stable source address and port to one stable destination address and port generally uses one entry while traffic refreshes it. Many changing source ports or spoofed sources can create many entries.
- Should a shred feed be excluded from conntrack?
- A direct, dedicated, one-way receiver may use nftables notrack when measured conntrack cost or table pressure warrants it. At this feed rate, it is often unnecessary. NOTRACK removes conntrack-based NAT and established-state semantics, so a receiver behind DNAT should normally remain tracked.
- How is a UDP NAT timeout detected?
- Read the NAT product's timeout policy, inspect conntrack remaining time where Linux owns the mapping, and test a silence interval longer than that value. After silence, send a production-sized probe and confirm firewall counters, packet capture, socket delivery, and protocol progress. A small ping does not test the mapping.