Add DNSSEC signing, key backups and Porkbun support

Zones get a DNSSEC setting: named signs them with BIND's default (or a
custom) dnssec-policy and inline signing, with keys in a per-view key
directory. Jarl shows the keys, the DS record and when it is safe to
publish it, checks the parent's DS records (check-ds, which also tells
named), and refuses steps that would break a signed domain: switching
straight to unsigned, finishing a turn-off too early, deleting or moving
a signed zone, TTLs above max-zone-ttl. Turning off goes through the
insecure policy; wipe starts over once the parent has no DS.

Backups store the DNSSEC keys and restore puts them back for named; the
backup unit gets CAP_DAC_READ_SEARCH to read them. Jarl raises a zone's
serial above named's whenever it writes an older one (after a restore).
The serials check compares the signed serial.

With a Porkbun API key in jarl.yaml, the registrar's name servers, glue
records and DS records can be shown and changed, each change checked
first (dry run, force to override).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-08 21:19:04 +00:00
1 parent 293e6ddd33
commit 5630e7a848
72 files changed
+5760 -153

No files matched your search

+46
View File
@@ -10,6 +10,41 @@ The first version, to be released as 0.1.0.
### Added
- DNSSEC signing per zone (docs/dnssec.md): `jarl zone dnssec
enable|status|check-ds|disable|wipe` and the zone page's DNSSEC tab, or
the zone's new `dnssec_policy` field in the API. named signs the zone
with BIND's `default` policy (one ECDSA P-256 key that is never replaced)
or a custom one, using inline signing, with keys in a per-view directory
under `/var/lib/bind/jarl/dnssec-keys`. Jarl shows the keys and the DS
record to give the registrar, says when it's safe to publish it, and
checks the parent's DS records (`check-ds`, which also tells named with
`rndc dnssec -checkds`). It refuses steps that would break a signed
domain: switching straight to unsigned (it goes through BIND's
`insecure` policy instead, and finishes only once named is done),
deleting a signed zone or moving it to another view, and TTLs above the
policy's `max-zone-ttl`. `wipe` starts over with a clean slate once the
parent has no DS. Each step in the web UI opens a dialog that says what it
needs first. `jarl zone delegation` now also compares the parent's DS
records with the zone's keys.
- Porkbun support (optional, docs/dnssec.md#porkbun): with an API key in
the new `porkbun:` section of jarl.yaml (and nowhere else), `jarl zone
registrar status|sync-glue|set-ns|publish-ds|remove-ds` and the zone
page's Registrar tab show and change the domain's name servers, glue
records (one per name server inside the domain, with all its IPv4 and
IPv6 addresses) and DS records at Porkbun. Every change first checks that
it won't take the domain offline (the name servers answer for the zone,
glue matches, a DS goes out only once the domain is delegated to servers
that serve the signed zone, DS records match the zone's keys before the
name servers change); `--dry-run` shows the checks and `--force` skips
them. Administrators only.
- Backups include the DNSSEC keys (private keys too), stored inside the
backup file, and `jarld restore` puts them back for named
(`bind.named_user`, default `bind`). `jarl-backup.service` has
`CAP_DAC_READ_SEARCH` to read them; `--without-keys` skips them.
- Jarl raises a zone's serial above the one named has loaded whenever it
writes a zone file whose serial isn't higher (after restoring an older
database, say), so named loads it (it refuses otherwise for a signed
zone) and secondaries pick it up.
- Daily database backups: the `jarl-backup.timer` systemd timer (turned on
by the Debian package) runs `jarld backup`, which writes
`jarl-<UTC time>.db` into `backup.dir` (`/var/backups/jarl`), checks it
@@ -219,6 +254,17 @@ The first version, to be released as 0.1.0.
### Changed
- `jarl zone serials` compares the serial named serves, which for a signed
zone is the signed zone's (ahead of Jarl's).
- `jarld import` turns `dnssec-policy` in an existing configuration into
the zones' DNSSEC setting, and warns that their keys must be moved into
Jarl's key directory before adopting.
- `dnssec-policy` is no longer accepted as a zone, view or server option
(zones have a DNSSEC setting instead), nor `key-directory` as a zone
option.
- Deleting a zone also removes the journal and signed files named kept
next to it.
- Web UI: the review/live switch is a small "Review edits" / "Live edits"
button in the header, and the bar below it only appears while there are
pending changes.