Skip to Content

Linux — Firewall Setup

Rabtly uses nftables (nft) to enforce port-level access control rules on Linux. It creates a dedicated inet rabtly table with input and forward chains that filter traffic on the WireGuard interface only — your regular network traffic is never touched.

Check if nftables is installed

which nft

If this returns a path (e.g. /usr/sbin/nft), you’re good. If it returns nothing, install it below.

Installation by distro

Ubuntu / Debian

sudo apt update sudo apt install nftables -y sudo systemctl enable --now nftables

Supported versions: Ubuntu 20.04+, Debian 11 (Bullseye)+

Fedora

sudo dnf install nftables -y sudo systemctl enable --now nftables

Supported versions: Fedora 33+

RHEL / CentOS Stream / AlmaLinux / Rocky Linux

sudo dnf install nftables -y sudo systemctl enable --now nftables

Supported versions: RHEL 8+, CentOS Stream 8+

Amazon Linux 2023

sudo dnf install nftables -y sudo systemctl enable --now nftables

Amazon Linux 2023 ships nftables by default, but minimal container images may not include it.

Arch Linux

sudo pacman -S nftables sudo systemctl enable --now nftables

openSUSE / SLES

sudo zypper install nftables sudo systemctl enable --now nftables

After installation

Restart the Rabtly daemon so it detects nft:

sudo systemctl restart rabtly

Verify

# Check daemon sees the firewall rabtly status # Should show firewall_enforced=true # Inspect the installed rules sudo nft list table inet rabtly

You should see output like:

table inet rabtly { chain input { type filter hook input priority filter - 5; policy drop; iifname != "rabtly0" accept comment "rabtly: pass non-vpn" ct state established,related accept comment "rabtly: replies" ip saddr { 100.64.0.2/32, 100.64.0.3/32 } accept comment "rabtly: rule#0 all" ... counter drop comment "rabtly: default-deny" } ... }

Troubleshooting

”nft list ruleset failed — kernel may lack nftables support”

Your kernel was compiled without the nf_tables module. This is rare on modern distros but can happen on:

  • Very old kernels (< 3.13)
  • Custom-compiled minimal kernels
  • Some container runtimes (Docker, LXC) that don’t expose nftables to the guest

Fix: Upgrade your kernel, or if you’re in a container, check that the host has nftables support and the container runtime allows it.

CentOS 7 / Amazon Linux 2 (legacy)

These ship only iptables-legacy (no nftables kernel support). Options:

  1. Upgrade to CentOS Stream 8+ or Amazon Linux 2023.
  2. Accept that port ACLs won’t be enforced on this device — the VPN still works, and the destination device still enforces its own rules.

nftables conflicts with existing iptables rules

Rabtly only touches its own inet rabtly table. It does not modify, flush, or interact with any other table. Your existing iptables/nftables rules are untouched.

However, if another tool (e.g. Docker, firewalld, ufw) flushes the entire nftables ruleset with nft flush ruleset, Rabtly’s table gets wiped too. The daemon’s watchdog detects this within seconds and reapplies automatically.

If you use firewalld, it coexists fine — firewalld uses its own table and Rabtly uses a separate one.

Running in Docker / LXC containers

Containers typically don’t have access to program the host’s nftables. The daemon will report firewall_enforced=false inside a container — this is expected. If you need port ACL enforcement inside a container, run the container with --cap-add=NET_ADMIN and ensure the host kernel supports nftables.

How Rabtly uses nftables

  • Table: inet rabtly (dual-stack: covers both IPv4 and IPv6)
  • Chains: input (inbound to this device) and forward (routed traffic for subnet routes)
  • Priority: filter - 5 (runs just before standard filter hook)
  • Default policy: drop (fail-closed)
  • Non-VPN bypass: First rule accepts all traffic not on the WireGuard interface
  • Conntrack: Second rule accepts established/related connections (reply traffic)
  • Per-rule accepts: One line per ACL rule, using IP sets and port sets for efficiency
  • Atomicity: Loaded via nft -f - (single transaction — all or nothing)