Skip to content

unbound-anchor to update root.key is noisy #2134

Description

@bwbroersma

See: https://github.com/internetstandards/Internet.nl/commits/main/remote_data/dns/root.key

Note: since the latest KSK 2024-04-26 which appeared on 2025-01-11 in the root zone no root KSK keys were changed, however due to the order and metadata, there are more commits changing the order, or just updating the metadata, while only one change was needed after 2025-01-11.
The problem is:

Internet.nl/Makefile

Lines 64 to 65 in cec0e01

update_root_key_file: ## update root key file
${DOCKER_COMPOSE_TOOLS_CMD} run --rm tools /opt/unbound/sbin/unbound-anchor -a $(DNSDIR)/root.key

Since unbound-anchor does fetching and validating, maybe wrap it in a script, e.g.:

#!/usr/bin/env sh
set -u

ROOT_KEY=remote_data/dns/root.key

/opt/unbound/sbin/unbound-anchor -a "$ROOT_KEY"
LC_ALL=C sed -r 's/;;.*//g;s/^(.) [0-9]' > "$NEW_ROOT_PLAIN"
sort "$ROOT_KEY" | sed -r 's/;;.*//g' > "$TMP_ROOT_PLAIN"

if [ -n "$(diff "$TMP_ROOT_PLAIN" "$NEW_ROOT_PLAIN")" ]; then
  mv "$NEW_ROOT" "$ROOT_KEY"
  echo "\e[42mDNSSEC root.key updated\e[0m"
else
  echo "\e[42mDNSSEC root.key OK\e[0m nothing changed."
fi

By default unbound-anchor queries the root via DNS, although the root anchors might not have been changed, and should have a TTL of 172800 (2 days), it depends on the docker host DNS, e.g. when running vanilla unbound the cache-max-ttl default is 86400 (1 day) ... I cannot seem to solve it by tweaking arguments (e.g. -f /dev/null -R still has this problem), while the -F option changes the file to DS records only (without TTL), instead of the current DNSKEY KSK records:

; created by unbound-anchor on Wed Jul 29 21:23:48 2026
. IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
. IN DS 38696 8 2 683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16

Maybe the TTL should always be stripped, e.g.:

#!/usr/bin/env sh
set -u

ROOT_KEY=remote_data/dns/root.key

/opt/unbound/sbin/unbound-anchor -a "$ROOT_KEY"
# The following sed rules do:
# s/ *;;.*//g				remove all metadata comments
# s/^(.\t)[0-9]+\t/\1/g		remove all TTLs
# /^$/d						delete empty lines
sed -ri 's/ *;;.*//g;s/^(.\t)[0-9]+\t/\1/g;/^$/d' "$ROOT_KEY"
# use C to have binary order and reverse to put ; above .
LC_ALL=C sort -ro "$ROOT_KEY" "$ROOT_KEY"

which would produce a stable output without timing metadata:

; autotrust trust anchor file
.	IN	DNSKEY	257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU= ;{id = 20326 (ksk), size = 2048b}
.	IN	DNSKEY	257 3 8 AwEAAa96jeuknZlaeSrvyAJj6ZHv28hhOKkx3rLGXVaC6rXTsDc449/cidltpkyGwCJNnOAlFNKF2jBosZBU5eeHspaQWOmOElZsjICMQMC3aeHbGiShvZsx4wMYSjH8e7Vrhbu6irwCzVBApESjbUdpWWmEnhathWu1jo+siFUiRAAxm9qyJNg/wOZqqzL/dL/q8PkcRU5oUKEpUge71M3ej2/7CPqpdVwuMoTvoB+ZOT4YeGyxMvHmbrxlFzGOHOijtzN+u1TQNatX2XBuzZNQ1K+s2CXkPIZo7s6JgZyvaBevYtxPvYLw4z9mR7K2vaF18UYH9Z9GNUUeayffKC73PYc= ;{id = 38696 (ksk), size = 2048b}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions