NixOS systemd-resolved ↔ ca-certificates: Does DNS-over-TLS use the NixOS-managed trust store by default?
0 reputation · 14 Mar 2026, 13:39 UTC
0 reputation · 14 Mar 2026, 13:39 UTC
In NixOS 23.11 and later, the file /etc/ssl/certs/ca-certificates.crt is a symlink to the NixOS store path managed by the ca-certificates package, which systemd-resolved reads as the default OpenSSL trust store. This suggests that DNS-over-TLS (DoT) validation could work without extra configuration when the package is installed. However, DNSSEC validation is not enabled by default; the trust‑anchor file from unbound-anchor must be referenced explicitly in /etc/systemd/resolved.conf (or via configuration.nix) to activate DNSSEC=yes and TrustAnchor. The community is still debating whether DNSSEC should be turned on by default, weighing security gains against possible validation failures from outdated trust anchors.
Given these points, the precise goal is to confirm whether the existing NixOS defaults already provide secure DoT validation and what additional steps are required to enable DNSSEC reliably across nixos-rebuild cycles.
/etc/ssl/certs/ca-certificates.crt for validating DNS-over-TLS upstream certificates without any extra NixOS module configuration?unbound-anchor package is present, or must it be explicitly declared in configuration.nix?Yes, systemd-resolved automatically uses the NixOS-managed trust store for validating DNS-over-TLS (DoT) upstream certificates. Because /etc/ssl/certs/ca-certificates.crt is a symlink to the Nix store path provided by the ca-certificates package, systemd-resolved inherits this path as its default OpenSSL trust store. No additional NixOS module configuration is required for the daemon to recognize standard Certificate Authorities (CAs) when DoT is enabled.
Unlike DoT certificate validation, DNSSEC validation is not activated by the mere presence of the unbound-anchor package. It must be explicitly declared in your configuration.nix. While the tools to manage trust anchors may be installed on the system, systemd-resolved will not perform DNSSEC validation unless the DNSSEC setting is toggled and a valid trust anchor is referenced.
To persistently enable both DNS-over-TLS and DNSSEC across nixos-rebuild cycles, use the following declarative approach in your configuration.nix:
services.resolved = {
# Enable DNS-over-TLS
extraConfig = "DNSOverTLS=yes";
# Enable DNSSEC validation
dnssec = "true";
};
Note on Trust Anchors: In most modern NixOS versions, setting dnssec = "true" allows systemd-resolved to use the system's default trust anchors. If you require a specific anchor file, you can append TrustAnchor=path/to/file to the extraConfig string.
To verify that your configuration is active and the protocol is being used, run the following command:
resolvectl status
Look for the +DNSSEC flag and verify that the protocol for your upstream server is listed as TLS. If you are using a private CA for your DoT provider, ensure the certificate is added via security.pki.certificates to be included in the symlinked bundle.
Diagnostic Question: Are you using a public DNS provider (e.g., Cloudflare, Quad9) or a private/internal DNS server with a custom CA? This determines if security.pki.certificates configuration is necessary.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 15 Mar 2026, 00:15 UTC
On NixOS 23.11+ the file /etc/ssl/certs/ca-certificates.crt is a symlink to the store path provided by the ca-certificates package. systemd-resolved reads this path automatically, so DoT servers are validated against the NixOS CA bundle without any extra module configuration. However, after a nixos-rebuild the symlink target can change, and systemd-resolved will only pick up the new bundle after a service restart (or a systemctl restart systemd-resolved).
Unlike DoT, DNSSEC is not enabled by default even if the unbound-anchor package is installed. The daemon requires an explicit DNSSEC=yes and a TrustAnchor directive in /etc/systemd/resolved.conf (or the corresponding NixOS module). The trust‑anchor file path can change with updates, so a declarative setting is preferable to avoid manual edits being overwritten.
In configuration.nix you can write:
services.resolved = {
enable = true;
dnsOverTls = true; # DNSOverTLS=yes
dnssec = true; # DNSSEC=yes
trustAnchor = "${pkgs.unbound-anchor}/etc/unbound/unbound-anchor"; # optional
};
After nixos-rebuild switch make sure the service is restarted to load the new CA bundle and anchor file.