Firewall Backends & Fallback Chain

April 18, 2026 · View on GitHub

Synapse enforces access rules through one of four firewall backends, selected automatically at startup. Every backend applies the same rule set — what differs is where in the network stack enforcement happens and what additional capabilities are available.


Fallback chain

┌─────────────────────────────────────────────────────────────────┐
│  XDP / eBPF                                                     │
│  Kernel pre-routing — packet dropped before socket buffer       │
│  Fastest. BPF stats. TCP fingerprinting. CIDR LPM Trie.        │
└───────────────────────────┬─────────────────────────────────────┘
                            │  XDP unavailable (driver/kernel)

┌─────────────────────────────────────────────────────────────────┐
│  nftables                                                       │
│  Kernel netfilter — post-routing, pre-userspace                 │
│  Same CIDR rules. No BPF stats. No kernel-level fingerprinting.│
└───────────────────────────┬─────────────────────────────────────┘
                            │  nftables unavailable

┌─────────────────────────────────────────────────────────────────┐
│  iptables                                                       │
│  Legacy netfilter — wider kernel compatibility                  │
│  Same CIDR rules. No BPF stats. No kernel-level fingerprinting.│
└───────────────────────────┬─────────────────────────────────────┘
                            │  iptables unavailable

┌─────────────────────────────────────────────────────────────────┐
│  Userland (none)                                                │
│  Application-layer check inside the Synapse process            │
│  Proxy mode only. Agent mode has no packet enforcement.        │
└─────────────────────────────────────────────────────────────────┘

When firewall.mode is auto (the default), Synapse logs the selected backend at startup:

INFO  Firewall backend: XDP/BPF
# or
WARN  XDP/BPF not available - trying fallback backends
INFO  Firewall backend: nftables

Capability comparison

CapabilityXDP/eBPFnftablesiptablesUserland
CIDR access rules (allow/block)✅ proxy only
Dynamic rule updates (no restart)
IPv4 rule capacity4,194,304OS limitOS limitunlimited
IPv6 rule capacity1,048,576OS limitOS limitunlimited
CIDR coalescing before load
Drop latencykernel pre-routingkernel post-routingkernel post-routinguserspace
BPF statistics & counters
Per-IP drop tracking
Kernel-level TCP fingerprinting
IDS active blocking
Agent mode enforcement
Proxy mode enforcement

Backend details

XDP / eBPF

The preferred backend. eBPF programs are loaded into the kernel and attached to the NIC driver's XDP hook. Packets are inspected and dropped in the network driver interrupt handler — before the packet is copied into the socket buffer, before any userspace process sees it.

What you get:

  • Sub-microsecond drop latency at any packet rate
  • BPF statistics: total packets processed/dropped, per-IP drop counters (tracked in kernel LRU map)
  • TCP fingerprinting (JA4T/JA4TS) captured directly in the XDP program
  • LPM Trie for CIDR lookups: O(1) regardless of rule count
  • Full CIDR coalescing applied before loading rules into the BPF map

Requirements:

  • Linux kernel 4.18+ (5.4+ recommended)
  • BTF (/sys/kernel/btf/vmlinux must exist)
  • NIC driver with XDP support — most modern drivers (virtio-net, i40e, mlx5, ixgbe, etc.)
  • CAP_BPF and CAP_NET_ADMIN (or CAP_SYS_ADMIN on older kernels)
  • libbpf available at runtime

Check:

bpftool map show name banned_ips        # shows the LPM Trie map
bpftool map show name ipv4_banned_stats # shows the stats counter
ip link show eth0 | grep xdp            # shows XDP program attached

nftables

Fallback when XDP is unavailable. Rules are loaded into the Linux netfilter subsystem via nftables. Packets are evaluated post-routing after the NIC driver, but still in kernel space before the socket buffer is processed.

What you get:

  • Kernel-level enforcement without eBPF/XDP requirements
  • Same CIDR allow/block rules
  • Works on any kernel with nftables (3.13+)

What you lose vs XDP:

  • No BPF statistics or per-IP drop counters
  • No kernel-level TCP fingerprinting (JA4T still available via userspace capture)
  • Higher latency than XDP (post-routing vs pre-routing)
  • No LPM Trie — rule evaluation is linear for large lists

Requirements:

  • Linux kernel 3.13+
  • nft binary installed (apt install nftables / dnf install nftables)
  • CAP_NET_ADMIN

Check:

nft list tables           # shows Synapse tables if active
nft list ruleset

iptables

Legacy fallback. Uses the older iptables/ip6tables interface to the netfilter subsystem. Functionally similar to nftables at the enforcement layer.

What you get:

  • Maximum kernel compatibility (any kernel with netfilter)
  • Same CIDR allow/block rules

What you lose vs XDP:

  • Same as nftables, plus: iptables is deprecated upstream and may not be available on newer distributions without the legacy package

What you lose vs nftables:

  • Slower rule insertion for large rule sets (iptables-legacy uses linear traversal per rule)
  • No atomic rule replacement — rules are updated one at a time

Requirements:

  • iptables binary (apt install iptables / already present on most systems)
  • CAP_NET_ADMIN

Check:

iptables -L SYNAPSE_INPUT -n --line-numbers 2>/dev/null
ip6tables -L SYNAPSE_INPUT -n --line-numbers 2>/dev/null

Userland (none)

Last resort, or deliberately chosen via firewall.mode: "none". Access rules are evaluated inside the Synapse process as each connection is accepted.

What you get:

  • Works everywhere — no kernel or capability requirements
  • Full CIDR matching still applied (same rule set)

Critical limitations:

  • Agent mode: no enforcement. Without a kernel firewall, the agent cannot drop packets — the process has no visibility into connections it doesn't own. Blocked CIDRs will still reach your services.
  • Proxy mode only: enforcement happens at the point where Synapse accepts the connection, before proxying to the upstream. Blocked IPs receive a rejection at the application layer.
  • No BPF stats, no kernel-level fingerprinting, IDS cannot block (only detect)
  • Higher CPU cost per connection vs kernel-level enforcement

Configuration

firewall:
  mode: "auto"        # auto | xdp | nftables | iptables | none
mode valueBehaviour
autoSelect highest available: XDP → nftables → iptables → none
xdpForce XDP; startup fails if XDP is unavailable
nftablesForce nftables; startup fails if nftables is unavailable
iptablesForce iptables; startup fails if iptables is unavailable
noneUserland enforcement only (see limitations above)
# Environment variable
FIREWALL_MODE=auto   # same as firewall.mode

Windows

Windows does not use the Linux netfilter stack. Synapse uses the following Windows-specific capture and enforcement path:

AvailableCaptureEnforcement
eBPF for Windows (recommended)AF_XDP — kernel-level packet captureeBPF programs drop packets at kernel level
WPF/NDIS driver (fallback)NDIS intermediate driver — kernel-level captureDriver-level packet filter
NeitherRaw socket capture (limited)Userland enforcement only (proxy mode)

Install eBPF for Windows with the -WithEBPF flag during setup:

powershell -ExecutionPolicy Bypass -File install.ps1 -WithEBPF

Requires test signing mode: bcdedit /set testsigning on (then reboot).


Diagnostics

Identify the active backend at startup

Search the Synapse log:

grep -i "firewall\|backend\|XDP\|nftables\|iptables" /var/log/synapse/app.log | head -20

Expected messages:

MessageMeaning
Firewall backend: XDP/BPFXDP active
XDP/BPF not available - trying fallback backendsXDP failed, trying next
Firewall backend: nftablesnftables active
Firewall backend: iptablesiptables active
Firewall backend: none (userland)No kernel firewall

Verify XDP is attached

# Check XDP program on interface
ip link show eth0 | grep xdp

# List BPF maps
bpftool map show name banned_ips
bpftool map show name recently_banned_ips

# Count loaded rules
bpftool map dump name banned_ips | grep -c prefixlen

# Check stats counters
bpftool map dump name ipv4_banned_stats
bpftool map dump name total_packets_processed

Verify nftables/iptables rules

# nftables
nft list tables
nft list chain inet synapse input 2>/dev/null

# iptables
iptables -n -L SYNAPSE_INPUT 2>/dev/null | head -20

Common reasons XDP fails

SymptomCauseFix
EPERM / permission deniedMissing CAP_BPF or CAP_NET_ADMINRun as root, or add capabilities to the systemd unit
BTF not found/sys/kernel/btf/vmlinux missingEnable CONFIG_DEBUG_INFO_BTF=y in kernel config, or upgrade kernel
XDP not supported by driverNIC driver has no XDP supportUse firewall.mode: nftables or switch to a supported driver/NIC
Falls back silently in containerContainer lacks CAP_BPF / NET_ADMINAdd --cap-add BPF --cap-add NET_ADMIN to Docker run, or use nftables mode
vmlinux.h error at buildBTF headers not present at compile timeInstall linux-headers or use a pre-built release binary
Works but no statsXDP in SKB mode instead of nativeForce native XDP with a supported driver; SKB mode is a driver fallback