• Jarl v0.4.1-rc.2
    release / release (push) Successful in 7m35s
    Pre-Release

    adam released this 2026-10-12 13:44:10 +00:00 | 60 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