DNS-Abfragen laufen normalerweise im Klartext über UDP Port 53. Jeder der den Traffic mitlesen kann (ISP, Hotspot-Betreiber, Geheimdienst) sieht welche Domains aufgelöst werden. RFC 7858 definiert DNS over TLS (DoT): DNS-Abfragen über eine TLS-verschlüsselte TCP-Verbindung auf Port 853.
BIND9 konnte zum Zeitpunkt dieses Beitrags kein natives DoT. Die Lösung: stunnel als TLS-Wrapper vor den BIND stellen. stunnel terminiert die TLS-Verbindung auf Port 853 und leitet die entschlüsselten DNS-Pakete an BIND auf Port 53 weiter.
Stunnel-Konfiguration
Unter FreeBSD liegt die Konfiguration in /usr/local/etc/stunnel/conf.d/. Für IPv4 und IPv6 jeweils eine Sektion:
# /usr/local/etc/stunnel/conf.d/dnstls.conf
[dns4]
accept = 853
connect = 127.0.0.1:53
cert = /usr/local/etc/stunnel/ssl/dns.crt
key = /usr/local/etc/stunnel/ssl/dns.key
CAfile = /usr/local/etc/stunnel/ssl/ca.crt
[dns6]
accept = :::853
connect = ::1:53
cert = /usr/local/etc/stunnel/ssl/dns.crt
key = /usr/local/etc/stunnel/ssl/dns.key
CAfile = /usr/local/etc/stunnel/ssl/ca.crt
accept ist der Port auf dem stunnel lauscht (853 = DoT-Standard). connect ist der lokale BIND9. Das Zertifikat muss für den Hostnamen des DNS-Servers gültig sein, sonst schlägt die Validierung auf der Client-Seite fehl.
Testen
TLS-Verbindung prüfen:
openssl s_client -connect ns1.kernel-error.de:853
In der Ausgabe sollte Verify return code: 0 (ok) stehen und eine TLS-1.2- oder TLS-1.3-Verbindung angezeigt werden.
DNS-Abfrage über TLS mit getdns_query (in den FreeBSD-Ports als getdns):
getdns_query @ns1.kernel-error.de -s -a -A -l L www.kernel-error.de AAAA
Die Option -l L erzwingt TLS. Bei Erfolg kommt ein JSON-Objekt mit "status": GETDNS_RESPSTATUS_GOOD und der aufgelösten Adresse zurück. Alternativ kann man mit kdig (aus dem Paket knot-utils) testen:
kdig +tls @ns1.kernel-error.de www.kernel-error.de AAAA
Clients
Android 9+ hat DoT nativ eingebaut (Einstellungen → Netzwerk → Privates DNS). Dort den Hostnamen des eigenen DNS-Servers eintragen. Unter Linux kann systemd-resolved DoT, oder man nutzt stubby als lokalen DoT-Proxy.
Weiterentwicklung
Siehe auch: RFC 7858 – DNS over Transport Layer Security, DNS over TLS (DoT) mit BIND, Stunnel und Android 9 einrichten, DNS over TLS mit BIND, Stunnel und Android 9: Eigener DoT-Server, BIND auf FreeBSD: DoT & DoH einrichten mit Views, IP‑Trennung und Testplan für IPv4/IPv6.
Neben DoT gibt es inzwischen auch DNS over HTTPS (DoH), das DNS-Abfragen über HTTPS auf Port 443 tunnelt. DoH hat den Vorteil, dass es durch Firewalls und Proxies nicht blockiert werden kann, weil es wie normaler HTTPS-Traffic aussieht. Mein DNS-Resolver dns.kernel-error.de bietet inzwischen beides an. Fragen? Einfach melden.