Files
nx9-wg/docs/NFTABLES.md
T

4.3 KiB

Native Linux nftables Engine (NativeLinuxNftablesEngine)

The NativeLinuxNftablesEngine manages Linux firewall filtering and Network Address Translation (NAT) via direct in-process interaction with libnftables.so.1 and the Linux Netfilter Netlink subsystem.


1. Protocol Architecture & In-Process Netfilter Binding

nx9-wg uses libnftables in-process C-ABI FFI via NftContext to execute atomic transaction batches without spawning the nft or iptables CLI utilities:

┌────────────────────────────────────────────────────────┐
│              NativeLinuxNftablesEngine                 │
└───────────────────────────┬────────────────────────────┘
                            │
               In-Process FFI Transactions
               via libnftables (NftContext)
                            │
┌───────────────────────────▼────────────────────────────┐
│         Netfilter Subsystem (table inet nx9_wg)        │
└────────────────────────────────────────────────────────┘

2. Table Scoping & Multi-Tenant Host Isolation

To prevent breaking container networks, hypervisors, or external security tools, nx9-wg enforces strict table isolation:

A. Dedicated Table Namespace: table inet nx9_wg

All chains, sets, rules, and NAT masquerade policies are strictly contained inside table inet nx9_wg.

B. Zero Table Interference

  • No Global Flushes: nx9-wg NEVER executes flush ruleset or alters tables belonging to Docker (table ip docker), Kubernetes (table inet cni), libvirt (table ip libvirt), fail2ban, or UFW/Firewalld.
  • Ownership Verification: Before modifying or inspecting rules, nx9-wg validates table family (inet) and name (nx9_wg). Any foreign table is rejected and untouched.

3. Ruleset Architecture & Chains

The generated inet nx9_wg table contains three dedicated chains:

table inet nx9_wg {
    chain input {
        type filter hook input priority filter; policy accept;
        # Custom peer filter rules (e.g. UDP/TCP port restrictions)
    }

    chain forward {
        type filter hook forward priority filter; policy accept;
        # Inter-client routing and subnet forward policies
    }

    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        # Outbound NAT masquerade scoped strictly to managed WireGuard subnets
        ip saddr { 10.100.0.0/24 } oifname != "wg0" masquerade
    }
}

4. Scoped NAT Masquerade Invariant

Outbound NAT masquerading is dynamically scoped exclusively to managed WireGuard client subnets:

  1. Subnet Deduplication: Overlapping subnets are merged to prevent redundant rules.
  2. Interface Exclusion: Traffic routing back into the WireGuard interface (oifname != "wg0") is not masqueraded to preserve true source IPs for site-to-site tunnels.
  3. No Catch-All Masquerade: nx9-wg never creates a catch-all masquerade rule that affects non-WireGuard traffic on the host.

5. Atomic Rule Compilation & Verification

The ruleset builder (NftablesRulesetBuilder) compiles desired database state into a single atomic Netfilter transaction buffer:

  1. Deterministic Rule Ordering: Rules are sorted by priority index (ascending) to guarantee consistent packet evaluation.
  2. Protocol Grouping: Supports tcp, udp, tcp_udp, icmp, and any.
  3. Port & Port-Range Parsing: Supports single ports (53), comma-separated lists (80,443), and contiguous ranges (8000-8100).
  4. Validation via nft_ctx_buffer_output: The compiled batch is verified by libnftables before committing to the kernel.

6. Runtime Dependency Qualification

On Linux systems, nx9-wg dynamically links against:

  • libnftables.so.1 (provided by libnftables1 / nftables package)
  • libmnl.so.0
  • libnftnl.so.11

No runtime dependency on the nft CLI binary or shell scripts exists.