Skip to content
LinkState
Go back

One five-tuple, two conntrack realities

Introduction to Container Networking and Conntrack Zones

Container networking isolates each container in its own network namespace, requiring virtual interfaces, IP addressing, and routing. Stateful firewalls rely on conntrack zones to track connection state per network context. Inconsistent zone assignment across veth edges can make firewall behavior appear random, even for identical flows.

Identifying the Issue: Random Stateful Firewall Behavior

Symptoms – legitimate traffic dropped, malicious traffic allowed, or inconsistent handling of identical flows. These can be seen with tcpdump/Wireshark.
Initial troubleshooting – inspect container network configuration and conntrack zones using docker inspect, ip link, ip route, and conntrack.

Understanding Conntrack Zone Assignment

Zones are assigned by the firewall based on source/destination IP, port, protocol, and the container’s network namespace. Factors influencing assignment across veth edges include:

Debugging the Container Path

CLI Inspection

# Show container‑side veth and other interfaces
ip link show

# View routing table
ip route show

# List conntrack entries (zones visible in the output)
conntrack -L

# List iptables rules (note zone matches if used)
iptables -n -L

Automation Script (Bash‑friendly)

#!/usr/bin/env bash
CONTAINER=$1

echo "=== Container $CONTAINER network interfaces ==="
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' "$CONTAINER"

echo "=== Host routes ==="
ip route show

echo "=== Conntrack table ==="
conntrack -L

echo "=== iptables rules ==="
iptables -n -L

Save as debug_container.sh, make executable, and run ./debug_container.sh <container_name>.

Mapping Zone Assignment End‑to‑End

Traffic Capture

# Capture 100 packets on any interface
tcpdump -i any -n -vv -s 0 -c 100 -w capture.pcap

# Open in Wireshark for detailed inspection
wireshark -r capture.pcap

Python + Scapy Automation

from scapy.all import sniff, IP, TCP

def map_zone(src_ip, dst_ip, src_port, dst_port):
    # Placeholder: replace with actual zone‑lookup logic
    return f"zone-{hash((src_ip, dst_ip, src_port, dst_port)) % 10}"

def process(pkt):
    if IP in pkt and TCP in pkt:
        ip = pkt[IP]
        tcp = pkt[TCP]
        zone = map_zone(ip.src, ip.dst, tcp.sport, tcp.dport)
        print(f"{ip.src}:{tcp.sport} -> {ip.dst}:{tcp.dport} => {zone}")

sniff(iface="any", prn=process, count=100)

Run with python3 zone_map.py. Adjust map_zone to query conntrack or firewall marks as needed.

Scaling Limitations and Considerations

Large‑scale deployments increase the number of concurrent flows, raising the chance of zone churn and mis‑assignment. Mitigation strategies:

Advanced Troubleshooting Techniques

Both can flag unexpected connections or repeated zone changes indicative of misconfiguration.

Best Practices for Consistent Conntrack Zones

Conclusion

Random firewall behavior in containerized environments often traces back to inconsistent conntrack zone assignment across veth edges. By systematically inspecting interfaces, routes, conntrack entries, and firewall marks—using the CLI tools, scripts, and packet captures shown above—you can map the zone assignment end‑to‑end, identify the root cause, and apply hardening measures such as ipset‑based zone mapping and optimized rule sets. Emerging tools like service meshes and network policies further simplify zone management, but the fundamentals of vigilant inspection and deterministic zone assignment remain essential.


Share this post on:

Previous Post
Ambiguous incidents beat single-answer benchmarks
Next Post
How much reordering can Linux TCP actually absorb