Networking - DNS - Unbound - Secure DNS over TLS

Secure DNS required TLS with certificate domain validation.

Without TLS certificate domain validation your DNS can still be intercepted, monitored, or manipulated by a man-in-the-middle attacker with nothing more than a self-signed certificate.

Here is how you set it up more securely.

Here is a minimal example configuration for Unbound, /etc/unbound/unbound.conf, that uses both Quad9 and Cloudflare Resolver as the forwarding resolvers and validates their TLS certificates against the expected domain names for each service:

server:
  tls-cert-bundle: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

forward-zone:
  name: "."
  forward-tls-upstream: yes
  # Quad9.
  forward-addr: 2620:fe::fe@853#dns.quad9.net
  forward-addr: 9.9.9.9@853#dns.quad9.net
  forward-addr: 2620:fe::9@853#dns.quad9.net
  forward-addr: 149.112.112.112@853#dns.quad9.net
  # Cloudflare DNS.
  forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com
  forward-addr: 1.1.1.1@853#cloudflare-dns.com
  forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com
  forward-addr: 1.0.0.1@853#cloudflare-dns.com

IMPORTANT: The names after the # signs in the forward-addr lines are NOT comments. They are really important.

The domain names to validate the certificates against may appear as comments behind the forward-addr configuration lines at first glance.

The syntax for forward-addr is IP address of the resolver an @ sign and then the resolver’s port number followed by a # sign and then the expected TLS domain name to validate the certificate the resolver will present.

It’s important that you get these domain names right or otherwise you’ll end up with the error messages:

notice: ssl handshake failed 9.9.9.9 port 853
error: ssl handshake failed crypto error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed

Unfortunately, Unbound doesn’t produce different error messages when the certificate domain mismatch, is expired, or when the root certificate is missing or otherwise not trusted.

NOTE: The tls-cert-bundle option points to the local system’s root certificate authority bundle; including all the trusted root certificates of the operating system. You’ll get this bundle by installing the ca-certificates package in most Linux distributions.

The default location of the root certificate bundle is /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem on Fedora, and /etc/ssl/certs/ca-certificates.crt on Debian/Ubuntu. Refer to the documentation of your distribution if you can’t locate their root certificate bundle.

If you haven’t setup the tls-cert-bundle option correctly, you may end up with certificate validation errors (below) and Unbound refusing to connect to the remove resolver:

notice: ssl handshake failed 9.9.9.9 port 853
error: ssl handshake failed crypto error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed

NOTE: Unbound randomizes which DNS forwarders to use by default with no additional configuration assuming each of your configured DNS forwarders respond within 400 milliseconds.

This ensures you’re not sending all your DNS traffic to one provider; making it more difficult for any one provider to build a complete profile on your online activities and behavior.

You can configure as many DNS forwarders as you want with Unbound and it will spread your forwarding requests out among each of them automatically.


Check Logs

You should keep an eye on your logs and watch out for any certificate errors.

It may be an indication that someone is trying to intercept, monitor, or modify your DNS requests.

You can add an additional layer of protection against this by enabling DNSSEC validation.

Both IPv4 and IPv6 addresses in the above configuration example.

Unbound will figure out which protocol is available and which is faster on its own.

You can get better reliability from your DNS server by configuring more routes and more options to cover for outages or routing disruptions.