nftably: Managing nftables Without the Fear of Locking Yourself Out

Kicked TeamMarch 30, 20266 min read

Everyone who manages Linux firewalls by hand knows the moment: you edit /etc/nftables.conf over SSH, you type nft -f, and for half a second you wonder whether the next thing you see will be a shell prompt or a frozen terminal. The mistake that locks you out is the same command that applies the fix. That asymmetry is the scariest thing about remote firewall work, and it is the problem we built nftably to remove.

nftably is now open source under the 0BSD license. This post is what it does, how it keeps you safe, and — just as important — what it will not do for you.

The real model, not a curated subset

Most firewall UIs give you a simplified abstraction: "allow SSH", "block this IP", and a fixed list of services. That works until you need something the abstraction didn't anticipate, at which point you are back in a text editor and the UI's view of the world is stale.

nftably manages the firewall as nftables actually models it: tables → chains → rules, in any family. Base chains hook into the traffic path; regular chains are jump and goto targets; a rule is a set of match conditions and action statements. Every rule is rendered as the real nft line it becomes, so what you see in the UI is what the kernel will run.

The catalogue reaches into the powerful corners too:

  • Verdict mapstcp dport vmap { 22 : accept, … } gives you one O(1) lookup instead of a stack of sequential rules.
  • Named counters — share one running total across several rules instead of guessing which of five copies fired.
  • Flowtables — fast-path offload for a router, where established flows bypass the full ruleset.
  • Guarded raw rules — for the rare construct the catalogue can't yet express, you can type a verbatim nft line, validated so it can't break out of its chain.

Explained as you build

nftables syntax is compact and unforgiving, and most of us do not write it often enough to keep it in our heads. In nftably, every option is a typed control that explains what it does: pick a match condition and the editor tells you in plain words what it matches, with an example; pick an action and only its relevant fields appear. Interfaces are offered from the box's real interface list, and sibling chains and flowtables autocomplete as you type.

The goal is that you can build anything nftables can express without memorising its syntax — while still learning the syntax, because the generated line is always in front of you.

The apply pipeline is the product

Editing rules is the easy part. Applying them to a remote box, through the very firewall you are changing, is where tools earn their keep. Every apply in nftably goes through the same pipeline:

  1. Dry run — the candidate config is checked with nft --check before anything touches the kernel.
  2. Diff review — you see exactly what will change, line by line, and confirm it.
  3. Atomic apply — the change lands as one nftables transaction. There is no window where half the rules are loaded.
  4. Armed auto-revert — after the apply, a revert is armed. If the change cut you off and you cannot confirm it, the previous ruleset comes back on its own. If you can still reach the UI, you confirm and the change stays.

That last step is the one that matters. It converts "one typo and I'm driving to the datacenter" into "one typo and I wait for the revert." It is the same discipline network engineers have used for years with commit confirmed on routers, applied to the Linux firewall.

Small enough to trust

nftably is a single Go binary backed by SQLite. No agent, no cloud, no external runtime dependency beyond nft itself. Install the package, run nftably init, and go. A command palette (Ctrl-K) jumps to any page or action. This is deliberate: a firewall management tool that phones home, or that needs a fleet controller before it manages one box, has its priorities wrong.

What you should know before pointing it at a real box

We would rather you read the warnings than learn them:

  • It is beta software. Expect bugs. It has not yet had the kind of testing a piece of firewall infrastructure deserves.
  • nftably owns the tables it manages. On every apply it renders each managed table entirely from its own database and swaps it in atomically. A hand-written rule in a managed table that nftably does not know about is gone after the next apply. Import an existing table before letting nftably manage it, or leave that table alone — tables it does not own are never named and never touched.
  • Put it behind an access list or an SSH tunnel. It is a control plane for your firewall; treat its port accordingly.

How it was built

nftably was written with AI coding agents doing the bulk of the implementation, under human design, specification, and review — the same workflow we described in what agentic development actually means. The object model, the safety pipeline, and the decision that the tool must own its tables outright were human calls; the agents turned them into working Go a great deal faster than we would have alone.

Takeaways

  1. The dangerous part of firewall work is the apply, not the edit — so the apply pipeline (check, diff, atomic transaction, armed auto-revert) is where the engineering went.
  2. Manage the real model. Abstractions that hide tables and chains fail exactly when you need them most.
  3. Explicit ownership beats silent merging. nftably replaces what it manages and never touches what it doesn't — a sharp rule, but one you can reason about.

If you run Linux at the edge and want help getting your firewalling, routing, or hosting into a state you can trust, talk to us — and if you try nftably, bug reports are very welcome on GitHub.