Skip to content

Witen Warden for Linux

Ban SSH attackers and web scanners at the firewall.

Warden reads your SSH and web server logs and bans attackers with nftables. Three failed SSH logins in five minutes earns a one-hour ban, and every ban comes with its reason. Free, with no account.

curl -fLO https://www.witenlabs.com/api/releases/warden/artifacts/witen-warden_0.1.48-1_amd64.deb
sha256sum witen-warden_*.deb    # compare with https://www.witenlabs.com/docs/warden#choose-build
sudo apt install ./witen-warden_*.deb
sudo warden discover
sudo sed -i 's/^backend = "nft"$/backend = "null"/' /etc/witen/warden.toml    # observation mode
sudo warden validate --config /etc/witen/warden.toml
sudo systemctl enable --now witen-warden
sudo warden tui

Start in observation mode: Warden logs what it would ban without touching your firewall.

Animation of the Warden TUI Events view as new SSH and web attack events arrive and scroll in
Live events: new attempts appear within seconds of reaching your logs.

Version 0.1.48 · Debian, Ubuntu, RHEL-family, and Alpine packages, plus portable glibc and musl builds · Free. No account needed to download.

Coming from another tool? Compare it with Fail2Ban or CrowdSec.

Watch every decision from the terminal

Run warden tui on the server to watch attacks arrive, see which addresses are close to a ban, and read the exact rule and score behind every ban. It runs over SSH, with no browser and no account.

Warden TUI Bans view listing banned IPv4 and IPv6 addresses with their service, dropped packets and bytes, packet rate, activity level, a trend sparkline, and time until the ban expires
Bans: every banned address with its service, the traffic it still sends into the firewall, and when the ban ends.
Warden TUI ban details for one address: the reason for the ban, an HTTP score of 33 against a threshold of 20 from 22 events, and an hour-long chart of dropped packets
Ban details: the exact rule and score that triggered the ban, and an hour of dropped packets.
Warden TUI Events view with one failed SSH key exchange expanded to show its confidence, the policy decision and reason, and the raw auth.log line
Event details: the policy decision for one event, next to the raw log line it came from.
Warden TUI Trends view with an hour-long chart of blocked packets, new bans by service, the policy categories contributing most evidence, and addresses banned more than once
Trends: an hour of blocked traffic, new bans by service, and addresses banned more than once.

Screens show a demonstration host with synthetic attack traffic from documentation address ranges.

Warden doesn't run as root

You're putting a closed-source binary on your server, so here is exactly what it can touch.

Its own user.
The Warden daemon runs as the unprivileged witen-warden account, not as root; only short start-up steps run as root, to fix ownership of Warden's own state files and grant read access to Apache logs.
Only the capabilities it uses, in a sandbox.
Warden keeps only the capabilities its configuration uses and drops the rest at start, for good: CAP_NET_ADMIN to manage its firewall rules, CAP_BPF only for the XDP backend, CAP_NET_RAW only for the JA4 sniffer, and none at all in observation mode. Under systemd it runs in a sandbox with a read-only system, no home directories, and a filtered set of system calls.
SELinux and AppArmor ready.
The RPM loads an SELinux policy that limits Warden to reading logs and its config, managing its own state, and running nft or iptables. The Debian and Ubuntu package installs an AppArmor profile in complain mode, which logs anything outside those limits, and you can switch it to enforce. On Alpine, the account, its capabilities, and no-new-privileges are the boundary.
Its own firewall table.
With nftables, every ban lives in Warden's own inet witen table and your rules are never edited; with iptables, Warden adds one jump at the top of INPUT and one at the top of OUTPUT, each pointing to its own chains.
Signed releases.
Every release is signed under an offline root key, and warden verify-release checks a download before you install it; updates trust nothing else. The packages don't carry a distribution signature yet, which is why the Alpine package installs with --allow-untrusted.
What leaves the server.
With no account, Warden only downloads reference data and checks for updates; it uploads nothing until you connect an account. Connect one and it uploads its security events (address, request, user agent, and an allowlisted set of headers) and its configuration with secrets removed, while package inventory stays off until you turn it on.

What Warden does

Bans at the firewall

Attackers are dropped by nftables before they reach SSH, your web server, or PHP. Warden keeps its rules in its own table and never touches yours.

Longer bans for repeat offenders

If a banned address keeps hammering, its ban doubles each time, up to a week. Returning attackers trip the wire sooner.

Bans that clean up after themselves

Every ban expires on schedule and survives restarts, so your firewall never fills with stale entries.

A reason for every ban

warden blocked shows each banned address, what it did, and which rule caught it. One command lifts a mistaken ban.

Works with your plugins

Witen's WordPress and Matomo plugins report to Warden over a local socket, turning application-level attacks into firewall bans.

JA4 fingerprinting

Optional TLS ClientHello capture records a JA4 fingerprint with each event, so you can see which requests came from the same kind of client.

Reads OpenSSH through journald, and nginx, Apache, Caddy, Cockpit, and container logs. Local detection and bans need no account; connect one to add shared blocklists.

Watch first, then block

Start Warden in observation mode with backend = "null" in the [jail] section. It detects and logs exactly what it would ban, without touching the firewall. When the results look right, switch to nftables.

See how observation mode works
  1. Install the package for your distribution.
  2. Add your own addresses to never_block.
  3. Run warden validate --config /etc/witen/warden.toml.
  4. Watch the detections, then switch the backend to nftables.

Questions about Warden

Can I use Warden on shared hosting?
No. Warden needs administrator access to read logs and manage the firewall. On shared hosting, use the WordPress plugin.
Does Warden need a paid account to block traffic?
No. Warden's local protection is free and works without hosted enrollment. Its default global shared feed requires a paid plan; Free accounts can configure the standard Free feed instead. The Free hosted plan covers 1 connected site or server. The standard Free feed includes up to 50 IPs, updated daily with a 14-day delay on new threats. See plans and feed limits.
Will it interfere with my existing firewall?
No. Warden keeps its rules in its own nftables table, inet witen, and never edits, flushes, or deletes your tables. A drop from Warden's table blocks the address even when your own rules would accept it.
Which firewall backends does it support?
nftables is the default and recommended. iptables is also supported. XDP is available for testing on supported hosts, but remains optional and experimental.
Can a package manager or script install it?
Yes. There's a public release manifest, a plain-text version endpoint, and stable artifact URLs with checksums. See Automate a verified installation.