• v0.4.1-rc.2 6313fa51f8

    Jarl v0.4.1-rc.2 Pre-release

    adam released this 2026-10-12 14:36:00 +01:00 | 69 commits to main since this release

    Upgrading from 0.4

    • New exposure warnings (docs/exposure.md) appear for views reachable from
      the internet, e.g. "no rate-limit" or "version visible" on an external
      view: fix them from the Exposure page, or acknowledge them. A change
      that newly opens a public view up (an open resolver, say) now needs
      --accept-risk, or the checkbox on the Changes page.

    • Once you use address ranges, the database can't go back to 0.4: its
      parser doesn't know them. Remove the ranges first if you need to
      downgrade.

    Fixed

    • Option values in the web UI looked different from the editor: a long
      line wrapped back to the left edge, losing its indentation, and the
      column changed width when Edit opened. Values now keep their layout
      (a long line scrolls), with the same width and padding as the editor.
      The "{ } around the list are optional" hint only shows for options that
      end in a list (not rate-limit, which only has one inside).
    • Query statistics skipped every query signed with a TSIG key (named
      writes "/key NAME" after the client's port), such as queries with a
      view's key: they are counted now.
    • A changeset with a staged record delete could not be applied after that
      record was deleted elsewhere (e.g. with the CLI), and it was hard to see
      which operation to remove: the error only said "record 832 does not
      exist". A staged delete of a record that is already gone now counts as
      done (with a warning), and the other operations that no longer apply
      (an edit or disable of a deleted record, a change to an object changed
      since) are named with their number and summary. The Changes page marks
      that operation and offers to remove it right in the error.

    Added

    • TLS certificates (docs/certificates.md): Jarl
      obtains certificates from Let's Encrypt or any ACME CA (account set up
      in jarl.yaml under acme.account) and renews them itself, from the CA's
      renewal information (ARI) or two thirds into their lifetime, with
      back-off after failures. It answers the DNS-01 challenges in a zone it
      serves, or through Porkbun's DNS API while Porkbun serves the domain;
      auto decides from the domain's public name servers at every renewal,
      so moving the domain to your own name servers needs no change. A CNAME
      on _acme-challenge into a zone Jarl serves is followed, for domains
      hosted elsewhere. A certificate is used for jarld's HTTPS ("web") and/or
      written for named (<bind.config_dir>/tls/NAME/, "dns"; named rereads
      it on renewal), and certificates you renew yourself can be used too
      (reread when their files change). Certificates page and dashboard card
      in the web UI, jarl cert (check, create, issue, update, delete,
      account), /api/v1/certificates, Prometheus
      jarl_certificate_expiry_timestamp_seconds, jarl_certificate_failing.
    • jarld serves HTTPS and plain HTTP on the same ports once it has a
      certificate (tls.cert_file, or one with the web use, which takes
      effect without a restart): plain HTTP from the server itself and from
      trusted proxies is served as before, browsers elsewhere are redirected
      to HTTPS and API requests get https_required. Before, with
      tls.cert_file, plain HTTP got an error even from localhost.
    • Internet exposure (docs/exposure.md): Jarl works out
      which views are reachable from the internet (match-clients ending in a
      catch-all; for a server without views, open allow-query and a
      non-private listen address), with a per-view override, and checks them:
      response rate limiting, open resolvers, ANY answers (minimal-any), cache
      snooping, open NOTIFY and zone transfers, BIND version and host name,
      management interfaces. Fixes are staged like any change, including
      response rate limiting from ISC's example in log-only mode, with your
      secondaries exempt, and a later "start enforcing". With statistics on,
      Jarl reads named's rate limiting log lines and shows what was (or would
      have been) limited: counts, client networks and names (Exposure page,
      jarl stats breakdown rrl, top lists ratelimited, Prometheus
      jarl_ratelimit_logged_total). A change that newly opens a public view
      up must be confirmed (checkbox on the Changes page, --accept-risk, API
      accept_risk; 409 confirm_risk otherwise). Findings can be
      acknowledged with a reason: they stay visible as info, with who, when
      and why. Exposure page and dashboard card in the web UI, jarl exposure (fix, ack, unack), GET /exposure.
    • jarl changeset show, diff, apply, discard and remove take the
      changeset from -C or JARL_CHANGESET when no ID is given
      (jarl changeset apply). A changeset from JARL_CHANGESET is now
      checked before it is used, for staging too: it must exist, be open and
      be yours, so a stale export (an applied changeset, or an ID that later
      turned into someone else's web UI draft) can't silently take your
      changes; the error says what to do. Commands say on stderr which
      changeset from JARL_CHANGESET they use, and apply/discard remind
      you to unset JARL_CHANGESET. -C and ID arguments are used as given.
    • Address ranges such as 10.0.10.101-10.0.10.199 or
      2001:db8::100-2001:db8::1ff (also ! negated, and with spaces around
      the dash) wherever an address match list is used: ACLs, views'
      match-clients and match-destinations, options such as allow-query, and
      blocking's client groups (docs/concepts.md). Jarl
      keeps the range as written and writes the fewest prefixes that cover
      exactly that range to named.conf, with the range as a comment. The web
      UI shows what a range becomes while you type it (GET /catalog/ranges). Mistakes are refused when entered: an end that isn't
      a full address, the start after the end, IPv4 mixed with IPv6, a range
      in an option that takes no address match list (forwarders). A range
      covered by an earlier element is reported as never matching, a range of
      every address counts as "any" for the open resolver and open transfer
      checks, and an IPv6 range in the IPv4-mapped space gets a warning. ACL
      names can no longer look like a range.
    • Prometheus metrics at /metrics (docs/metrics.md),
      set up in the new metrics: section of jarl.yaml (off by default).
      metrics.allow lists the addresses that may scrape (loopback by
      default), metrics.token lets anyone who sends it as a bearer token
      scrape, and metrics.listen adds addresses that serve only /metrics
      (for a Prometheus server elsewhere). Root and jarld's own user can also
      scrape on the local socket.
      • Health, always: named up, recursive and TCP clients against their
        limits, adopted, open changesets, last apply, validation problems by
        severity, drifted files, object counts, the last backup (and failure,
        and whether it is stale), blocking paused, each blocklist's entries,
        last check and change and whether it fails, the DNSSEC phase of every
        signed zone, and when API tokens expire.
      • With query statistics on: named's counters (queries, result codes,
        record types, UDP/TCP, authoritative/recursive, rate limiting, upstream
        round-trip times, DNSSEC validation, cache hits) and Jarl's (logged
        responses per view and zone, blocked queries per blocklist), as
        counters since jarld started, plus named's memory, CPU, threads, cache
        and sockets, and the collector's health.
      • Example queries and alert rules, checked with promtool.
    Downloads
  • v0.4.1-rc.1 cf550bd512

    Jarl v0.4.1-rc.1 Pre-release

    adam released this 2026-10-11 23:53:31 +01:00 | 74 commits to main since this release

    Upgrading from 0.4

    • Once you use address ranges, the database can't go back to 0.4: its
      parser doesn't know them. Remove the ranges first if you need to
      downgrade.

    Fixed

    • A changeset with a staged record delete could not be applied after that
      record was deleted elsewhere (e.g. with the CLI), and it was hard to see
      which operation to remove: the error only said "record 832 does not
      exist". A staged delete of a record that is already gone now counts as
      done (with a warning), and the other operations that no longer apply
      (an edit or disable of a deleted record, a change to an object changed
      since) are named with their number and summary. The Changes page marks
      that operation and offers to remove it right in the error.

    Added

    • jarl changeset show, diff, apply, discard and remove take the
      changeset from -C or JARL_CHANGESET when no ID is given
      (jarl changeset apply). A changeset from JARL_CHANGESET is now
      checked before it is used, for staging too: it must exist, be open and
      be yours, so a stale export (an applied changeset, or an ID that later
      turned into someone else's web UI draft) can't silently take your
      changes; the error says what to do. Commands say on stderr which
      changeset from JARL_CHANGESET they use, and apply/discard remind
      you to unset JARL_CHANGESET. -C and ID arguments are used as given.
    • Address ranges such as 10.0.10.101-10.0.10.199 or
      2001:db8::100-2001:db8::1ff (also ! negated, and with spaces around
      the dash) wherever an address match list is used: ACLs, views'
      match-clients and match-destinations, options such as allow-query, and
      blocking's client groups (docs/concepts.md). Jarl
      keeps the range as written and writes the fewest prefixes that cover
      exactly that range to named.conf, with the range as a comment. The web
      UI shows what a range becomes while you type it (GET /catalog/ranges). Mistakes are refused when entered: an end that isn't
      a full address, the start after the end, IPv4 mixed with IPv6, a range
      in an option that takes no address match list (forwarders). A range
      covered by an earlier element is reported as never matching, a range of
      every address counts as "any" for the open resolver and open transfer
      checks, and an IPv6 range in the IPv4-mapped space gets a warning. ACL
      names can no longer look like a range.
    • Prometheus metrics at /metrics (docs/metrics.md),
      set up in the new metrics: section of jarl.yaml (off by default).
      metrics.allow lists the addresses that may scrape (loopback by
      default), metrics.token lets anyone who sends it as a bearer token
      scrape, and metrics.listen adds addresses that serve only /metrics
      (for a Prometheus server elsewhere). Root and jarld's own user can also
      scrape on the local socket.
      • Health, always: named up, recursive and TCP clients against their
        limits, adopted, open changesets, last apply, validation problems by
        severity, drifted files, object counts, the last backup (and failure,
        and whether it is stale), blocking paused, each blocklist's entries,
        last check and change and whether it fails, the DNSSEC phase of every
        signed zone, and when API tokens expire.
      • With query statistics on: named's counters (queries, result codes,
        record types, UDP/TCP, authoritative/recursive, rate limiting, upstream
        round-trip times, DNSSEC validation, cache hits) and Jarl's (logged
        responses per view and zone, blocked queries per blocklist), as
        counters since jarld started, plus named's memory, CPU, threads, cache
        and sockets, and the collector's health.
      • Example queries and alert rules, checked with promtool.
    Downloads
  • v0.4.0 7e6e274a89

    Jarl v0.4.0 Stable

    adam released this 2026-10-11 21:58:15 +01:00 | 79 commits to main since this release

    Upgrading from 0.3

    • Back up first (sudo jarld backup).
    • When jarld first starts, it rewrites named's configuration: options
      move into their new fixed order, and every view gets its view key in
      match-clients and keys.conf. It is checked with named-checkconf
      before named reloads, like any apply. Files you changed by hand are left
      alone; the log then says to run jarl resync.
    • The systemd unit changed (it allows AF_NETLINK). The package replaces
      it; an override that adds AF_NETLINK (systemctl edit jarl) does no
      harm and can be removed.
    • The database moves to schema 8 (disabled zones, client groups) as
      jarld starts.
    • If statistics showed a spike after views were created or changed, see
      "Statistics" under Fixed: the bad minutes can be removed from
      /var/lib/jarl/stats.db (minute rows have res = 'm'; the hours and
      days that include them are 'h' and 'd').

    Added

    • Different blocking for different devices (docs/blocking.md), like
      Pi-hole's groups, in one view and without loading any list twice.
      Client groups put devices (addresses, networks or ACLs of them) at a
      blocking step: off (only your rules), normal (the default), or steps
      you add above it, each including the lists of the steps below. Lists
      start at a step. Jarl puts a small "gate" policy zone in front of each
      step's lists that lets the devices below that step through. Web UI: a
      Devices panel on the Blocking page and a step on each list. CLI: jarl block step, jarl block group, jarl blocklist update --step. API:
      /blocking/steps, /blocking/groups. Database schema 8.
    • View keys: every view gets a TSIG key, jarl-view-NAME, at the front of
      its match-clients, so a query signed with it lands in that view from any
      address. Jarl signs its delegation check's queries to this server's own
      addresses with the key of the zone's view: before, they got whichever
      view matched the server's own address (usually internal), so the check
      could report the wrong serial for the external view. jarl view key VIEW shows a key, for dig -k (docs/views.md). The first apply after
      upgrading adds the keys to named.conf and keys.conf.
    • Server statistics: named's memory (resident, and its own count) and
      CPU use, its cache size, sockets, and recursive and TCP clients against
      their limits; the host's memory and load; free space where zone files,
      logs and Jarl's data are. Memory and CPU are kept over time like the
      other statistics. Statistics page → Server, jarl stats server, API
      /stats/server. Read from named's statistics channel, rndc status and
      /proc, with no extra privileges.
    • CLI: the record commands that change records take several views,
      --view internal,external, or --view all, and make the change in each,
      as one changeset (all views or none).
    • Blocking can be paused until resumed, like Pi-hole's "indefinitely":
      jarl block pause indefinitely, Until I resume on the Blocking page,
      {"indefinitely": true} in the API.
    • Disabled zones: a zone can be disabled instead of deleted. named stops
      loading it (its zone statement is left out of named.conf), while Jarl
      keeps it with its records, options and history, still editable;
      enabling it serves it as it is then. Disabling says what clients get
      instead (recursion, or REFUSED). Signed zones can't be disabled. Web
      UI: Disable/Enable on the zone page, a badge in the zone list. CLI:
      jarl zone disable|enable. API: PATCH /zones/{zone} with
      {"disabled": true}. Database schema 7.
    • Blocking (docs/blocking.md): named answers "doesn't exist" for ads,
      trackers and malware, using BIND's response policy zones.
      • Blocklists in Adblock, hosts or plain-domain format, downloaded by jarld
        and checked daily (blocking.refresh). A list is downloaded only when
        the server says it changed, checked with named-checkzone, and reloaded
        only when its content differs; a failed update keeps the previous
        version and shows on the dashboard.
      • Your own block and allow rules, for a domain and the names below it or
        the exact name. Rules take precedence over every list, and the most
        specific rule wins.
      • Lists and rules apply to chosen views, or to every view that offers
        recursion. They are configuration: staged, reviewed and reverted like
        any change.
      • Checking a name says whether it is blocked and by which rule or list
        entry, with an Allow button in the web UI.
      • Web UI: a Blocking page, with well-known lists to pick and named's
        memory per list. CLI: jarl blocklist and jarl block. API:
        /blocking/lists, /blocking/rules, /blocking/check.
      • Pausing: jarl block pause [DURATION] or the Blocking page lets every
        name through for a while (at most a day); blocking resumes by itself.
        The lists stay loaded, so it takes effect at once.
      • Statistics: blocked queries over time (a line on the queries chart)
        and their share, blocked per list, the most blocked names and the
        clients with the most blocked queries (jarl stats top blocked,
        top blocked-clients). Blocked answers no longer count as names that
        don't exist.
      • The view choice in the web UI's forms is a compact dropdown, however
        many views there are.
      • A blocking permission; database schema 6.

    Changed

    • Web UI: each view has its own page, like a zone: Settings (match lists,
      comment, colour), Options and Zones tabs (with New zone in VIEW),
      and Delete. The Views page lists them in order, with the arrows that
      reorder them; view links everywhere open the view's page.
    • Web UI: A and AAAA records have a + CNAME button that fills in the
      add form with a CNAME pointing to the record's name, leaving only the
      alias's name to type. It shows when the row is hovered or focused
      (always on touch screens).
    • Blocking page: how many queries each blocklist blocked in the last 24
      hours, and your rules together, with statistics on (linking to the
      Statistics page).
    • Options are kept in one fixed order, in named.conf, the web UI and the
      CLI: grouped by topic (files, listening, access control, recursion and
      forwarding, DNSSEC, transfers and notify, then the rest), alphabetical
      within a group. The same option is now in the same place in every view
      and zone. The first apply after upgrading reorders named.conf (a diff
      that only moves lines). Top-level statements keep their order.
    • Options that end in a list (allow-transfer, forwarders,
      listen-on, ...) can be given without their braces, in the web UI, CLI
      and API: 10.0.10.53; key xfer becomes { 10.0.10.53; key xfer; }.
      Before, only some server options (those edited one element per line)
      added them.
    • The dashboard's configuration checks include named-checkconf's own
      warnings about the running configuration (such as both "recursion no;" and "allow-recursion" active), which before only showed while applying.
      The CLI now prints them after an apply too.
    • Statistics page: cards and tiles fill their rows instead of leaving one
      alone beside an empty space, and the queries and failed answers charts
      have the same margins, so their time axes line up.
    • Dashboard: options have their own tile; "0 TSIG keys · 22 options" read
      as if the options belonged to the keys.
    • Web UI times use the 24-hour clock.
    • Diffs of named.conf say which block each change is in, after the @@
      line numbers (@@ -50,6 +49,8 @@ view "internal" {), like git does
      with function names. Moving an option from the server's options into a
      view no longer looks like two unrelated edits.
    • Web UI options (server, top-level, view and zone): values with blocks,
      such as logging, are shown and edited laid out as in named.conf, over
      several lines with indentation. The editor grows with its content, Tab
      indents and Enter keeps the indentation (Esc, then Tab, moves on). With
      a draft open, the tables show the draft's values, so a staged edit stays
      visible after Save.
    • The pending-changes banner has an Apply now button: it applies your
      draft without going to the Changes page, and stays on the page you're
      on. If the changes are refused, a dialog says why and links to Changes.
    • Blocking page: blocklists and rules have an Edit button (name, URL,
      views, comment; a rule's action and scope). The list button that
      downloads now is called Refresh, like jarl blocklist refresh.
    • Records table: disabled records are hatched and have a "disabled" badge
      next to their name, instead of only a muted colour and a badge in the
      comment column.

    Fixed

    • Reverting a changeset added needless "restore" operations for
      blocklists, rules and views that hadn't changed: copying the state
      turned their empty view lists into missing ones.
    • Under the shipped systemd unit, jarld couldn't list the host's
      addresses (it needs a netlink socket, which RestrictAddressFamilies
      didn't allow), so the name server checks didn't recognize this server's
      own addresses. The Name servers tab then queried them like another
      server's, and the delegation check didn't sign those queries with the
      view's key: with views, both got the view matching the server's own
      address (usually internal) and reported a wrong serial. The unit now
      allows AF_NETLINK, and without it jarld reads the addresses from
      /proc.
    • Statistics: after a reconfig that added, removed or recreated views
      (creating the first view, for instance), a minute could count everything
      since named started: millions of queries in an hour. A per-view counter
      (cache, upstream times, validation) going down was taken for a restart
      of named. Now only a new boot time means a restart, and a counter that
      goes down counts 0 for that minute.
    • Blocking page, checking a name: when your own block rule is for that very
      name, it offers to remove the rule instead of an allow rule, which was
      refused as a second rule for the same name. It also names the rule that
      matched rather than the policy zone entry.
    • docs/validation.md lacked the disabled_conflict warning added in 0.3.0.
    Downloads
  • v0.4.0-rc.5 11ed877c3c

    Jarl v0.4.0-rc.5 Pre-release

    adam released this 2026-10-11 21:33:22 +01:00 | 80 commits to main since this release

    Upgrading from 0.3

    • Back up first (sudo jarld backup).
    • When jarld first starts, it rewrites named's configuration: options
      move into their new fixed order, and every view gets its view key in
      match-clients and keys.conf. It is checked with named-checkconf
      before named reloads, like any apply. Files you changed by hand are left
      alone; the log then says to run jarl resync.
    • The systemd unit changed (it allows AF_NETLINK). The package replaces
      it; an override that adds AF_NETLINK (systemctl edit jarl) does no
      harm and can be removed.
    • The database moves to schema 8 (disabled zones, client groups) as
      jarld starts.
    • If statistics showed a spike after views were created or changed, see
      "Statistics" under Fixed: the bad minutes can be removed from
      /var/lib/jarl/stats.db (minute rows have res = 'm'; the hours and
      days that include them are 'h' and 'd').

    Added

    • Different blocking for different devices (docs/blocking.md), like
      Pi-hole's groups, in one view and without loading any list twice.
      Client groups put devices (addresses, networks or ACLs of them) at a
      blocking step: off (only your rules), normal (the default), or steps
      you add above it, each including the lists of the steps below. Lists
      start at a step. Jarl puts a small "gate" policy zone in front of each
      step's lists that lets the devices below that step through. Web UI: a
      Devices panel on the Blocking page and a step on each list. CLI: jarl block step, jarl block group, jarl blocklist update --step. API:
      /blocking/steps, /blocking/groups. Database schema 8.
    • View keys: every view gets a TSIG key, jarl-view-NAME, at the front of
      its match-clients, so a query signed with it lands in that view from any
      address. Jarl signs its delegation check's queries to this server's own
      addresses with the key of the zone's view: before, they got whichever
      view matched the server's own address (usually internal), so the check
      could report the wrong serial for the external view. jarl view key VIEW shows a key, for dig -k (docs/views.md). The first apply after
      upgrading adds the keys to named.conf and keys.conf.
    • Server statistics: named's memory (resident, and its own count) and
      CPU use, its cache size, sockets, and recursive and TCP clients against
      their limits; the host's memory and load; free space where zone files,
      logs and Jarl's data are. Memory and CPU are kept over time like the
      other statistics. Statistics page → Server, jarl stats server, API
      /stats/server. Read from named's statistics channel, rndc status and
      /proc, with no extra privileges.
    • CLI: the record commands that change records take several views,
      --view internal,external, or --view all, and make the change in each,
      as one changeset (all views or none).
    • Blocking can be paused until resumed, like Pi-hole's "indefinitely":
      jarl block pause indefinitely, Until I resume on the Blocking page,
      {"indefinitely": true} in the API.
    • Disabled zones: a zone can be disabled instead of deleted. named stops
      loading it (its zone statement is left out of named.conf), while Jarl
      keeps it with its records, options and history, still editable;
      enabling it serves it as it is then. Disabling says what clients get
      instead (recursion, or REFUSED). Signed zones can't be disabled. Web
      UI: Disable/Enable on the zone page, a badge in the zone list. CLI:
      jarl zone disable|enable. API: PATCH /zones/{zone} with
      {"disabled": true}. Database schema 7.
    • Blocking (docs/blocking.md): named answers "doesn't exist" for ads,
      trackers and malware, using BIND's response policy zones.
      • Blocklists in Adblock, hosts or plain-domain format, downloaded by jarld
        and checked daily (blocking.refresh). A list is downloaded only when
        the server says it changed, checked with named-checkzone, and reloaded
        only when its content differs; a failed update keeps the previous
        version and shows on the dashboard.
      • Your own block and allow rules, for a domain and the names below it or
        the exact name. Rules take precedence over every list, and the most
        specific rule wins.
      • Lists and rules apply to chosen views, or to every view that offers
        recursion. They are configuration: staged, reviewed and reverted like
        any change.
      • Checking a name says whether it is blocked and by which rule or list
        entry, with an Allow button in the web UI.
      • Web UI: a Blocking page, with well-known lists to pick and named's
        memory per list. CLI: jarl blocklist and jarl block. API:
        /blocking/lists, /blocking/rules, /blocking/check.
      • Pausing: jarl block pause [DURATION] or the Blocking page lets every
        name through for a while (at most a day); blocking resumes by itself.
        The lists stay loaded, so it takes effect at once.
      • Statistics: blocked queries over time (a line on the queries chart)
        and their share, blocked per list, the most blocked names and the
        clients with the most blocked queries (jarl stats top blocked,
        top blocked-clients). Blocked answers no longer count as names that
        don't exist.
      • The view choice in the web UI's forms is a compact dropdown, however
        many views there are.
      • A blocking permission; database schema 6.

    Changed

    • Web UI: each view has its own page, like a zone: Settings (match lists,
      comment, colour), Options and Zones tabs (with New zone in VIEW),
      and Delete. The Views page lists them in order, with the arrows that
      reorder them; view links everywhere open the view's page.
    • Web UI: A and AAAA records have a + CNAME button that fills in the
      add form with a CNAME pointing to the record's name, leaving only the
      alias's name to type. It shows when the row is hovered or focused
      (always on touch screens).
    • Blocking page: how many queries each blocklist blocked in the last 24
      hours, and your rules together, with statistics on (linking to the
      Statistics page).
    • Options are kept in one fixed order, in named.conf, the web UI and the
      CLI: grouped by topic (files, listening, access control, recursion and
      forwarding, DNSSEC, transfers and notify, then the rest), alphabetical
      within a group. The same option is now in the same place in every view
      and zone. The first apply after upgrading reorders named.conf (a diff
      that only moves lines). Top-level statements keep their order.
    • Options that end in a list (allow-transfer, forwarders,
      listen-on, ...) can be given without their braces, in the web UI, CLI
      and API: 10.0.10.53; key xfer becomes { 10.0.10.53; key xfer; }.
      Before, only some server options (those edited one element per line)
      added them.
    • The dashboard's configuration checks include named-checkconf's own
      warnings about the running configuration (such as both "recursion no;" and "allow-recursion" active), which before only showed while applying.
      The CLI now prints them after an apply too.
    • Statistics page: cards and tiles fill their rows instead of leaving one
      alone beside an empty space, and the queries and failed answers charts
      have the same margins, so their time axes line up.
    • Dashboard: options have their own tile; "0 TSIG keys · 22 options" read
      as if the options belonged to the keys.
    • Web UI times use the 24-hour clock.
    • Diffs of named.conf say which block each change is in, after the @@
      line numbers (@@ -50,6 +49,8 @@ view "internal" {), like git does
      with function names. Moving an option from the server's options into a
      view no longer looks like two unrelated edits.
    • Web UI options (server, top-level, view and zone): values with blocks,
      such as logging, are shown and edited laid out as in named.conf, over
      several lines with indentation. The editor grows with its content, Tab
      indents and Enter keeps the indentation (Esc, then Tab, moves on). With
      a draft open, the tables show the draft's values, so a staged edit stays
      visible after Save.
    • The pending-changes banner has an Apply now button: it applies your
      draft without going to the Changes page, and stays on the page you're
      on. If the changes are refused, a dialog says why and links to Changes.
    • Blocking page: blocklists and rules have an Edit button (name, URL,
      views, comment; a rule's action and scope). The list button that
      downloads now is called Refresh, like jarl blocklist refresh.
    • Records table: disabled records are hatched and have a "disabled" badge
      next to their name, instead of only a muted colour and a badge in the
      comment column.

    Fixed

    • Reverting a changeset added needless "restore" operations for
      blocklists, rules and views that hadn't changed: copying the state
      turned their empty view lists into missing ones.
    • Under the shipped systemd unit, jarld couldn't list the host's
      addresses (it needs a netlink socket, which RestrictAddressFamilies
      didn't allow), so the name server checks didn't recognize this server's
      own addresses. The Name servers tab then queried them like another
      server's, and the delegation check didn't sign those queries with the
      view's key: with views, both got the view matching the server's own
      address (usually internal) and reported a wrong serial. The unit now
      allows AF_NETLINK, and without it jarld reads the addresses from
      /proc.
    • Statistics: after a reconfig that added, removed or recreated views
      (creating the first view, for instance), a minute could count everything
      since named started: millions of queries in an hour. A per-view counter
      (cache, upstream times, validation) going down was taken for a restart
      of named. Now only a new boot time means a restart, and a counter that
      goes down counts 0 for that minute.
    • Blocking page, checking a name: when your own block rule is for that very
      name, it offers to remove the rule instead of an allow rule, which was
      refused as a second rule for the same name. It also names the rule that
      matched rather than the policy zone entry.
    • docs/validation.md lacked the disabled_conflict warning added in 0.3.0.
    Downloads
  • v0.4.0-rc.4 8f0a0cc233

    Jarl v0.4.0-rc.4 Pre-release

    adam released this 2026-10-11 20:16:26 +01:00 | 83 commits to main since this release

    Upgrading from 0.3

    • Back up first (sudo jarld backup).
    • When jarld first starts, it rewrites named's configuration: options
      move into their new fixed order, and every view gets its view key in
      match-clients and keys.conf. It is checked with named-checkconf
      before named reloads, like any apply. Files you changed by hand are left
      alone; the log then says to run jarl resync.
    • The systemd unit changed (it allows AF_NETLINK). The package replaces
      it; an override that adds AF_NETLINK (systemctl edit jarl) does no
      harm and can be removed.
    • The database moves to schema 7 (disabled zones) as jarld starts.
    • If statistics showed a spike after views were created or changed, see
      "Statistics" under Fixed: the bad minutes can be removed from
      /var/lib/jarl/stats.db (minute rows have res = 'm'; the hours and
      days that include them are 'h' and 'd').

    Added

    • View keys: every view gets a TSIG key, jarl-view-NAME, at the front of
      its match-clients, so a query signed with it lands in that view from any
      address. Jarl signs its delegation check's queries to this server's own
      addresses with the key of the zone's view: before, they got whichever
      view matched the server's own address (usually internal), so the check
      could report the wrong serial for the external view. jarl view key VIEW shows a key, for dig -k (docs/views.md). The first apply after
      upgrading adds the keys to named.conf and keys.conf.
    • Server statistics: named's memory (resident, and its own count) and
      CPU use, its cache size, sockets, and recursive and TCP clients against
      their limits; the host's memory and load; free space where zone files,
      logs and Jarl's data are. Memory and CPU are kept over time like the
      other statistics. Statistics page → Server, jarl stats server, API
      /stats/server. Read from named's statistics channel, rndc status and
      /proc, with no extra privileges.
    • CLI: the record commands that change records take several views,
      --view internal,external, or --view all, and make the change in each,
      as one changeset (all views or none).
    • Blocking can be paused until resumed, like Pi-hole's "indefinitely":
      jarl block pause indefinitely, Until I resume on the Blocking page,
      {"indefinitely": true} in the API.
    • Disabled zones: a zone can be disabled instead of deleted. named stops
      loading it (its zone statement is left out of named.conf), while Jarl
      keeps it with its records, options and history, still editable;
      enabling it serves it as it is then. Disabling says what clients get
      instead (recursion, or REFUSED). Signed zones can't be disabled. Web
      UI: Disable/Enable on the zone page, a badge in the zone list. CLI:
      jarl zone disable|enable. API: PATCH /zones/{zone} with
      {"disabled": true}. Database schema 7.
    • Blocking (docs/blocking.md): named answers "doesn't exist" for ads,
      trackers and malware, using BIND's response policy zones.
      • Blocklists in Adblock, hosts or plain-domain format, downloaded by jarld
        and checked daily (blocking.refresh). A list is downloaded only when
        the server says it changed, checked with named-checkzone, and reloaded
        only when its content differs; a failed update keeps the previous
        version and shows on the dashboard.
      • Your own block and allow rules, for a domain and the names below it or
        the exact name. Rules take precedence over every list, and the most
        specific rule wins.
      • Lists and rules apply to chosen views, or to every view that offers
        recursion. They are configuration: staged, reviewed and reverted like
        any change.
      • Checking a name says whether it is blocked and by which rule or list
        entry, with an Allow button in the web UI.
      • Web UI: a Blocking page, with well-known lists to pick and named's
        memory per list. CLI: jarl blocklist and jarl block. API:
        /blocking/lists, /blocking/rules, /blocking/check.
      • Pausing: jarl block pause [DURATION] or the Blocking page lets every
        name through for a while (at most a day); blocking resumes by itself.
        The lists stay loaded, so it takes effect at once.
      • Statistics: blocked queries over time (a line on the queries chart)
        and their share, blocked per list, the most blocked names and the
        clients with the most blocked queries (jarl stats top blocked,
        top blocked-clients). Blocked answers no longer count as names that
        don't exist.
      • The view choice in the web UI's forms is a compact dropdown, however
        many views there are.
      • A blocking permission; database schema 6.

    Changed

    • Web UI: each view has its own page, like a zone: Settings (match lists,
      comment, colour), Options and Zones tabs (with New zone in VIEW),
      and Delete. The Views page lists them in order, with the arrows that
      reorder them; view links everywhere open the view's page.
    • Web UI: A and AAAA records have a + CNAME button that fills in the
      add form with a CNAME pointing to the record's name, leaving only the
      alias's name to type.
    • Options are kept in one fixed order, in named.conf, the web UI and the
      CLI: grouped by topic (files, listening, access control, recursion and
      forwarding, DNSSEC, transfers and notify, then the rest), alphabetical
      within a group. The same option is now in the same place in every view
      and zone. The first apply after upgrading reorders named.conf (a diff
      that only moves lines). Top-level statements keep their order.
    • Options that end in a list (allow-transfer, forwarders,
      listen-on, ...) can be given without their braces, in the web UI, CLI
      and API: 10.0.10.53; key xfer becomes { 10.0.10.53; key xfer; }.
      Before, only some server options (those edited one element per line)
      added them.
    • The dashboard's configuration checks include named-checkconf's own
      warnings about the running configuration (such as both "recursion no;" and "allow-recursion" active), which before only showed while applying.
      The CLI now prints them after an apply too.
    • Statistics page: cards and tiles fill their rows instead of leaving one
      alone beside an empty space, and the queries and failed answers charts
      have the same margins, so their time axes line up.
    • Dashboard: options have their own tile; "0 TSIG keys · 22 options" read
      as if the options belonged to the keys.
    • Web UI times use the 24-hour clock.
    • Diffs of named.conf say which block each change is in, after the @@
      line numbers (@@ -50,6 +49,8 @@ view "internal" {), like git does
      with function names. Moving an option from the server's options into a
      view no longer looks like two unrelated edits.
    • Web UI options (server, top-level, view and zone): values with blocks,
      such as logging, are shown and edited laid out as in named.conf, over
      several lines with indentation. The editor grows with its content, Tab
      indents and Enter keeps the indentation (Esc, then Tab, moves on). With
      a draft open, the tables show the draft's values, so a staged edit stays
      visible after Save.
    • The pending-changes banner has an Apply now button: it applies your
      draft without going to the Changes page, and stays on the page you're
      on. If the changes are refused, a dialog says why and links to Changes.
    • Blocking page: blocklists and rules have an Edit button (name, URL,
      views, comment; a rule's action and scope). The list button that
      downloads now is called Refresh, like jarl blocklist refresh.
    • Records table: disabled records are hatched and have a "disabled" badge
      next to their name, instead of only a muted colour and a badge in the
      comment column.

    Fixed

    • Under the shipped systemd unit, jarld couldn't list the host's
      addresses (it needs a netlink socket, which RestrictAddressFamilies
      didn't allow), so the name server checks didn't recognize this server's
      own addresses. The Name servers tab then queried them like another
      server's, and the delegation check didn't sign those queries with the
      view's key: with views, both got the view matching the server's own
      address (usually internal) and reported a wrong serial. The unit now
      allows AF_NETLINK, and without it jarld reads the addresses from
      /proc.
    • Statistics: after a reconfig that added, removed or recreated views
      (creating the first view, for instance), a minute could count everything
      since named started: millions of queries in an hour. A per-view counter
      (cache, upstream times, validation) going down was taken for a restart
      of named. Now only a new boot time means a restart, and a counter that
      goes down counts 0 for that minute.
    • Blocking page, checking a name: when your own block rule is for that very
      name, it offers to remove the rule instead of an allow rule, which was
      refused as a second rule for the same name. It also names the rule that
      matched rather than the policy zone entry.
    • docs/validation.md lacked the disabled_conflict warning added in 0.3.0.
    Downloads
  • v0.4.0-rc.3 ecffc2d5c1

    Jarl v0.4.0-rc.3 Pre-release

    adam released this 2026-10-11 18:35:13 +01:00 | 84 commits to main since this release

    Added

    • View keys: every view gets a TSIG key, jarl-view-NAME, at the front of
      its match-clients, so a query signed with it lands in that view from any
      address. Jarl signs its delegation check's queries to this server's own
      addresses with the key of the zone's view: before, they got whichever
      view matched the server's own address (usually internal), so the check
      could report the wrong serial for the external view. jarl view key VIEW shows a key, for dig -k (docs/views.md). The first apply after
      upgrading adds the keys to named.conf and keys.conf.
    • Server statistics: named's memory (resident, and its own count) and
      CPU use, its cache size, sockets, and recursive and TCP clients against
      their limits; the host's memory and load; free space where zone files,
      logs and Jarl's data are. Memory and CPU are kept over time like the
      other statistics. Statistics page → Server, jarl stats server, API
      /stats/server. Read from named's statistics channel, rndc status and
      /proc, with no extra privileges.
    • CLI: the record commands that change records take several views,
      --view internal,external, or --view all, and make the change in each,
      as one changeset (all views or none).
    • Blocking can be paused until resumed, like Pi-hole's "indefinitely":
      jarl block pause indefinitely, Until I resume on the Blocking page,
      {"indefinitely": true} in the API.
    • Disabled zones: a zone can be disabled instead of deleted. named stops
      loading it (its zone statement is left out of named.conf), while Jarl
      keeps it with its records, options and history, still editable;
      enabling it serves it as it is then. Disabling says what clients get
      instead (recursion, or REFUSED). Signed zones can't be disabled. Web
      UI: Disable/Enable on the zone page, a badge in the zone list. CLI:
      jarl zone disable|enable. API: PATCH /zones/{zone} with
      {"disabled": true}. Database schema 7.
    • Blocking (docs/blocking.md): named answers "doesn't exist" for ads,
      trackers and malware, using BIND's response policy zones.
      • Blocklists in Adblock, hosts or plain-domain format, downloaded by jarld
        and checked daily (blocking.refresh). A list is downloaded only when
        the server says it changed, checked with named-checkzone, and reloaded
        only when its content differs; a failed update keeps the previous
        version and shows on the dashboard.
      • Your own block and allow rules, for a domain and the names below it or
        the exact name. Rules take precedence over every list, and the most
        specific rule wins.
      • Lists and rules apply to chosen views, or to every view that offers
        recursion. They are configuration: staged, reviewed and reverted like
        any change.
      • Checking a name says whether it is blocked and by which rule or list
        entry, with an Allow button in the web UI.
      • Web UI: a Blocking page, with well-known lists to pick and named's
        memory per list. CLI: jarl blocklist and jarl block. API:
        /blocking/lists, /blocking/rules, /blocking/check.
      • Pausing: jarl block pause [DURATION] or the Blocking page lets every
        name through for a while (at most a day); blocking resumes by itself.
        The lists stay loaded, so it takes effect at once.
      • Statistics: blocked queries over time (a line on the queries chart)
        and their share, blocked per list, the most blocked names and the
        clients with the most blocked queries (jarl stats top blocked,
        top blocked-clients). Blocked answers no longer count as names that
        don't exist.
      • The view choice in the web UI's forms is a compact dropdown, however
        many views there are.
      • A blocking permission; database schema 6.

    Changed

    • Web UI: each view has its own page, like a zone: Settings (match lists,
      comment, colour), Options and Zones tabs (with New zone in VIEW),
      and Delete. The Views page lists them in order, with the arrows that
      reorder them; view links everywhere open the view's page.
    • Web UI: A and AAAA records have a + CNAME button that fills in the
      add form with a CNAME pointing to the record's name, leaving only the
      alias's name to type.
    • Options are kept in one fixed order, in named.conf, the web UI and the
      CLI: grouped by topic (files, listening, access control, recursion and
      forwarding, DNSSEC, transfers and notify, then the rest), alphabetical
      within a group. The same option is now in the same place in every view
      and zone. The first apply after upgrading reorders named.conf (a diff
      that only moves lines). Top-level statements keep their order.
    • Options that end in a list (allow-transfer, forwarders,
      listen-on, ...) can be given without their braces, in the web UI, CLI
      and API: 10.0.10.53; key xfer becomes { 10.0.10.53; key xfer; }.
      Before, only some server options (those edited one element per line)
      added them.
    • The dashboard's configuration checks include named-checkconf's own
      warnings about the running configuration (such as both "recursion no;" and "allow-recursion" active), which before only showed while applying.
      The CLI now prints them after an apply too.
    • Statistics page: cards and tiles fill their rows instead of leaving one
      alone beside an empty space, and the queries and failed answers charts
      have the same margins, so their time axes line up.
    • Dashboard: options have their own tile; "0 TSIG keys · 22 options" read
      as if the options belonged to the keys.
    • Web UI times use the 24-hour clock.
    • Diffs of named.conf say which block each change is in, after the @@
      line numbers (@@ -50,6 +49,8 @@ view "internal" {), like git does
      with function names. Moving an option from the server's options into a
      view no longer looks like two unrelated edits.
    • Web UI options (server, top-level, view and zone): values with blocks,
      such as logging, are shown and edited laid out as in named.conf, over
      several lines with indentation. The editor grows with its content, Tab
      indents and Enter keeps the indentation (Esc, then Tab, moves on). With
      a draft open, the tables show the draft's values, so a staged edit stays
      visible after Save.
    • The pending-changes banner has an Apply now button: it applies your
      draft without going to the Changes page, and stays on the page you're
      on. If the changes are refused, a dialog says why and links to Changes.
    • Blocking page: blocklists and rules have an Edit button (name, URL,
      views, comment; a rule's action and scope). The list button that
      downloads now is called Refresh, like jarl blocklist refresh.
    • Records table: disabled records are hatched and have a "disabled" badge
      next to their name, instead of only a muted colour and a badge in the
      comment column.

    Fixed

    • Statistics: after a reconfig that added, removed or recreated views
      (creating the first view, for instance), a minute could count everything
      since named started: millions of queries in an hour. A per-view counter
      (cache, upstream times, validation) going down was taken for a restart
      of named. Now only a new boot time means a restart, and a counter that
      goes down counts 0 for that minute.
    • Blocking page, checking a name: when your own block rule is for that very
      name, it offers to remove the rule instead of an allow rule, which was
      refused as a second rule for the same name. It also names the rule that
      matched rather than the policy zone entry.
    • docs/validation.md lacked the disabled_conflict warning added in 0.3.0.
    Downloads
  • v0.4.0-rc.2 73d97ecc0a

    Jarl v0.4.0-rc.2 Pre-release

    adam released this 2026-10-11 16:51:29 +01:00 | 90 commits to main since this release

    Added

    • Disabled zones: a zone can be disabled instead of deleted. named stops
      loading it (its zone statement is left out of named.conf), while Jarl
      keeps it with its records, options and history, still editable;
      enabling it serves it as it is then. Disabling says what clients get
      instead (recursion, or REFUSED). Signed zones can't be disabled. Web
      UI: Disable/Enable on the zone page, a badge in the zone list. CLI:
      jarl zone disable|enable. API: PATCH /zones/{zone} with
      {"disabled": true}. Database schema 7.
    • Blocking (docs/blocking.md): named answers "doesn't exist" for ads,
      trackers and malware, using BIND's response policy zones.
      • Blocklists in Adblock, hosts or plain-domain format, downloaded by jarld
        and checked daily (blocking.refresh). A list is downloaded only when
        the server says it changed, checked with named-checkzone, and reloaded
        only when its content differs; a failed update keeps the previous
        version and shows on the dashboard.
      • Your own block and allow rules, for a domain and the names below it or
        the exact name. Rules take precedence over every list, and the most
        specific rule wins.
      • Lists and rules apply to chosen views, or to every view that offers
        recursion. They are configuration: staged, reviewed and reverted like
        any change.
      • Checking a name says whether it is blocked and by which rule or list
        entry, with an Allow button in the web UI.
      • Web UI: a Blocking page, with well-known lists to pick and named's
        memory per list. CLI: jarl blocklist and jarl block. API:
        /blocking/lists, /blocking/rules, /blocking/check.
      • Pausing: jarl block pause [DURATION] or the Blocking page lets every
        name through for a while (at most a day); blocking resumes by itself.
        The lists stay loaded, so it takes effect at once.
      • Statistics: blocked queries over time (a line on the queries chart)
        and their share, blocked per list, the most blocked names and the
        clients with the most blocked queries (jarl stats top blocked,
        top blocked-clients). Blocked answers no longer count as names that
        don't exist.
      • The view choice in the web UI's forms is a compact dropdown, however
        many views there are.
      • A blocking permission; database schema 6.

    Changed

    • Web UI options (server, top-level, view and zone): values with blocks,
      such as logging, are shown and edited laid out as in named.conf, over
      several lines with indentation. The editor grows with its content, Tab
      indents and Enter keeps the indentation (Esc, then Tab, moves on). With
      a draft open, the tables show the draft's values, so a staged edit stays
      visible after Save.
    • The pending-changes banner has an Apply now button: it applies your
      draft without going to the Changes page, and stays on the page you're
      on. If the changes are refused, a dialog says why and links to Changes.
    • Blocking page: blocklists and rules have an Edit button (name, URL,
      views, comment; a rule's action and scope). The list button that
      downloads now is called Refresh, like jarl blocklist refresh.
    • Records table: disabled records are hatched and have a "disabled" badge
      next to their name, instead of only a muted colour and a badge in the
      comment column.

    Fixed

    • Statistics: after a reconfig that added, removed or recreated views
      (creating the first view, for instance), a minute could count everything
      since named started: millions of queries in an hour. A per-view counter
      (cache, upstream times, validation) going down was taken for a restart
      of named. Now only a new boot time means a restart, and a counter that
      goes down counts 0 for that minute.
    • Blocking page, checking a name: when your own block rule is for that very
      name, it offers to remove the rule instead of an allow rule, which was
      refused as a second rule for the same name. It also names the rule that
      matched rather than the policy zone entry.
    • docs/validation.md lacked the disabled_conflict warning added in 0.3.0.
    Downloads
  • v0.4.0-rc.1 59baccd636

    Jarl v0.4.0-rc.1 Pre-release

    adam released this 2026-10-10 13:56:15 +01:00 | 93 commits to main since this release

    Added

    • Blocking (docs/blocking.md): named answers "doesn't exist" for ads,
      trackers and malware, using BIND's response policy zones.
      • Blocklists in Adblock, hosts or plain-domain format, downloaded by jarld
        and checked daily (blocking.refresh). A list is downloaded only when
        the server says it changed, checked with named-checkzone, and reloaded
        only when its content differs; a failed update keeps the previous
        version and shows on the dashboard.
      • Your own block and allow rules, for a domain and the names below it or
        the exact name. Rules take precedence over every list, and the most
        specific rule wins.
      • Lists and rules apply to chosen views, or to every view that offers
        recursion. They are configuration: staged, reviewed and reverted like
        any change.
      • Checking a name says whether it is blocked and by which rule or list
        entry, with an Allow button in the web UI.
      • Web UI: a Blocking page, with well-known lists to pick and named's
        memory per list. CLI: jarl blocklist and jarl block. API:
        /blocking/lists, /blocking/rules, /blocking/check.
      • Pausing: jarl block pause [DURATION] or the Blocking page lets every
        name through for a while (at most a day); blocking resumes by itself.
        The lists stay loaded, so it takes effect at once.
      • Statistics: blocked queries over time (a line on the queries chart)
        and their share, blocked per list, the most blocked names and the
        clients with the most blocked queries (jarl stats top blocked,
        top blocked-clients). Blocked answers no longer count as names that
        don't exist.
      • The view choice in the web UI's forms is a compact dropdown, however
        many views there are.
      • A blocking permission; database schema 6.

    Changed

    • Web UI options (server, top-level, view and zone): values with blocks,
      such as logging, are shown and edited laid out as in named.conf, over
      several lines with indentation. The editor grows with its content, Tab
      indents and Enter keeps the indentation (Esc, then Tab, moves on). With
      a draft open, the tables show the draft's values, so a staged edit stays
      visible after Save.
    • The pending-changes banner has an Apply now button: it applies your
      draft without going to the Changes page, and stays on the page you're
      on. If the changes are refused, a dialog says why and links to Changes.
    • Blocking page: blocklists and rules have an Edit button (name, URL,
      views, comment; a rule's action and scope). The list button that
      downloads now is called Refresh, like jarl blocklist refresh.
    • Records table: disabled records are hatched and have a "disabled" badge
      next to their name, instead of only a muted colour and a badge in the
      comment column.

    Fixed

    • Blocking page, checking a name: when your own block rule is for that very
      name, it offers to remove the rule instead of an allow rule, which was
      refused as a second rule for the same name. It also names the rule that
      matched rather than the policy zone entry.
    • docs/validation.md lacked the disabled_conflict warning added in 0.3.0.
    Downloads
  • v0.3.0 436cd79ec9

    Jarl v0.3.0 Stable

    adam released this 2026-10-10 00:39:15 +01:00 | 100 commits to main since this release

    Added

    • Disabled records: a record can be disabled instead of deleted. It stays
      in Jarl with its ID, TTL and comment but is left out of the zone (the
      zone file lists it as a comment), and enabling it puts it back exactly
      as it was. Web UI: a Disable/Enable button on each record, disabled
      records greyed out with a badge, a filter for them, and a count in the
      zone list. CLI: jarl record disable|enable (by ID or by name, type and
      data, --ptr for the PTR record, --missing-ok), record list --disabled, and disable:/enable: entries for jarl apply -f. API:
      POST /records/{id}/disable|enable, POST /zones/{zone}/records/disable|enable, a disabled field on records,
      ?disabled= on record lists and record.disable|enable operations.
      Validation checks the zone as it is served: the last NS record can't be
      disabled, enabling a record is checked like adding it, and a disabled
      record that a CNAME now blocks gets a warning. Database schema 5.

    • DNSSEC for a zone whose parent zone is in Jarl: the DNSSEC tab gives the
      jarl record add PARENT NAME DS ... command to copy and an "Add to
      PARENT" button (staged like any change), links to the parent zone, and
      says when the parent has the DS record. jarl zone dnssec status prints
      the command too, and turning signing off gives the matching jarl record delete.

    • CLI output for scripts: -o id prints just the IDs of what a command
      shows or lists (jarl zone show adbraun.lol -o id), -o field=view,soa.serial just those fields, tab separated. -q on show
      and list prints the IDs too. With a change (jarl record add ... -o id) they apply to the changed object.

    • Statistics: client lists (busiest and refused clients, in the web UI,
      jarl stats top clients|refused and jarl stats summary) show the host
      name Jarl's records have for each address: the PTR record's target, or
      else the name of an A/AAAA record. Looked up in Jarl's own data, so no
      DNS queries; an address without a record shows as before.

    • Zones list: a padlock after each signed zone's name, linking to its
      DNSSEC tab (open and amber while signing is being turned off).

    Changed

    • The web UI and API can listen on ports below 1024, such as 443:
      jarl.service now gives jarld the CAP_NET_BIND_SERVICE capability
      (and only that). With a unit that doesn't, jarld's error says what's
      missing. See docs/configuration.md, "HTTPS on port 443".
    • Records table: names are no longer greyed out when they repeat the row
      above (it made those records look inactive). Records of the same name
      are separated by a faint line instead, and a full line marks where the
      next name starts.

    Fixed

    • jarl record list: one long value (a DKIM key) padded every row to its
      length, so on a terminal each row wrapped onto a second, blank-looking
      line. Long data is now shortened to fit the terminal; --wide shows it
      in full, as does output to a pipe or file.
    Downloads
  • v0.3.0-rc.2 c645dae14f

    Jarl v0.3.0-rc.2 Pre-release

    adam released this 2026-10-10 00:27:56 +01:00 | 101 commits to main since this release

    Added

    • Disabled records: a record can be disabled instead of deleted. It stays
      in Jarl with its ID, TTL and comment but is left out of the zone (the
      zone file lists it as a comment), and enabling it puts it back exactly
      as it was. Web UI: a Disable/Enable button on each record, disabled
      records greyed out with a badge, a filter for them, and a count in the
      zone list. CLI: jarl record disable|enable (by ID or by name, type and
      data, --ptr for the PTR record, --missing-ok), record list --disabled, and disable:/enable: entries for jarl apply -f. API:
      POST /records/{id}/disable|enable, POST /zones/{zone}/records/disable|enable, a disabled field on records,
      ?disabled= on record lists and record.disable|enable operations.
      Validation checks the zone as it is served: the last NS record can't be
      disabled, enabling a record is checked like adding it, and a disabled
      record that a CNAME now blocks gets a warning. Database schema 5.

    • DNSSEC for a zone whose parent zone is in Jarl: the DNSSEC tab gives the
      jarl record add PARENT NAME DS ... command to copy and an "Add to
      PARENT" button (staged like any change), links to the parent zone, and
      says when the parent has the DS record. jarl zone dnssec status prints
      the command too, and turning signing off gives the matching jarl record delete.

    • CLI output for scripts: -o id prints just the IDs of what a command
      shows or lists (jarl zone show adbraun.lol -o id), -o field=view,soa.serial just those fields, tab separated. -q on show
      and list prints the IDs too. With a change (jarl record add ... -o id) they apply to the changed object.

    • Statistics: client lists (busiest and refused clients, in the web UI,
      jarl stats top clients|refused and jarl stats summary) show the host
      name Jarl's records have for each address: the PTR record's target, or
      else the name of an A/AAAA record. Looked up in Jarl's own data, so no
      DNS queries; an address without a record shows as before.

    • Zones list: a padlock after each signed zone's name, linking to its
      DNSSEC tab (open and amber while signing is being turned off).

    Changed

    • The web UI and API can listen on ports below 1024, such as 443:
      jarl.service now gives jarld the CAP_NET_BIND_SERVICE capability
      (and only that). With a unit that doesn't, jarld's error says what's
      missing. See docs/configuration.md, "HTTPS on port 443".
    • Records table: names are no longer greyed out when they repeat the row
      above (it made those records look inactive). Records of the same name
      are separated by a faint line instead, and a full line marks where the
      next name starts.

    Fixed

    • jarl record list: one long value (a DKIM key) padded every row to its
      length, so on a terminal each row wrapped onto a second, blank-looking
      line. Long data is now shortened to fit the terminal; --wide shows it
      in full, as does output to a pipe or file.
    Downloads