EN
  • English
  • Deutsch
  • Polski
  • Italiano
  • Español

Project principles

Warden’s design is not a list of features picked from a survey. It’s a small set of constraints that the codebase honors everywhere. Those explain both what the daemon does and what it deliberately does not do.

No Registration Needed

No login, no subscription, no cloud account in the loop.

There’s no account to create because there’s no customer base — there’s a community. Installing the binary is the whole onboarding: run it, subscribe to the lists you want, done. Nothing phones home: Warden sends no telemetry, no usage data, no crash reports to any server. Reducing the tracking your network does to you is the whole point of the tool — it would be strange for it to turn around and do the same to you.

No service runs on your behalf, so there’s nothing to bill for. Warden is funded by donations, not subscriptions; the community supports itself with shared lists, issues, and feedback.

  • No login on the daemon, no login on the TUI, no API key issued by anyone.
  • You choose your own blocklists. Subscribe to any URL that serves a domain list — community projects, your employer’s, your own static files.

This is the property that distinguishes Warden from the hosted DNS filtering services it can replace: the policy you write never leaves the machine you wrote it on.

Open Code

Free to download, run, fork, audit, modify.

Warden is released under the GNU AGPLv3: free to use, study, share, and modify — commercial use included. It’s a strong copyleft license: any modified version you distribute, or run as a network service for others, must be offered under the same license. The whole stack is yours to read, build, and run on your own hardware.

  • Fork the repository if you want to change a behavior — the code is yours to inspect and modify.
  • The license already lets you redistribute your changes; we’d still rather you send them upstream. One canonical Warden that everyone sharpens beats a scatter of private forks that quietly drift apart — that’s why it’s kept open and free.

Single binary, zero dependencies

One static binary, one TOML file, one systemd unit. Runs on a Pi Zero 2 W in tens of megabytes.

Warden is a single statically-linked executable. There is no Redis, no PostgreSQL, no Docker requirement, no Elasticsearch, no scrape endpoint to expose, no cloud account to register.

  • Steady-state memory on a Raspberry Pi Zero 2 W is ~29 MB RSS, no swap touched.
  • The install path makes no network calls beyond fetching the blocklists you configure.
  • One systemd unit for the daemon, one TUI binary for ad-hoc inspection. That’s it.

Built in Rust

Memory safety and predictable performance — both built into the language, not bolted on at runtime.

Warden is written in Rust because the resolver runs in your network’s hot loop: every microsecond of latency is felt by the device making the query. Rust gives the project two properties that matter at that hot path. The first is memory safety without a garbage collector: the classes of bug that bring down a long-running daemon — buffer overruns, use-after-free, data races — are caught at compile time rather than at 3 a.m. The second is predictable, low-overhead performance: no GC pauses, no JIT warmup, no surprise allocations.

The result, in code:

  • Every shared piece of state on the query path is updated by atomic pointer swap, never a lock — so query threads never wait on a writer, and latency stays flat even while a reload is in flight.
  • The blocklist, the profile resolver map, and the top-N stats snapshot are wrapped in ArcSwap. A reload swaps a pointer; in-flight queries finish on the old map without blocking, and new ones pick up the new map. A reload is measured in microseconds, not dropped queries.
  • Domain names are stored as CompactString — ≤24 bytes inline, no heap allocation in the common case. The typical lookup allocates nothing, keeping allocator pressure and memory fragmentation off the hot path.
  • Filtering is two-tier: an O(1) HashSet fast-path covers the bulk of rules, with a smaller engine for the edge cases (regex, allow-overrides, priority). The common query is a single hash lookup — you only pay for the heavier machinery when a rule actually needs it.

This is a deliberate trade: the entire blocklist lives in RAM. Warden loads every domain from every subscribed list into an in-memory map at startup and answers each query straight from memory — the hot path never touches the disk. You spend memory to buy that, and the bill scales with your lists: tens of megabytes for a curated set, a few hundred for a full multi-million-domain bundle. The payoff is that every lookup is a single hash on memory you already hold, not a disk seek — and it stays that fast no matter how large your lists grow.

Native TUI not GUI

Inspection is a tool you launch when you need it, not a server that runs all the time.

Warden ships a TUI as a separate binary. There is no built-in web UI, by choice. A web UI would mean an HTTP server, a session store, an asset pipeline, and JavaScript on the user’s browser, all sharing the resolver’s CPU and RAM and adding their own attack surface to the daemon. The TUI uses neither when it isn’t running.

  • Launch the TUI to inspect, close it when you’re done. The resolver doesn’t notice.
  • No HTTP listener bound to a port — one fewer thing to firewall, one fewer thing to authenticate.
  • The TUI talks to the daemon over a Unix socket constrained to the same machine; the boundary is a local filesystem permission, not a network credential.

Security as a cornerstone

Defense in depth, sandboxed external lists, fail-closed defaults — not features layered on top, but how the daemon is built.

Warden treats security as a foundational property, not a posture. Filtering is one layer of many. Subscribed blocklists can only contribute block rules — never allow-overrides, never priority elevation. Fourteen named threat classes have independent controls. Configuration that would expose the network refuses to boot.

And because the whole tree is open, you don’t have to take our word for any of it. Warden has been through an internal, whole-tree trust-and-backdoor review — no phone-home, no hidden filter exception, no alternate credential path — and its dependencies are CVE-scanned in CI. The real guarantee isn’t our review, though; it’s that you can run your own. The code is there to read, build, and audit yourself.

The full story — threat model, anti-bypass enforcement, audit log, fail-closed checks, the Operator Configuration Contract, host hardening — is on the Security by design page.

Declarative configuration

git diff config.toml is the complete picture of what the daemon will do.

Every CLI mutation rewrites the config file, re-validates it with the full loader, and atomically renames it into place. There is no in-memory live state that drifts from disk.

  • Edits hot-reload by atomic pointer swap; in-flight queries finish on the old config, new ones see the new one.
  • An invalid new config is rejected at the seam; the old config keeps running.
  • An append-only audit log records every reload — boot, shutdown, CLI mutations — with SHA-256 hashes of the config tree before and after.

This is the property that makes Warden comfortable to manage with git: the file is the truth, and the file is the only thing you back up.

Lightweight, file-based observability

JSON counters dumped to disk. Query logs as JSON-line files with daily rotation. No metrics daemon, no scrape endpoint.

Stats live as atomic counters in memory and snapshot to disk periodically. Query logs are plain JSON-line files rotated daily at UTC midnight.

  • Read stats with jq; graph with whatever you already use.
  • Query log retention defaults to seven days, configurable via retention_days. The same mental model as every other syslog tool you’ve ever set up.
  • Prometheus export and external-database query logging are explicitly out of scope by design.