Encrypting DNS traffic on Linux with DoT
Curious Looks
DNS over HTTPS (DoH) is an established, practical method of Domain Name System (DNS) encryption [1]. The standard, which dates back to 2018, encrypts DNS traffic within the HTTPS protocol, which means DNS traffic uses the same network port (tcp/443) as HTTPS. As a result, administrators initially have no way of distinguishing between DNS and HTTPS traffic. The standard is now supported by most web browsers, as well as Windows 11, and a number of public DNS servers also speak this protocol [2].
DNS over TLS (DoT) was standardized two years earlier in RFC 7858 [3]. As the name suggests, the DNS traffic is encrypted directly above the User Datagram Protocol (UDP), without needing another protocol in the application layer, making it easier for DNS providers to support this standard because they don't have to implement the fairly complex HTTP protocol on the DNS server. However, as with HTTPS, a public key infrastructure (PKI) is required; the DNS server must offer an X.509 certificate as soon as a client establishes a connection with DoT to any server supporting the standard.
DoT uses a dedicated network port (tcp/853) so that, unlike DoH, it is possible for administrators to identify DNS traffic on the network and filter it, if necessary.
Querying a Recursive DNS Server
The DNS dig
utility makes it easy to formulate a manual query to a recursive DNS server. The server then takes care of providing a response by sending the query to the DNS server ultimately responsible for the domain in question, starting with the DNS root servers. To safeguard the request with TLS, you can use the +tls-ca
option when calling dig
. In the example here, I used the public DNS server (1.1.1.1) operated by provider Cloudflare [4]. In addition to regular DNS on port 53, it also supports the DoH and DoT protocols. For example, the DNS query for it-administrator.de
resolves to 88.198.228.86. The additional information also shows that the request was made over a TLS channel.
Subject Alternative Name
You also need to use the +tls-ca
option to ensure that the DNS server's hostname matches the Subject Alternative Name in the server's X.509 certificate. This arrangement protects you against adversary-in-the-middle (AITM) attacks. If the hostname is not identical, the TLS handshake fails. You can easily simulate this case by using the +tls-hostname
option in the dig
-based DNS query and quoting a hostname that matches the DNS server's hostname.
To verify the certificate chain, dig
either accesses the certificate file in the PEM format you specified in the command with the +tls-ca
option or, if you have not specified a file, via your system's standard certificate store. You can easily find out where this is if you run openssl
as:
openssl version -d OPENSSLDIR: "/etc/pki/tls"
On a Fedora system, this directory contains a cert.pem
file that, in turn, contains a number of root CA certificates for validating X.509 certificates. In this case, a call with the +tls-ca
option is identical to +tls-ca=/etc/pki/tls/cert.pem
. If dig
is unable to validate the certificate because of missing root CA certificates, the query again fails in this case:
dig @1.1.1.1 +tls-ca=/dev/null it-administrator.de ;; TLS context cannot be created
The kdig
tool from the knot-utils
package belonging to the Knot DNS server [5] also lets you display the DNS server's certificate chain in full, which can be helpful for troubleshooting if you are having problems with the TLS handshake. Figure 1 shows how to call up the tool in debug mode.
Setting Up a Local Resolver
To give the applications on your system the ability to send DNS queries to a recursive DNS server with DoT, you can use a local resolver that supports this standard; I am using systemd-resolved
here. Figure 2 shows an example of how to configure systemd-resolved
on a specific interface for DoT. Don't forget to specify the DNS server in the <IP>#<Server-Name>
format, because it enables the TLS Server Name Indication (SNI) extension to validate the DNS server's X.509 certificate. However, if the DNS server does not support DoT, all queries fail. In this case, you can use "opportunistic" DoT mode, but systemd-resolved
will not be able to verify the server's authenticity – giving you protection against passive eavesdroppers on the network but not active attackers who manipulate the DNS traffic.
Buy this article as PDF
(incl. VAT)