Securing Domain Name System Queries

Date: February 27 2019[n.b.]

System administration is one of my hobbies. Part of this hobby involves running servers for my own domain. I run my own authoritative Domain Name System (DNS) server, my own mail (MX) server, and this very web (WWW) server. Earlier this month, I noticed that my domain name registrar finally added DNSSEC support for my domain. "My registrar doesn't support it" is a poor excuse not to look into deploying DNSSEC but it was one I had been using for over 4 years. With that excuse vapourized, I went down a rabbit hole yielding the following article.


This section covers common internet protocols and the web's public key infrastructure. You may wish to skip to DNSSEC below.

Domain Name System (DNS)

The Domain Name System (DNS) is the protocol used by every device on the internet to turn a domain name such as into an IP address such as fe84:10ad::4a67. An IP address is only one type of record stored by DNS. An A record stores an IPv4 address and an AAAA record stores an IPv6 address. A device asking about a domain name will create a message called a query. A query specifies both the name and the type of record about which the device wants to know.

There are three entities associated with any DNS query: the client, the resolver, and the authoritative nameservers. The client is some device on the internet that creates the query and sends it to a resolver. The resolver will break the queried name into parts. The authoritative nameserver responsible for the entire name can definitively answer the query. The resolver must find this authoritative nameserver before it can send it the query.

DNS is hierarchical. Domain names are written backwards so the first part is the part after the last dot. The first part is often referred to as a top-level domain (TLD). .com and .ca are examples of top-level domains. The last part is the part before the first dot. For example, it might be www. The root nameservers are authoritative nameservers for the entire namespace. They delegate each TLD to other sets of authoritative nameservers.

An authoritative nameserver does not know about records kept by other authoritative nameservers. It may delegate part of its namespace to another authoritative nameserver. It will respond to queries about that part with directions to those other nameservers. Those other nameservers may have done the same thing. They will respond to queries about delegated parts of their namespace with directions to yet other nameservers.

The resolver will start out knowing only about the root nameservers. It will send the query to those nameservers. The root nameservers will respond with directions to the nameservers for the TLD. The resolver will send the query to those nameservers. Those nameservers will respond with directions to the next set of nameservers. The resolver will recursively follow this process. It will stop when it finds the nameserver responsible for the entire name. This is why resolvers are sometimes referred to as recursive nameservers.

DNS normally runs over User Datagram Protocol (UDP). One property of UDP is that it does not keep state about connections. The client sends out a query and hopes it gets a response back. The same holds for connections between recursive nameservers and authoritative nameservers.

Transport Layer Security (TLS)

Transport Layer Security (TLS) provides an encrypted transport layer between two endpoints on the internet. The endpoint which initiates the connection is the client. The endpoint which accepts incoming connections is the server. TLS needs a stateful connection so it can only run over Transmission Control Protocol (TCP). TCP always processes messages in the order they were sent even if they were received out of order.

Once the server establishes a TCP connection with the client, it will present a certificate that proves its identity. It is crucial that the client validate the server certificate. It is the only way to ensure that the client is not talking to an eavesdropper. The client may prove its identity to the server with its own certificate. The server and client use the certificate(s) to negotiate a symmetric key. The server and client then use that key for encrypting and decrypting the rest of the connection.

Hypertext Transfer Protocol (HTTP)

Hypertext Transfer Protocol (HTTP) is also known as the web. It is the most widely deployed and used application layer protocol on the internet. Hypertext Transfer Protocol Secure (HTTPS) refers to HTTP when secured by TLS. Clients use different ports to distinguish between plaintext HTTP and secured HTTPS. Online banking and eCommerce would not exist as we know them today without TLS and HTTPS.

Certificate Authority (CA)

A chain of trust validates TLS certificates. If Alice trusts Bob and Bob trusts Charles, then Alice trusts Charles. This works based on a transitive property of trust but it presents a chicken and egg problem. If Alice does not trust anyone, then there is no one for her to rely on in determining whom to trust. Root certificate authorities (CAs) solve this chicken and egg problem. Operating System and Browser vendors determine an initial set of trustworthy entities. Those trustworthy entities form the root of the chain. Only CAs transitively transfer trust. A random server certificate that a CA trusts does not make a certificate trusted by signing it. An intermediary CA is a CA which is not a root CA but which a root CA or other intermediary CA trusts.

Secure Shell (SSH)

Secure shell (SSH) provides secure remote access to other computers. Most commonly, it is used to interact with a commandline shell running on the remote system. It can do many other things too. It can forward GUI programs from the remote system to a local screen. It can create a tunnel to allow internet traffic to proxy via the remote system. The secure tunnel portion of the protocol is very much like TLS. SSH keys differ from TLS certificates but both serve the same function. SSH keys are generally not signed.

DNSSEC (Domain Name System Security Extensions)

DNSSEC does not provide for end-to-end encryption of DNS queries. The design of DNS makes this an impossible feat. There are messages between a client and a resolver. There are messages between a resolver and multiple authoritative nameservers. DNSSEC focuses on responses from the authoritative nameservers to the resolver. I will come back to the messages between a client and a resolver later.

DNS records are effectively public. DNSSEC reflects this in its design. The principle is quite simple: each authoritative nameserver signs its records. Anyone can ask for them so there is no need to keep them secret. It sends a signature along with every response to a resolver. The resolver then has to validate each signature. This validation is where DNSSEC gets complicated.

The resolver gets the public, zone-signing key (ZSK) from the same authoritative nameserver as the signature. It uses the zone-signing key to validate the signature. The resolver then needs to validate the zone-signing key. The owner of the domain signs the zone-signing key with a separate key-signing key (KSK) and gives that key to the owner of the namespace a level up.

The owner of the namespace a level up places it in a record on their own authoritative nameserver. That authoritative nameserver signs that record with its own zone-signing key. The owner of the namespace a level up signs that zone-signing key with their own key-signing key. The owner of the namespace a level up gives their key-signing key to the owner of the namespace two levels up.

These keys signing keys form a chain of trust. Key-signing keys sign zone-signing keys at each level. Zone-signing keys sign key-signing keys for each level below them. The root of this chain of trust are the zone-signing keys that sign the root nameservers' records. The resolver trusts these keys and anything signed by keys that it trusts. It can validate each record it receives through the transitive property of trust.

The resolver started by asking for nameserver records in the first place. It can ask for a nameserver and that nameserver's key-signing keys in one go. The resolver can then ask for a bunch of records all at once from that nameserver. Of course, it wants the record it is actually looking up. It will want that record's signature from the ZSK, the ZSK itself, and the ZSK's signature from the KSK as well. The resolver can authenticate signed records with DNSSEC without making additional queries.

DNS-based Authentication of Named Entities (DANE)

Existing DNS naming schemes provide for mapping of TCP and UDP ports on an existing name. DNS-based Authentication of Named Entities (DANE) uses this naming scheme to identify a server by domain name, port, and transport protocol (TCP or UDP). Domain operators can use these names to store certificates in DNS. For TLS certificates, they use TLSA records. A client can validate a TLS certificate using DANE by looking up a TLSA record with this naming scheme.

If DNSSEC protects the TLSA record, then the client knows that it was not modified in transit. DNSSEC also chains the certificate to a chain of trust. The record's integrity is more important to clients than the DNSSEC chain of trust. DNSSEC is the only way to ensure the record's integrity. A trusted CA can chain a certificate to a chain of trust as well as DNSSEC can.

A TLSA record may contain either a CA certificate or an end certificate. If it is a CA certificate, then the client should validate that it signed the server certificate. If it is an end certificate, then the client should ensure it matches exactly. A TLSA record may specify that the client should also validate it using root CAs that the client trusts. This validation is particularly important for TLSA records that contain a CA certificate. If that CA becomes untrustworthy, it may issue certificates to attackers. This validation prevents clients who see those TLSA records from trusting those certificates.

Other Record Types

Two other record types benefit greatly from DNSSEC:

DNS over TLS (DoT)

Here I return to end-to-end encryption of DNS queries. It is possible to encrypt the connection between the client and the resolver. It is possible to encrypt connections between the resolver and authoritative nameservers. End-to-end encryption of these two links is the best we can do without changing DNS itself.

TLS has a hidden dependency on DNS. Clients typically identify a server by domain name. They validate the server certificate against that domain name. A client identifies DNS resolver by IP address. If it was identified by a domain name, then a DNS resolver would be necessary to resolve the DNS resolver. One simple solution is to configure a domain name beside the already configured IP address.

The client can use the domain name to validate the DNS resolver's server certificate. The client cannot use the chain of trust established by DNSSEC. To do that, the client would need to already trust the DNS resolver. The client should trust root CAs provided by its operating system. The client must use these root CAs to validate a DNS resolver's server certificate.

The resolver does not know which root CAs the client trusts. The resolver most likely has its own, separate list of trusted root CAs. So the resolver cannot use its list of trusted root CAs to validate an authoritative nameserver's certificate but it can use DNSSEC and DANE. This presents no problem if the client also trusts the DNSSEC chain of trust.

DNS over HTTPS (DoH)

DNS over HTTPS would be better described as DNS over HTTP over TLS. The client configuration needs an IP address and a domain name just like DNS over TLS. The client uses them for the same purpose as in DNS over TLS. The client maps DNS queries to HTTP requests with a configured URI template. The HTTP responses come back with a special MIME type that the client maps back to DNS responses. DNS query and response semantics do map well to HTTP request and response semantics. But, the supposed benefits of HTTP are not worth the additional complexity.

DNS over HTTPS is difficult to extend from resolver to authoritative nameserver. The first hurdle is that each domain operator must operate an HTTP server. They would need to configure the it with a TLS certificate. The resolver would act as an HTTPS client. The operator would have to continue operating a DNS server too. Authoritative responses would be available through plain DNS or through DNS over HTTPS.

DANE is not typically used by HTTPS clients for certificate validation. This raises the issue of which root CAs to use to validate the server certificate. The client may trust it while the resolver does not. The resolver may trust it while the client does not. This presents no problem if the resolver can validate the records with DNSSEC. But, DANE is the right answer if the resolver is using DNSSEC for record validation anyways.

Deploying DoT or DoH on your client

Information about the protocols and their security is useless if you cannot use it to secure your own devices. DNS over TLS and DNS over HTTPS are recent standards. Implementation in operating systems and browsers is on-going. Here are some options for securing DNS queries between your devices and your DNS resolver for now:


Stubby is a local DNS forwarder. It runs as a service on your device that forwards DNS queries to a configured DNS resolver with DNS over TLS. It acts as a client for the configured DNS resolver and a resolver for applications on your device. Connections between applications and Stubby never leave your device. These connections are as secure as your device.

Stubby documentation includes installation and configuration instructions. You will need to choose a public DNS resolver. I list resolvers with DNS over TLS and DNS over HTTPS support below.

Firefox support for DNS over HTTPS

Firefox has DNS over HTTPS support but it is not yet available through the normal settings menu. For now, you can control DNS over HTTPS through the network.trr.mode setting in about:config. A setting of 2 will prefer DoH and use insecure DNS as a fallback. Temporary docs for what the different values of network.trr.mode do.

It is not enough to turn on DoH, you need to configure a resolver too! Mozilla preloads network.trr.uri with the URI template for Cloudflare DNS. You can replace that URI template with another. I list URI templates for other public DNS resolvers below.

Trusting Your Resolver

As a client, DNS needs you to trust your resolver. The resolver is the entity that performs DNSSEC validation. When that fails, a client will receive a failure response from the resolver. A client cannot distinguish between a failure response due to a DNSSEC failure and other types of failures. A resolver might not be able to reach any authoritative nameserver for that domain. It would send a similar failure response for that scenario too.

Some resolvers are not trustworthy. They might respond to clients with the IP address of an ad server when a domain does not exist. Many Internet Service Providers (ISP) do this. Customers often use their ISP's DNS resolver by default. When the customer navigates to a non-existent domain in their web browser, they will see an ad server. The ad revenue goes to their ISP. Up until 2014, OpenDNS did this too.

Public DNS Resolvers

A public DNS resolver is one alternative to an ISP's resolver. Many organizations run public DNS resolvers:

Running Your Own Resolver

If you trust neither your ISP's resolver nor a public DNS resolver then you can run your own. This has serious privacy implications. The authoritative nameservers can associate requests to resolvers by IP address. If you are using your ISP's resolver, your requests are mixed in with the ISP's other customers. If you are using a public DNS resolver, your requests are mixed in with other members of the public. If you are running your own resolver, your requests do not get mixed in with the requests of anyone else.

The trade-off for privacy at the authoritative nameserver level is privacy at the resolver level. If you are using your ISP's resolver, your ISP will know every request you make. If you are using a public resolver, its operator will know every request you make. If you use your own resolver, you distribute this data around these requests among the authoritative nameservers that your resolver queries.

The domain owner chooses who operates the authoritative nameserver. The domain registrar will usually provide this service by default. GoDaddy has inexplicably been the largest domain registrar for over a decade. There are plenty of reasonable objections to giving your DNS query data to Google, Cloudflare, or Quad9. Those objections should apply even more strongly to a company like GoDaddy. As recently as January 2019, GoDaddy was potentially breaking its customers website by injecting JavaScript.

Those who host a web server on their domain often use cloud service providers. The cloud service providers offer their own authoritative nameserver services. Some of them allow registration of a domain through them. Google, Amazon, and Microsoft all allow you to register a domain with them and use their authoritative nameservers. Other companies, like Cloudflare and DNSimple, provide authoritative nameservers as part of their internet infrastructure offerings.

June 20 2019: n.b. The date at the top is the original "publication" date. It is around the time I originally wrote this article. I intended to add an additional section on attacks against DNS over TLS plus DNSSEC but never did. I may make it the subject of a future post.