-
Print
-
DarkLight
-
PDF
NB: This document is retained for historical interest only as "named" and "dig" have supported TLS natively since BIND release 9.17.7.
RFC 7858 specifies DNS over TLS (Transport Layer Security). There are multiple ways to implement DoT. One implementation example, which uses nginx, is provided in the contrib directory of the BIND 9 distribution, entitled 'dnspriv'. This is documented at https://dnsprivacy.org/wiki/.
This article explains how to provide a DNS over TLS service using BIND 9 and stunnel. The setup of a privacy aggregator is at the end.
BIND 9 configuration: nothing special, but if you want to limit external insecure access to the service you can play with listen-on
clause address and port, acl
, or even a system firewall as BIND 9 provides no per-transport protocol access control.
stunnel setup for the opportunistic privacy profile:
- Create a X.509 public key certificate, for instance by:
openssl genrsa -out dns.key 1024
openssl req -new -key dns.key -out dns.crt -x509
This creates a self-signed certificate, enough for clients performing no authentication.
- Create a stunnel configuration
dnstls.conf
:
[dns]
accept = 853
connect = 127.0.0.1:53
cert = dns.crt
key = dns.key
The service_name should be dns
according to documentation. The DNS over TLS well-known port is 853
; stunnel will accept any TLS connection on this port and forward content in TCP to 127.0.0.1
(localhost) on port 53
(dns).
- Launch stunnel in daemon mode using the configuration file:
stunnel dnstls.conf
stunnel setup for the the out-of-band key-pinned privacy profile:
- You should use a real X.509 CA but for experiments you can create a CA certificate by:
openssl genrsa -out ca.key 1024
openssl req -new -key ca.key -out ca.crt -x509 -extensions v3_ca
- Create a X.509 public key certificate in a X.509 Certificate Authority, for instance the homemade CA:
openssl genrsa -out dns.key 1024
openssl req -new -key dns.key -out dns.req
openssl x509 -req -in dns.req -out dns.crt -CA ca.crt -CAkey ca.key -CAcreateserial
- Add in stunnel configuration:
CAfile = ca.crt
This makes stunnel add the CA certificate to the chain during TLS handshake (as it is supposed to do).
- Launch stunnel in daemon mode
How to test the service using getdns (https://getdnsapi.net).
-
Install (or configure and compile) getdns with the
getdns_query
tool you can find insrc/test
of the distribution. -
If you'd like to authenticate the server, the CA must be known. The simplest way to do it is:
$ export SSL_CERT_FILE=.../ca.crt
% setenv SSL_CERT_FILE .../ca.crt
If you have a shell or a c-shell filling the ... by the path where the OpenSSL library can find the CA certificate.
- For key-pinning you have to compute the sha256 pin, according to https://timtaubert.de/blog/2014/10/http-public-key-pinning-explained/. You can use from the key:
openssl rsa -in dns.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
or from the certificate:
openssl x509 -in dns.crt -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
- A typical call could be:
getdns_query -s foo.example.org a @10.1.2.3 -l L
-l L
ask for TLS transport (vs. U
for UDP or T
for TCP)
- or with key-pinning:
getdns_query -s foo.example.org a @10.1.2.3 -l L -K 'pin-sha256="KAGwR1fXzY4JJtBP1yYoAisc+4yNomT6VrFPwkMi5qE="' -m
-K
specifies a public key pin, -m
requires authentication (vs -n
for no authentication).
BIND 9 setup for a privacy aggregator uses, for instance:
options {
...
forwarders { 127.0.0.1 port 1053; };
forward only;
};
server 127.0.0.1 {
tcp-only yes;
};
...
forwarders
makes all queries to be forwarded to the designated service on another port, forward only
disables fallback to standard resolution, and the tcp-only
clause in the server
entry enforces the use of TCP transport (note this feature was added in version 9.11).
stunnel setup for a privacy aggregator is in client mode with, for instance:
[dns]
client = yes
accept = localhost:1053
connect = <server>:853
To test the privacy aggregator setup: <client_hosts> --- *:53 <named> localhost:1053 <stunnel> ---- *:853 <unbound> an unbound configuration could be:
server:
...
interface: 0.0.0.0@853
ssl-port: 853
ssl-service-key: dns.key
ssl-service-pen: dns.crt
do-udp: no