DNS over TLS/HTTP(S)
Introduction
Another relatively novel feature in BIND is DNS over TLS (DoT, RFC 7858) and DNS over HTTP(S) (DoH, RFC 8484). DNS over DTLS (read: UDP, RFC 8094) and DNS over HTTP3/QUIC (DoH3/DoQ, RFC 9250) are currently not supported.
These standards provide some level of protection of traffic between a querier and a server against eavesdropping and tampering (DNSSEC does not protect against the former).
If the feature dot
(DNS over TLS) is enabled in bind__features
,
BIND will be configured to listen to incoming DNS queries over a separate
TCP port (default: 853
).
If the feature doh_https
(DNS over HTTPS) is enabled, BIND will be
configured to listen to incoming DNS queries over HTTPS. This means that
BIND will listen to the standard HTTPS port (443
) for queries on
the paths defined in bind__doh_endpoints
.
Both dot
and doh_https
setups rely on the certificates provided by
Public Key Infrastructure setup by the debops.pki role.
Since doh_https
will render the HTTPS port unusable to other roles
(notably, web servers), a separate doh_proxy
mode is also available.
In this mode, BIND will only listen to a port (see
bind__doh_proxy_port
) on the loopback interface. This can then be
used by a local webserver to forward DNS queries to the BIND server. Currently,
only debops.nginx is supported.
In addition, or separately, stats_proxy
also makes detailed statistics
available over the same proxy (using bind__stats_proxy_port
on the
loopback interface).
Note
Both doh_proxy
and stats_proxy
mean that incoming connections
will be considered to originate from the loopback address. This means that
care has to be taken to make sure that ACLs, IP matches, etc in the BIND
configuration are correct so that e.g. external views are not inadvertently
exposed over the DoH interface provided by the web proxy.
Finally, a doh_http
(DNS over HTTP, i.e. unencrypted) mode is available.
Since this mode offers no encryption, it is mostly meant for debugging and
testing.
Testing
If you want to test DNS over TLS/HTTPS/HTTP, the kdig utility
from the knot-dnsutils
Debian package can be used (the examples below
assume that the DNS server is dns.example.com
and that it has a
valid certificate, you can also use the +tls-ca=<path>
argument
to pass a valid CA certificate to kdig):
# kdig 1.0.0.127.in-addr.arpa. PTR @dns.example.com
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 18529
;; Flags: qr aa rd; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 0
;; QUESTION SECTION:
;; 1.0.0.127.in-addr.arpa. IN PTR
;; ANSWER SECTION:
1.0.0.127.in-addr.arpa. 604800 IN PTR localhost.
;; Received 63 B
;; Time 2022-08-08 20:29:17 CEST
;; From 192.168.2.1@53(UDP) in 29.3 ms
# kdig 1.0.0.127.in-addr.arpa. PTR @dns.example.com +tls
;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 50232
;; Flags: qr aa rd; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR
;; EDE: 18 (Prohibited)
<snip question and answer section>
;; Received 80 B
;; Time 2022-08-08 20:29:21 CEST
;; From 192.168.2.1@853(TCP) in 103.5 ms
$ kdig 1.0.0.127.in-addr.arpa. PTR @dns.example.com +https=dns.example.com/dns-query
;; TLS session (TLS1.3)-(ECDHE-SECP384R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
;; HTTP session (HTTP/2-POST)-(dns.example.com/dns-query)-(status: 200)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 0
;; Flags: qr aa rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR
<snip question and answer section>
;; Received 74 B
;; Time 2022-08-08 20:34:45 CEST
;; From 192.168.2.1@443(TCP) in 56.2 ms
Client support
Setting up BIND with support for DoT/DoH is, of course, just one piece of the
puzzle. Clients also need to make use of these protocols. Notable examples of
Linux clients which provides such support include systemd-resolved
(see systemd-resolved(8) and the DNSOverTLS
option in
resolved.conf(5)) which can provide network name resolution to local
clients over DoT.
Work is also under way to draft standards which would allow clients to automatically discover that a given DNS server/resolver supports protocols such as DoT/DoH/DoQ. Notable examples include DDR, which adds new records to zones indicating the protocols supported by the name server, and DNR, which define new DHCP and IPv6 Router Advertisement (RA) options for announcing the availability of encrypted DNS resolvers.
Drawbacks
As can be seen from the above kdig examples (plain DNS, DoT, DoH), there may be some extra overhead (latency) incurred by DoT/DoH compared to plain DNS (and there are other factors and tradeoffs to consider, such as "head of queue blocking", long message support, privacy, etc). The latency is, however, partially amortized by the fact that TCP connections can be kept open over a longer time period and reused for several queries.
Most of these potential drawbacks are expected to be addressed, or at least ameliorated, by new standards such as DNS over QUIC/HTTP3 (DoQ/DoH3, RFC 9250), for more details see these two articles: first, second.
Unfortunately, DoQ/DoH3 is not yet supported by BIND (or common Linux clients), but that is likely to change in the future.
Clients using external DoT/DoH servers
Another drawback with DoT/DoH is that there are clients which may make use of external DNS servers via DoT/DoH, which breaks split-view/internal DNS (i.e. situations where a local DNS server presents a different, usually more complete view, to internal clients).
One notable example of a client which, by default, ignores the system-defined resolvers, instead sending all DNS queries to predefined external DoH providers is Firefox, as explained in this blog post. Mozilla also included support for turning off this feature by using a so-called "canary domain".
In short, if the local name server returns NXDOMAIN
for the special-purpose
domain use-application-dns.net.
, Firefox will fall back to using the
system-defined resolvers.
The defaults provided by this role includes an example of blocking such
special-purpose domains using BINDs Response Policy Zone (RPZ) Rewriting
feature (see bind__blocked_domains
and its use in
bind__default_zones
and bind__default_configuration
).
This is, of course, not a perfect solution. First, it is Firefox-specific and other applications may use different mechanisms (for example, Chrome uses the system-defined DNS resolver but may auto-upgrade to DoH). Second, some clients (including malware) may offer no mechanism at all, meaning that DoT/DoH using external servers will have to be blocked using other means (such as firewall rules). That is, however, outside the scope of this role.