Home / Alt manpages / dnssec-trust-anchors.d(5)

  • dnssec-trust-anchors.d(5)
  • File format
  • linux

Configure DNSSEC Trust Anchors with systemd-resolved

You will add a DNSSEC trust anchor or a narrowly scoped negative trust anchor for systemd-resolved, verify that the file is selected, and have a recovery path if the change breaks lookups. Allow about 15 minutes, plus time to verify any key material with its operator or an authoritative source.

This guide follows the installed dnssec-trust-anchors.d(5) manual from systemd 255. Trust anchors affect DNS security decisions, so do not paste a key from an untrusted message or disable validation as a general troubleshooting shortcut.

1. Check the resolver and the configuration paths

First confirm that the service and command-line tools are present. These checks do not change anything and normally need no elevated privileges.

$ systemctl is-active systemd-resolved
active
$ systemctl --version | head -1
systemd 255 (255.4-1ubuntu8.17)
$ resolvectl status

In the resolvectl output, look for the DNSSEC= state on the relevant link. no/unsupported means this machine is not currently reporting usable DNSSEC support; adding a file alone does not make an upstream DNS server validate records.

Positive files end in .positive and negative files end in .negative. The directories are searched in this order: /etc/dnssec-trust-anchors.d/, /run/dnssec-trust-anchors.d/, then /usr/lib/dnssec-trust-anchors.d/. A same-named file in an earlier directory overrides one later in the list.

2. Choose the smallest change

Use a positive anchor when you have a verified DS or DNSKEY record that should be trusted as the base of DNSSEC validation. A DS record is the recommended form. Use a negative anchor only for a private DNS subtree that is intentionally unsigned or cannot be validated through the public DNS hierarchy.

Most installations do not need a root positive file. When no root anchor is configured, systemd-resolved uses its built-in Internet root key. Defining even one positive root key disables that built-in key, so an obsolete or mistyped root file can make ordinary Internet lookups fail.

3. Add a positive anchor from verified data

Get the record from the zone operator or a primary source such as the IANA root trust-anchor data. Check the key tag, algorithms and digest independently before installing it. The following is the current root DS value published by IANA at the time this guide was written; treat it as an example to compare with the live source, not as a reason to stop checking updates.

$ sudo install -d -m 0755 /etc/dnssec-trust-anchors.d
$ if sudo test -e /etc/dnssec-trust-anchors.d/iana-root.positive; then sudo cp --preserve=all /etc/dnssec-trust-anchors.d/iana-root.positive /etc/dnssec-trust-anchors.d/iana-root.positive.before-change; fi
$ sudo sh -c 'printf "%s\n" ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D" > /etc/dnssec-trust-anchors.d/iana-root.positive'

The line has five meaningful fields: the domain, IN, DS, key tag, signature algorithm, digest algorithm and hexadecimal digest. The root domain is written as .. Comments beginning with # or ; and empty lines are ignored.

Before making this root-level change, save the current state and check the file you are about to use. The commands below are read-only after the installation step:

$ sudo sed -n '1,5p' /etc/dnssec-trust-anchors.d/iana-root.positive
$ sudo systemctl restart systemd-resolved
$ resolvectl status

Restarting the resolver briefly interrupts name resolution for applications using it. If your distribution reloads this configuration without a restart, the restart is still a clear way to make the check reproducible; do it during a suitable maintenance window.

4. Add a negative anchor only for a private subtree

A negative anchor disables DNSSEC validation for the named domain and everything below it. For a private namespace such as corp.example, create one line in an .negative file. The filename is local policy, so choose a descriptive name.

$ sudo install -d -m 0755 /etc/dnssec-trust-anchors.d
$ sudo sh -c 'printf "%s\n" "corp.example" > /etc/dnssec-trust-anchors.d/corp.negative'
$ sudo systemctl restart systemd-resolved
$ resolvectl status'

Do not put a public domain in this file to silence a DNSSEC error. That hides an integrity failure from every client using this resolver. For interface-specific policy, the manual points to DNSSECNegativeTrustAnchors= in a systemd.network file instead.

5. Check precedence and failure recovery

When a package supplies a file under /usr/lib/dnssec-trust-anchors.d/, an identically named file under /etc takes precedence. An empty file or a symlink to /dev/null masks the packaged file. Inspect all three locations if the contents you expect are not being used:

$ for d in /etc/dnssec-trust-anchors.d /run/dnssec-trust-anchors.d /usr/lib/dnssec-trust-anchors.d; do
>   printf '%s\n' "$d"
>   find "$d" -maxdepth 1 \( -type f -o -type l \) -name '*.positive' -o -name '*.negative' 2>/dev/null | sort
> done
$ journalctl -u systemd-resolved -b --no-pager

If lookups fail after your change, remove or rename the file you added, then restart the service. Removing a file is a state change, so identify the exact path first:

$ sudo rm -- /etc/dnssec-trust-anchors.d/iana-root.positive
$ sudo systemctl restart systemd-resolved
$ resolvectl status

This restores the built-in root anchor when no other root positive file remains. If you replaced a pre-existing local file, restore the backup you made rather than deleting it. Do not remove package-owned files in /usr/lib to troubleshoot an override.

Done means

  • The installed systemd version and active systemd-resolved service were checked.
  • Any positive key was obtained and verified from a primary source, with the root built-in-anchor consequence understood.
  • Any negative anchor names only the private DNS subtree that needs validation disabled.
  • The selected paths, resolver state and journal were checked after the change.
  • A precise recovery command is available, and package files under /usr/lib were left untouched.