Merge branch 'dnssec'

The DNSSEC notes in CHANGELOG.md belong under Unreleased; git had put
them into the 0.1.0 section, which didn't exist when the branch was made.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-09 15:16:33 +00:00
commit 24a2c875fa
72 files changed
+5759 -153

No files matched your search

+43
View File
@@ -100,6 +100,7 @@ bind:
zone_dir: $E/zones
cache_dir: $E/cache/jarl
file_group: ""
named_user: $(id -un)
named_checkconf: $CHECKCONF
named_checkzone: $CHECKZONE
rndc: $RNDC
@@ -305,9 +306,32 @@ contains "soon"
run "status lists the expiring token" 0 $J status
contains "Token:.*soon"
# DNSSEC: sign the external view's zone (the parent can't be asked here).
api() { curl -s -H "Authorization: Bearer $(cat $E/admin.token)" -H 'Content-Type: application/json' "$@"; }
run "dnssec status: off" 0 $J zone dnssec status adbraun.test --view external
contains "Policy:.*none"
run "dnssec enable" 0 $J zone dnssec enable adbraun.test --view external
contains "named is signing"
for i in $(seq 50); do $J zone dnssec status adbraun.test --view external 2>/dev/null | grep -q "signed serial" && break; sleep 0.2; done
run "dnssec status: signing" 0 $J zone dnssec status adbraun.test --view external
contains "CSK.*ECDSAP256SHA256"
contains "named:.*signed serial"
contains "DS record for the parent zone"
contains "not yet: wait until"
run "dnssec: switching off at once is refused" 0 api -X PATCH -d '{"dnssec_policy":""}' "http://127.0.0.1:$HTTP/api/v1/zones/adbraun.test?view=external"
contains "switching DNSSEC off at once"
run "dnssec: a TTL over a day is refused" 6 $J record add adbraun.test longttl A 203.0.113.9 --view external --ttl 172800
contains "max-zone-ttl"
run "record in the signed zone" 0 $J record add adbraun.test signed A 203.0.113.5 --view external
run "check-ds without a reachable parent (exit 2)" 2 $J zone dnssec check-ds adbraun.test --view external --resolver 127.0.0.1
contains "named wasn't told anything"
KEYS=$(ls $E/zones/dnssec-keys/*/Kadbraun.test.+013+*.private 2>/dev/null | head -1)
if [ -n "$KEYS" ]; then ok "named's key is in Jarl's key directory"; else bad "no key in $E/zones/dnssec-keys"; fi
# Backups and restore
run "jarld backup" 0 $JARLD -c jarl.yaml backup
contains "Database backed up to $E/backups/jarl-"
contains "with 3 DNSSEC key files"
run "status shows the backup" 0 $J status
contains "Backup:.*$E/backups/jarl-"
run "restore refused while jarld runs" 1 $JARLD -c jarl.yaml restore latest --yes
@@ -317,20 +341,39 @@ contains "in use by a running jarld"
run "record after the backup" 0 $J record add adbraun.test afterbackup A 192.168.1.99 --view internal
expect_dig "afterbackup A" "192.168.1.99" afterbackup.adbraun.test A
kill $JARLD_PID; wait $JARLD_PID 2>/dev/null
KEYSUM=$(sha256sum "$KEYS" | cut -d' ' -f1)
rm -f "$KEYS"
run "jarld restore lists backups" 0 $JARLD -c jarl.yaml restore
contains "jarl-.*\.db"
run "jarld restore latest" 0 $JARLD -c jarl.yaml restore latest --yes
contains "previous database is in"
contains "Put back 3 DNSSEC key files"
if [ "$(sha256sum "$KEYS" 2>/dev/null | cut -d' ' -f1)" = "$KEYSUM" ]; then ok "the private key is back"; else bad "the private key wasn't restored"; fi
$JARLD -c jarl.yaml serve >> jarld.log 2>&1 &
JARLD_PID=$!
for i in $(seq 50); do curl -s -o /dev/null http://127.0.0.1:$HTTP/healthz && break; sleep 0.2; done
run "restored database lacks the later record" 0 $J record list adbraun.test --view internal
if echo "$OUT" | grep -q afterbackup; then bad "afterbackup still there after restore"; else ok "afterbackup gone after restore"; fi
run "resync after restore" 0 $J resync --force
contains "serial"
expect_dig "afterbackup gone from named" "" afterbackup.adbraun.test A
run "audit shows the restore" 0 $J audit --action system.restore
contains "system.restore"
# Turning DNSSEC off: insecure first; the DS never reached a parent, so
# named can finish at once. Then wipe the old keys.
run "dnssec disable starts turning off" 0 $J zone dnssec disable adbraun.test --view external --yes
contains "remove the DS record"
for i in $(seq 75); do $J zone dnssec status adbraun.test --view external 2>/dev/null | grep -q "Turning DNSSEC off: the parent has no DS\|has finished" && break; sleep 0.2; done
run "dnssec disable finishes" 0 $J zone dnssec disable adbraun.test --view external --yes
contains "DNSSEC is off"
run "dnssec status: old keys left" 0 $J zone dnssec status adbraun.test --view external
contains "keys from when the zone was signed"
run "dnssec wipe" 0 $J zone dnssec wipe adbraun.test --view external --yes --force --resolver 127.0.0.1
contains "removed .*Kadbraun.test"
run "dnssec status: clean" 0 $J zone dnssec status adbraun.test --view external
contains "Status:.*DNSSEC is off.$"
run "status at the end" 0 $J status
contains "Drift:.*none"