Skip to content

Firewall

vxnsin edited this page Sep 7, 2026 · 1 revision

Firewall

warden holds the machine's packet filter in whatever that machine actually uses, and every change it makes can be undone by doing nothing.

warden firewall allow ssh --from 10.0.0.0/8
warden firewall allow 8080
warden firewall apply

Rules are written down first and applied when you say so. warden firewall export prints what the machine would be told, and changes nothing. --for nftables writes for a firewall this machine does not have, which is how a ruleset gets read on a laptop before it reaches the server it is meant for.

Which firewall

kind Used on How a whole ruleset is applied
nftables Linux, by default nft -f — one transaction
iptables Linux, asked for by name iptables-restore — one transaction
pf macOS, FreeBSD, OpenBSD, NetBSD pfctl -f — one ruleset at a time
windows Windows netsh, rule by rule, with a snapshot around it

warden picks by what the machine is. WARDEN_FIREWALL_BACKEND or --for names one instead — an older Linux box still running iptables-legacy wants iptables.

Three of the four swap a whole ruleset in one step. Windows Defender Firewall has no such thing, so that backend takes its own snapshot before it starts and puts it back if any rule fails: a half-applied policy is never left standing.

Windows also filters statefully whichever way it is told, so it needs no established-traffic rule — allowing outbound is what lets the answers back. The other three are told explicitly, and warden never writes a ruleset without it:

ct state established,related accept
iif lo accept

Without those two lines a default-drop policy also drops the ssh session that applied it.

Nothing that cannot be undone

$ warden firewall apply
12 rules applied
rolling back in 60s unless you run `warden firewall confirm`

The order matters and is not negotiable:

  1. Snapshot first. Taken after the change, it would describe the change rather than what to go back to.
  2. Arm the rollback second. Armed after applying, there would be a window where a lost session means a lost machine.
  3. Apply third. An apply that fails disarms, because nothing was applied and nothing should be waiting to be undone.

The watchdog runs detached — its own session on POSIX, DETACHED_PROCESS on Windows — so it outlives the ssh session that armed it. That is the whole point: a rule that locks you out costs a minute, not a drive.

Command
warden firewall confirm Keep it, and call off the rollback
warden firewall restore Put it back now, without waiting
warden firewall status Whether a rollback is waiting, and for how long

--rollback 0 turns the window off, for a machine you are sitting at. WARDEN_FIREWALL_ROLLBACK sets the default, which is 60 seconds.

Taking over from ufw or firewalld

Two firewalls managing one machine is one too many, so taking over means reading the other one first and turning it off last.

$ warden firewall adopt
ufw is holding 5 rules
NAME              DIR  ACTION  WHAT           FROM        ORIGIN   UNTIL
allow-22          in   allow   tcp/22         any         adopted  -
allow-8000-8100…  in   allow   tcp/8000-8100  10.0.0.0/8  adopted  -
deny-3389         in   deny    tcp/3389       any         adopted  -
could not read: [ 6] Anywhere on eth0  ALLOW FWD  10.5.0.0/16
those would be lost. Write them by hand first, or say no.
Take over from ufw? [y/N]:
  • ufw is read from ufw status numbered, which is the output it documents. A bare 3389 means both protocols to ufw, so it becomes two rules rather than half an answer. ufw lists v4 and v6 apart; warden's table is inet, which is both, so the twin is not a second rule.
  • firewalld is read from firewall-cmd --list-all: services resolved against warden's own catalogue, ports and ranges as written, and the zone's source becoming the rule's source.

Anything that cannot be translated is named before anything is applied. A rule quietly dropped in this step is a door quietly left open, or quietly shut.

The other firewall stays enabled while the rollback window is open. Its rules are not loaded — warden's ruleset replaced them in one step — but the service is untouched, so rolling back returns the machine exactly as it was. warden firewall confirm is what finally disables it, and says so:

kept
  ufw --force disable
ufw is off

Named services

warden firewall allow ssh
warden firewall allow postgres --from 10.0.0.0/8
warden firewall deny smb

ssh, sftp, ftp, http, https, dns, dhcp, ntp, smtp, imap, rdp, vnc, smb, postgres, mysql, redis, mongodb, wireguard, mdns. A name nobody knows suggests the nearest one rather than just refusing.

A bare port number works too, and --proto udp when it is not tcp.

Rules that belong to a service

This is the part no other firewall tool can do, and the reason the registry and the firewall are one program: warden knows which port a service holds, for how long, and whether its holder is still there.

$ warden firewall open shop-api
NAME            DIR  ACTION  WHAT      FROM        ORIGIN    UNTIL
allow-shop-api  in   allow   tcp/8300  10.0.0.0/8  registry  58s

The rule takes the port the registry actually handed out, and the lease with it. When the registration lapses or is released, the rule goes:

$ warden firewall list
closed allow-shop-api - its service is gone
no rules yet

warden firewall dev-mode --for 2 opens the whole pool from one network for two hours, for the afternoon somebody else needs to reach what you are running. It closes itself, and warden doctor says it is open for as long as it is.

What a rule from the registry can never do

The registry listens on loopback and asks for no token there. If registering a service could open the machine to the network, then anything able to register could open the machine to the network — which is how UPnP became a byword. So a rule whose origin is the registry passes through one place, and that place decides:

  1. Registering opens nothing. A person types warden firewall open.
  2. The pool is the ceiling. Only ports between pool_start and pool_end. 22, 3389 and 445 are outside it and stay unreachable — to a mistake, and to a registry somebody else is driving.
  3. Loopback services have nothing to open, and are told so.
  4. Off until switched on. firewall_from_registry is false.
  5. Where from is decided once, by the operator, in firewall_allow_from. Not by the service.
  6. The lease is the rule's lease. A rule may not outlive it.
  7. Every rule says where it came frommanual, adopted, catalogue, registry — in the listing, the history, the event stream and the webhook.
  8. A development window is bounded and temporary, never a standing hole.

Bounds 2 and 6 carry the weight: one limits what can ever be opened, the other how long. Both are checked in one place, and there is a test for each of the eight that tries to get through it.

When a service dies while the ruleset is applied

warden closes the rule in its own book straight away, so it can never be applied again. The kernel still holds it until the next warden firewall apply, and warden doctor says so. Re-applying a firewall without being asked is not something warden does quietly.

What this needs

Root, or an elevated prompt on Windows. Every backend says which it is rather than failing obscurely:

nft refused: Operation not permitted - a firewall needs root
netsh refused: a firewall needs an elevated prompt on Windows

Clone this wiki locally