1. DNS over TLS (DoT)
Anfragen zu DNS-Servern werden im Normalfall unverschlüsselt über den Port 53 (TCP | UDP) versendet. Das bedeutet: Selbst wenn ihr einen unzensierten und freien DNS-Server gewählt habt, besteht die Möglichkeit, dass jemand eure DNS-Anfragen mitliest und auswertet – DNS via Port 53 ist damit grundsätzlich anfällig für Man-in-the-Middle-Angriffe. Neue Ansätze wie DNS over TLS (DoT) oder DNS over HTTPS (DoH) sollen dies verhindern.
Für OpenWrt steht das Addon stubby zur Verfügung, mit dem alle DNS-Anfragen und -Antworten über eine TLS-gesicherte Verbindung übertragen werden, die zwischen eurem OpenWrt-Router und einem DNS-Server aufgebaut wird. Im Gegensatz zur ungesicherten Abfrage von DNS-Anfragen über den UDP-Port 53, schützt stubby unter anderem vor dem Ausspähen der DNS-Anfragen und Man-in-the-Middle-Angriffen. DoT verbessert also sowohl die Privatsphäre als auch die Sicherheit.
Im vorliegenden Beitrag möchte ich euch die Installation und Konfiguration von stubby vorstellen. Nach Abschluss des Tutorials werden eure DNS-Anfragen TLS-verschlüsselt mit einem DNS-Resolver eurer Wahl ausgetauscht.
- FRITZ!Box 4040 und Netzwerkaufbau – OpenWrt Teil1
- Flash OpenWrt auf FRITZ!Box 4040 – OpenWrt Teil2
- Hardening SSH- und LuCI-Webzugang – OpenWrt Teil3
- Keine Werbung und Tracker mit Adblock-Addon – OpenWrt Teil4
- Stubby: Verschlüsselte DNS-Anfragen – OpenWrt Teil5
- Firewall | Kontrolle ausgehender Datenverkehr – OpenWrt Teil6
- OpenWrt-Upgrade einspielen – OpenWrt Teil7
2. Stubby | DNS over TLS (DoT)
Stubby ist eine Anwendung, die nicht nur für OpenWrt verfügbar ist, sondern ebenfalls für diverse Linux-Distributionen, macOS und Windows. Die Anwendung fungiert als lokaler DNS-Resolver, der DNS-Anfragen entgegennimmt und diese stellvertretend für den Client via TLS verschlüsselt an einen DNS-Server sendet.
Technisch betrachtet läuft stubby als Daemon auf dem OpenWrt-Router und sendet eure DNS-Anfragen über eine verschlüsselte TLS-Verbindung. Passive Beobachter in einem (lokalen) Netzwerk können die von euren Clients versendeten DNS-Abfragen nicht mehr einsehen, die im Normalfall über UDP Port 53 im Klartext über die Leitung gesendet werden. Dazu nutzt stubby DNS over TLS (DoT) – standardisiert im RFC7858. Stubby unterstützt ebenfalls DNSSEC, mit dem sich DNS-Informationen kryptografisch gegen Fälschungen absichern lassen. Anhand einer eingebetteten Signatur und zweier kryptografischer Schlüssel kann stubby prüfen, ob die übermittelten DNS-Informationen unverfälscht (Integrität) und authentisch (Authentizität) sind, also vom zuständigen DNS-Server stammen. Fallen beide Prüfungen positiv aus, gilt die DNS-Antwort als vertrauenswürdig.
3. Installation
Die Installation von stubby erfolgt über das LuCI-Webinterface oder die Kommandozeile. Im Falle von stubby bevorzuge ich für die Installation und auch anschließende Konfiguration die Kommandozeile.
Der Kuketz-Blog ist spendenfinanziert!
Unabhängig. Kritisch. Informativ. Praxisnah. Verständlich.
Die Arbeit von kuketz-blog.de wird vollständig durch Spenden unserer Leserschaft finanziert. Sei Teil unserer Community und unterstütze unsere Arbeit mit einer Spende.
3.1 Benötigte Pakete installieren
Verbindet euch zunächst per SSH mit dem OpenWrt-Router. Damit ihr später ebenfalls DNSSEC nutzen könnt, muss zunächst das dnsmasq-full-Paket installiert werden. Das standardmäßig installierte dnsmasq-Paket von OpenWrt unterstützt kein DNSSEC.
Die Installation erfolgt mit folgender Befehlsverkettung:
opkg install dnsmasq-full --download-only && opkg remove dnsmasq && opkg install dnsmasq-full --cache . && rm *.ipk
Während der Installation werden modifizierte Config-Dateien nicht überschrieben, sondern die neuen Config-Dateien werden bspw. unter /etc/config/dhcp-opkg
gespeichert.
Anschließend wird noch stubby installiert:
opkg install stubby
3.2 Standardeinstellungen nach der Installation
Nach Abschluss der Konfiguration lauscht stubby auf dem Loopback-Interface (IPv4 / IPv6) unter dem Port 5453 auf Verbindungen. Standardmäßig reagiert stubby daher nur auf DNS-Anfragen vom OpenWrt-Router selbst. Weiterhin nutzt stubby die DNS-Server von Cloudflare – das möchten wir natürlich ändern, da Cloudflare aus meiner Sicht kein vertrauenswürdiger DNS-Anbieter ist.
4. Konfiguration
4.1 Integration mit dnsmasq
Zunächst möchten wir erreichen, dass DNS-Anfragen von dnsmasq an stubby gesendet werden. DNS-Anfragen, die aus dem internen Netzwerk auf dem Port 53 eingehen, müssen demnach auf den Port 5453 weitergeleitet werden – stubby lauscht auf dem Loopback-Interface des OpenWrt-Routers auf DNS-Anfragen. Ebenfalls müssen wir dafür sorgen, dass dnsmasq keine DNS-Resolver verwendet, die in der /etc/resolv.conf
hinterlegt sind:
uci add_list dhcp.@dnsmasq[-1].server='127.0.0.1#5453' uci set dhcp.@dnsmasq[-1].noresolv=1 uci commit && reload_config
4.2 DNS-Anfragen nicht an ISP-DNS übermitteln
Die Konfigurationsanpassungen unter Ziffer 4.1 stellen sicher, dass DNS-Anfragen TLS-verschlüsselt via stubby erfolgen. Bis die beiden Dienste stubby und dnsmasq in OpenWrt gestartet bzw. verfügbar sind, besteht allerdings die Gefahr, dass OpenWrt DNS-Server nutzt, die euch von eurem ISP bereitgestellt werden. Dieses kleine Leck müssen wir stopfen, indem wir Upstream-Resolver deaktivieren und OpenWrt ausschließlich die Kombination aus dnsmasq + stubby für die DNS-Auflösung verwendet:
uci set network.wan.peerdns='0' uci set network.wan.dns='127.0.0.1' uci set network.wan6.peerdns='0' uci set network.wan6.dns='0::1' uci commit && reload_config
4.3 Eigene DNS-Server hinterlegen
Standardmäßig nutzt stubby Cloudflare DNS-Server. Das solltet ihr anpassen und DNS-Server konfigurieren, die in der Empfehlungsecke genannt werden. Dazu passen wir die Konfiguration von stubby an:
nano /etc/config/stubby
Als Beispiel ergänze ich zwei DNS-Server bzw. Resolver:
config resolver option address '116.203.32.217' option tls_auth_name 'fdns1.dismail.de' list spki 'sha256/MMi3E2HZr5A5GL+badqe3tzEPCB00+OmApZqJakbqUU=' config resolver option address '46.182.19.48' option tls_auth_name 'dns2.digitalcourage.de' list spki 'sha256/v7rm6OtQQD3x/wbsdHDZjiDg+utMZvnoX3jq3Vi8tGU='
Alle weiteren Zeilen, die mit config resolver
beginnen, solltet ihr entfernen. Das bedeutet: Am Ende habt ihr nur jene DNS-Server in der Konfigurationsdatei hinterlegt, denen ihr persönlich vertraut.
Den öffentlichen SPKI-Schlüssel (list spki 'digest type/value'
) müsst ihr hin und wieder aktualisieren. Er wird bei einer DNS-Anfrage an den DNS-Server übermittelt und gegen den privaten Schlüssel des Serverzertifikats geprüft bzw. verifiziert. Die DNS-Gegenstelle wird also immer authentifiziert – sofern der stubby-Parameter tls_authentication
auf 1
gesetzt ist. Standardmäßig ist dies der Fall.
Zum Abschluss ergänzen wir die Konfiguration noch um den stubby-Parameter tls_min_version
, den wir auf (ein Minimum von) TLS 1.2 setzen:
config stubby 'global' [..] option tls_min_version '1.2'
Hinweis
Aufgrund des stubby-Parametersround_robin_upstreams '1'
werden die in der Konfiguration hinterlegten DNS-Server gleichermaßen beansprucht bzw. angefragt. Das Round-Robin-Verfahren ist ein Begriff aus der Informatik und wird unter anderem auch zur Lastverteilung verwendet.4.4 DNSSEC-Validierung via dnsmasq aktivieren
Damit dnsmasq unsere DNS-Anfragen via DNSSEC validiert, müssen wir zwei Parameter anpassen:
uci set dhcp.@dnsmasq[-1].dnssec=1 uci set dhcp.@dnsmasq[-1].dnsseccheckunsigned=1 uci commit && reload_config
4.5 Services neu starten
Nach Abschluss der Konfiguration solltet ihr die beiden Dienste stubby und dnsmasq neu starten. Das könnt ihr über das LuCI-Webinterface erledigen. Navigiert zu System -> Startup und klickt jeweils bei beiden Diensten auf den Restart-Button
.
4.6 Optional: DNS-Anfragen aus lokalem Netzwerk verbieten
Aus eigenem Interesse solltet ihr die DNS-Namensauflösung für eure Clients vom OpenWrt-Router erledigen lassen. Für Clients ist es allerdings auch möglich andere DNS-Server direkt anzusprechen und so stubby und Co. zu umgehen. Wer das verhindern möchte, der hat folgende zwei Möglichkeiten, die sich beide über Network -> Firewall -> Traffic Rules
konfigurieren lassen:
- White-List-Ansatz: Ihr erlaubt explizit, welcher Netzwerkverkehr bzw. welche Ports für eure Clients im Internet erreichbar sind. Gefolgt von einer »Block-All-Regel« am Ende der Regelkette.
- Black-List-Ansatz: Ihr verbietet euren Clients explizit den Zugriff auf Port 53 via TCP und UDP.
Der White-List-Ansatz ist in jedem Fall zu bevorzugen. In einem späteren Teil der OpenWrt-Artikelserie werde ich das Thema nochmal detailliert aufgreifen.
5. Test
Nach abgeschlossener Konfiguration gilt es zu prüfen ob das Setup funktioniert. Mit nachfolgendem Befehl prüfen wir mit einem Linux-Client innerhalb des Netzwerks zunächst, ob DNSSEC arbeitet:
dig dnssectest.sidn.nl +dnssec +multi @OpenWrt-Gateway-IP-Adresse
Der Befehl sollte eine Ausgabe wie diese zurückgeben:
; <<>> DiG 9.11.5-P4-5.1-Debian <<>> dnssectest.sidn.nl +dnssec +multi @192.168.150.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60258 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;dnssectest.sidn.nl. IN A ;; ANSWER SECTION: dnssectest.sidn.nl. 3582 IN A 213.136.9.12 dnssectest.sidn.nl. 3582 IN RRSIG A 8 3 3600 ( 20191225081058 20191125081058 42033 sidn.nl. XQ7t5u70ibaKpVEmKJLkbfU4cwbWPJup/hvZk78MCG12 Uk3WEr3p5FNKXaPiGOAj80hE/cn0xYLA4VUz37YXjR3G 7XTQZmi1nwUvB0dnFdNC3WExHNwbaqt8HyWEC+pxBRgj B1MIcdQe9u8HLwiS9sb3MQgRiMsIeTs1/Q4Db3Q= ) ;; Query time: 122 msec ;; SERVER: 192.168.150.1#53(192.168.150.1) ;; WHEN: Mo Nov 25 14:44:58 CET 2019 ;; MSG SIZE rcvd: 266
Interessant ist vor allem diese Zeile:
;; flags: qr rd ra ad
; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
Das ad-Flag signalisiert, dass dnsmasq die Antwort des DNS-Servers für authentisch hält bzw. die Validierung via DNSSEC funktioniert.
Anschließend prüfen wir noch, ob die in der stubby-Konfiguration hinterlegten DNS-Server die DNS-Anfragen beantworten: DNS Leak test.com
6. Fazit
Gerade an einem zentralen Netzwerkgerät wie einem Router macht die DNS-Namensauflösung via stubby + DNSSEC Sinn. Die dahinterliegenden Clients profitieren von einer Verbesserung der Sicherheit und der Privatsphäre. Stubby ist allerdings nicht die einzige Lösung, mit dem sich DoT realisieren lässt. Auch DNS-Resolver wie Unbound sind dazu in der Lage. Allerdings im Gegensatz zu Stubby mit kleinen Nachteilen:
[…] However at the moment Unbound does not have all the TCP/TLC features that Stubby has for example, it cannot support ‚Strict‘ mode, it cannot pad queries to hide query size and it opens a separate connection for every DNS query (Stubby will re-use connections). […]
Im nachfolgenden Teil der OpenWrt-Artikelserie werden wir uns mit der Paket-Filterung bzw. Kontrolle des ausgehenden (Client-)Datenverkehrs via Firewall-Regeln befassen.
Bildquellen:
Phone book: DinosoftLabs from www.flaticon.com is licensed by CC 3.0 BY
Wenn du über aktuelle Beiträge informiert werden möchtest, hast du verschiedene Möglichkeiten, dem Blog zu folgen:
16 Ergänzungen zu “Stubby: Verschlüsselte DNS-Anfragen – OpenWrt Teil5”
Forum oder der Chat geeignete Anlaufstellen, um dein Anliegen zu diskutieren. Per E-Mail beantworte ich grundsätzlich keine (Support-)Anfragen – dazu fehlt mir einfach die Zeit. Kuketz-ForumAbschließender Hinweis
Blog-Beiträge erheben nicht den Anspruch auf ständige Aktualität und Richtigkeit wie Lexikoneinträge (z.B. Wikipedia), sondern beziehen sich wie Zeitungsartikel auf den Informationsstand zum Zeitpunkt des Redaktionsschlusses.Kritik, Anregungen oder Korrekturvorschläge zu den Beiträgen nehme ich gerne per E-Mail entgegen.
Hallo Mike,
danke erst Mal für die Artikelserie.
Wenn ich den Befehl
dig dnssectest.sidn.nl(...)
eingebe, kommt bei mir das hier raus: -ash: dig: not found. Welche Paket fehlt mir da?Installiere das Paket knot-dig unter OpenWRT. Anstatt ‚dig‘ verwendest Du dann den Befehl ‚kdig‘. Gruß!
Nicht notwendig. Den dig-Befehl sollte man von einem Client (Linux-Maschine) innerhalb des Netzwerks absetzen.
Den dig Befehl solltest du auf einem Client – einer Linux-Maschine absetzen. Alternativ den Online-DNSSEC-Check nutzen.
Die Umsetzung ist leider gescheitert:
In Abschnitt 4.2
lieferte „uci: Invalid argument“
Der Test in Abschnitt 5. mit
dig dnssectest.sidn.nl +dnssec +multi @OpenWrt-Gateway-IP-Adresse endete in einem
Der openwrt-router befindet sich hinter einer FB7490, die direkt ans Internet angeschlossen ist. Bisher konnte ich mit dem openwrt auf das Internet zugreifen. Das geht nach Umsetzung dieses Tutorials leider nicht mehr. Ich komme auf luci, auf Teilnehmer hinter der FB7490, aber nicht mehr ins internet.
Dann habe ich versucht, stubby zu deinstallieren und neu zu installieren, weil ich dachte, ich hätte in der stubby-config einen Fehler gemacht. Wenn ich vorher nachgedacht hätte, wäre mir aufgefallen, dass ich kein Internet mehr habe und darum auch nichts mehr per ssh installieren kann.
Im Moment ist der openwrt für mich quasi tot. Hat jemand eine Idee, wie ich die kompletten Änderungen ohne Internetzugriff wieder rückgängig machen kann? Hoffentlich nicht mit dem recovery-tool zurück auf fritzOS. Nochmal den gleichen stubby-Artikel runterarbeiten, um wieder kein Internet zu haben ist keine Option.
Du musst folgende zwei Befehle rückgängig machen:
Also so:
Dann sollte es erstmal wieder funktionieren. Wo der Fehler liegt, kann ich dir allerdings nicht sagen.
Es hat sich ein kleiner Tippfehler eingeschlichen:
-> opKG install stubby
Vielen Dank für die super Anleitung.
Funtioniert alles wie beschrieben. Danke Mike für deine Mühen und das Bestreben die Online-Welt besser und sicherer zu gestalten! Und vor allem für die Klasse Tutorials und Informationen! Du leistest hier großartige Arbeit!
Der Punkt 4.6 kann aber unter Umständen nicht ausreichend sein, wenn nämlich ein Client selber DNS-over-HTTPS (DOH) benutzt, wie es z.B. beim Firefox möglich ist.
Dann geht DNS nämlich nicht mehr über Port 53 UDP sonder über Port 443 TCP.
Stimmt. Lässt sich allerdings auch nicht ohne Weiteres als Firewall-Regel in OpenWrt blocken. Wer DoH nutzt, der sollte sich dessen bewusst sein. Das ist einer der Gründe weshalb ich DoT gegenüber DoH vorziehe.
Hallo Mike!
Hier ein paar Anmerkungen und Fragen zu deiner Artikelserie zu OpenWRT von mir.
1. Adblock funktioniert nur wenn auch das Paket ‚libustream-openssl‘ installiert wurde. Diese Abhängigkeit berücksichtigt das ‚adblock‘-Paket leider nicht.
2. Die Namensauflösung für die FRITZ!Box ‚fritz.box“ funktioniert nach der Installation von Stubby nicht mehr, so dass nun mehr die korrekte IP-Adresse eingegeben werden muss. Gibt es einen Kniff um wieder ‚fritz.box‘ verwenden zu können?
Nach dem Versuch auf „fritz.box“ über den OpenWRT-Router zuzugreifen, habe ich mal das LAN meines Computers mal direkt mit dem vorgeschaltenten Router verbunden und bin promt mit einer Meldung zum „DNS-Rebind-Schutz“ abgewiesen worden. Der Zugriff funktionerte erst mit einem Neustart des vorgeschalteten Routers wieder.
3. Sollte man bei der Konfiguration der DNS-Weiterleitungen für Stubby neben 127.0.0.1#5453 nicht auch 0::1#5453 eintragen? Bei den Netzwerk-Schnittstellen wurde bei WAN6 ja ebenfalls ein eigener DNS-Server mit 0::1 eingetragen.
4. Für einige Verwirrung hat bei mir gesorgt, dass der Test mit https://dnssec.vs.uni-due.de/ bereits vor der Installation des Paketes ‚dnsmasq-full‘ erfolgreich verlief. Daher dachte ich erst, warum sollte ich das dann installieren? Im Test mit „dig …“ fehlte dann aber die „ad“ Kennzeichnung, so dass ich es dann doch installiert habe. Irgendwie verstehe ich den Unterschied dieser beiden Tests nicht so richtig.
5. Test: https://www.cloudflare.com/ssl/encrypted-sni/
Nach der Installation von ‚dnsmasq-full‘ und den beiden DNSSEC-Konfigurationseinstellungen verläuft der DNSSEC-Test des oben genannten Tests spürbar langsamer. Der „Secure DNS Test“ schlägt zudem fehl. Warum ist das so?
6. Sollte man dieser Anleitung von OpenWRT folgen?
https://openwrt.org/docs/guide-user/services/dns/intercept
(Vielleicht greife ich damit schon dem nächsten Teil der Arikelserie vor.)
LG Skynet
1. Das kann ich nicht bestätigen. Gibt es dazu Quellen, dass das Paket erforderlich ist?
3. Nein nicht unbedingt notwendig. Wir teilen dnsmasq ja mit, wo stubby läuft.
4. Der Test auf der Webseite prüft lediglich den ausgewählten bzw. in der Stubby-Konfiguration hinterlegten DNS-Server auf die Unterstützung von DNSSEC, nicht die lokale Konfiguration von dnsmasq bzw. Stubby. Ich passe das mal noch an.
6. Wieso sollte man?
zu 1. Ja unter
https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md
steht das und ohne lud Adblock auch keine Quellen bei mir.
„The package used by default is probably uclient-fetch so in order to
make adblock work with its default configuration it is needed to
install one of the libustream-* SSL libraries. Example: opkg install
libustream-openssl“
zu 3. In /etc/config/stubby befanden sich nach der Installation u.a.
zwei Zeilen:
list listen_address ‚127.0.0.1@5453‘ und
list listen_address ‚0::1@5453‘
Daher dachte ich, dass es auch ein Weiterleitung für IPv6 geben müsse.
Eine Frage wäre da noch. Sollte man nach der Konfiguration von Stubby
die Adblock Einstellung „Force Local DNS“ auf ON setzen?
zu 1.: Versuch es mal mit dem Addon bzw. Paket wget. Das hat den TLS-Support bereits integriert.
zu 3.: Stubby lauscht auf dem lokalen IPv4- und IPv6-Interface. Dnsmasq muss nur „einmal“ wissen wo stubby erreichbar ist. Daher genügt die IPv4-Information.
Nein, nicht notwendig.
Ich frage mich immer, ob sich DoT/DHO wirklich lohnt. Meine DNS-Anfrage ist unverschlüsselt, aber wo ist da das Problem? Mein ISP sieht eh, welche Seiten ich aufrufe – da hilft die beste DNS-Verschlüsselung nichts. Mit DNSSEC stelle ich sicher, dass mir keine falschen Antworten untergeschoben werden. Wo ist da also der Mehrwert?
Ich hole mir über einen DNS-Server nur noch einen Dritten rein, der potentiell mitlauschen und mitschreiben kann.
Kurzum ich sehe keinen Mehrwert zu einem Pi-Hole mit unbound und einer direketen Abfrage bei den Root-Servern.
Hi Mike
Tolle Artikelserie, danke! Nur ein kleiner Hinweis: Du schreibst
Gemäss der README des OpenWrt-Stubby-Paketes funktioniert diese Option allerdings bloss im Zusammenspiel mit OpenSSL 1.1.1+. Zumindest in den OpenWrt-18-06-Paketquellen ist OpenSSL aber noch auf dem Stand
1.0.2t
(hier bspw. für diearm_cortex-a15_neon-vfpv4
-Plattform). Sofern also kein OpenWrt-Snapshot oder RC der 19.07-Version verwendet wird, dürfte dietls_min_version
-Option also ignoriert – und der LeserIn falsche Sicherheit suggeriert – werden.Gruss
Salim