abrown38andClaude Opus 5.5 0795a1001e Fix zone list filtering and BIND warning display; add a views guide
- jarl zone list showed only primary zones. zone create binds its --type
  flag (default "primary") to the same variable as list's --type, so the
  default leaked into the list filter and hid hint, secondary and forward
  zones. list now has its own variable. TestListQueries runs list
  commands against a fake server and checks the filters they send.
- named-checkconf/named-checkzone messages are classified by the tool's
  exit code: on success, everything printed is a warning. Warnings such
  as 'both "recursion no;" and "allow-recursion" active' were shown as
  errors. The CLI, jarld check and the web UI now label them as warnings
  and skip the routine "loaded serial" lines.
- The zone_outside_view error points at --adopt-zones.
- docs/views.md: step-by-step split DNS for a server that has no views
  yet, tested on a copy of a stock Ubuntu 26.04 setup. Linked from the
  README, concepts and validation docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 15:36:24 +00:00

Jarl

A Jarl rules a Hold; this one rules your zones.

Jarl manages a BIND 9 (named) server: zones, records of every type, views, ACLs, TSIG keys and any named.conf option. It has a web UI, a REST API and a command line client. All three go through the same validated, audited, all-or-nothing change pipeline, and nothing reaches named before BIND's own checkers have accepted it.

$ jarl record add adbraun.lol nas A 192.168.1.20 --ptr
add nas.adbraun.lol. IN A 192.168.1.20
add 20.1.168.192.in-addr.arpa. IN PTR nas.adbraun.lol.
zone 1.168.192.in-addr.arpa serial 2026100700 -> 2026100701
zone adbraun.lol serial 2026100701 -> 2026100702
applied (changeset 12)

$ jarl record add adbraun.lol www A 192.168.1.99
error: www.adbraun.lol has a CNAME, so it can't have any other records (found A); a CNAME must be the only record at its name (RFC 1034) [zone adbraun.lol]

Features

  • Everything in one place: primary, secondary, forward, stub, mirror, hint, redirect and in-view zones, reverse zones from a CIDR, split DNS with views, ACLs, TSIG keys, and every BIND 9.20 option at server, view, zone and top level, with the ARM's description and grammar built in.
  • Safe changes. Every change is validated as a whole (CNAME rules, glue, delegations, RRset TTLs, references, option syntax, open-resolver and open-transfer lints), checked with named-checkconf -z, installed atomically, reloaded, and verified with rndc zonestatus. If named doesn't load it, the previous files are put back.
  • Changesets: apply edits one at a time, or bundle them, review the diff, and apply them together. Every applied changeset can be reverted. Serials are bumped automatically.
  • Users and API tokens with granular permissions, e.g. a token that may only write _acme-challenge TXT records in one zone. Passwords use argon2id, sessions have CSRF protection, logins are rate limited.
  • Audit log of every login, change and token, with user, token, IP and outcome.
  • Let's Encrypt DNS-01 built in: jarl acme plus certbot and acme.sh hooks, including CNAME delegation to a dedicated ACME zone.
  • Adopts an existing server: imports named.conf and zone files (comments included), then switches named over with an automatic fallback.
  • One static Go binary for the daemon (web UI embedded, SQLite built in) and one for the CLI, run by a sandboxed systemd service as an unprivileged user.

Quick start

On a Debian/Ubuntu BIND 9.20 server (install.md has the details):

make && sudo make install
sudo systemd-sysusers jarl.conf && sudo systemd-tmpfiles --create jarl.conf
sudo chgrp jarl /etc/jarl/jarl.yaml
sudo -u jarl jarld init --token            # first admin + a CLI token
sudo -u jarl jarld import                  # read the current named.conf and zones
sudo jarld adopt                           # switch named over (keeps a backup, rolls back on failure)
sudo systemctl enable --now jarl

jarl config set server http://127.0.0.1:8053
jarl config set token                      # paste the token from 'jarld init'
jarl status

Then open the web UI at http://127.0.0.1:8053/, or set listen and tls in /etc/jarl/jarl.yaml to reach it from your management network.

Documentation

docs/concepts.md How Jarl works: source of truth, changesets, the apply pipeline, authentication. Read this first
docs/install.md Installing, importing and adopting an existing server, TLS, upgrading
docs/configuration.md /etc/jarl/jarl.yaml reference
docs/cli.md The jarl command line client
docs/api.md REST API reference
docs/permissions.md Users, tokens, grants and roles
docs/views.md Split DNS: adding views to a server that has none
docs/acme.md Let's Encrypt DNS-01 with certbot and acme.sh
docs/validation.md Every check Jarl makes
docs/operations.md Backups, drift, failures, recovery, monitoring
docs/development.md Code layout, tests against real BIND, conventions
CHANGELOG.md Changes per release

The web UI

The UI is built for getting things done rather than for looks. It has these pages:

  • Dashboard: named status, adoption, drift, recent changes, open problems.
  • Zones: list, create (fields adapt to the zone type), per-zone records with inline editing and type-specific hints, settings (SOA, TTL, serial policy, view), options, the generated zone file, and pasting a zone file to merge or replace records.
  • Views, ACLs, TSIG keys, Server options: the options editor knows every BIND 9.20 statement for the scope and shows its description, grammar and a value field that fits it.
  • Changes: pending edits with the diff, named-checkconf output and problems, applied as one changeset. History lists applied changesets with their diffs and a revert button.
  • Audit, Users, Account (password, API tokens) and Search.

By default, edits are collected as pending changes. Pending rows are shown inline (green = new, yellow = changed, struck out = deleted) until you review and apply them. Switch on "Apply edits immediately" to skip the review step.

Requirements

  • BIND 9.20, with named-checkconf, named-checkzone and rndc. The option catalog follows 9.20. 9.18 will probably work, because named-checkconf still checks every change, but it is untested.
  • Linux with systemd for the packaged service. Defaults match Debian/Ubuntu, and other layouts are configurable.
  • Go 1.27+ to build.

Status

Version 0.1.0, the first release. It is feature-complete for one server's configuration. DNSSEC signing and managing several servers are not handled yet (concepts.md).

S
Description
No description provided
Readme MIT
11 MiB
0 Stars 1 Watchers 0 Forks
Jarl v0.6.2
Latest
2026-10-21 21:21:23 +00:00
Languages
Go 80.6%
JavaScript 14.2%
Shell 3.3%
CSS 1.3%
Makefile 0.3%
Other 0.3%