DecaTec

Home-Server | Linux | Nextcloud | Raspberry Pi | Programmierung | Fotografie

Anonyme DNS-Kommunikation mit Pi-hole und dnscrypt-proxy

Pi-hole/dnscrypt-proxy Logo

Heute soll es mal wieder um Pi-hole gehen: Dabei handelt es sich um einen Werbe-Blocker für das gesamte Netzwerk, der nicht nur störende Werbung auf Websites herausfiltert, sondern auch einen Schutz vor Tracking und Schadsoftware ermöglicht.
Die Installation und Einrichtung von Pi-hole hatte ich ja bereits im Artikel Nie mehr Werbung – Pi-hole auf Ubuntu Server 18.04 beschrieben. Mittlerweile würde man dafür vermutlich Ubuntu 20.04 LTS nutzen, trotzdem ist genannte Artikel weiterhin aktuell. Ebenso kann Pi-hole (wie der Name ja schon vermuten lässt) auf einem Raspberry Pi installiert werden – besonders viel Leistung wird hier also nicht benötigt.

In Sachen Datenschutz und Privatsphäre ist Pi-hole schon einmal ein riesiger Schritt nach vorne. Trotzdem gibt es hier noch ein Problem: Ein verwendeter DNS-Server (Upstream-DNS) kennt immer die Quell-IP, von der die DNS-Anfrage abgesetzt wird. Daran ändert auch eine verschlüsselte DNS-Abfrage (z.B. mit DNS over TLS) nichts. Damit lassen sich trotz aller Maßnahmen Profile erstellen, die z.B. Rückschlüsse auf die Surf-Gewohnheiten ermöglichen.

Zu diesem Problem gibt es allerdings schon Lösungsansätze: Die Protokolle DNSCrypt und Oblivious DNS-over-HTTPS (eine Protokollerweiterung von DNS over HTTPS – kurz: ODoH) bieten hier Mechanismen an, um die Quell-IP bei DNS-Anfragen effektiv zu schützen. Beide Protokolle werden vom DNS-Client dnscrypt-proxy implementiert.

Der folgende Artikel zeigt, wie man dnscrypt-proxy einrichten und in Kombination mit Pi-hole verwenden kann.

Zielsetzung/Funktionsweise dnscrypt-proxy

Um die Funktionsweise von dnscrypt-proxy besser zu verstehen, schauen wir uns erst einmal (vereinfacht) eine DNS-Abfrage eines Clients über Pi-hole und die damit verbundenen Probleme an:

Vereinfachte Darstellung einer DNS-Abfrage über Pi-hole
Vereinfachte Darstellung einer DNS-Abfrage über Pi-hole

Als Upstream-DNS-Server sind hier die DNS-Server des Internet-Providers, von Quad9, Google, etc. gemeint. Diese kennen nun immer die Quell-IP der DNS-Abfrage (d.h. in den meisten Fällen die öffentliche IP-Adresse des Internet-Anschlusses) und könnten dementsprechend Profile für Clients anlegen, die dann weiter ausgewertet werden könnten (u.a. auch für Werbezwecke).

Um dies zu verhindern, benötigt man nun eine Art “Mittelsmann” – ein sog. DNS-Relay. Dies ist ein Server, der eine verschlüsselte DNS-Anfrage entgegen nimmt und an einen DNS-Resolver weiterleitet. Die Quell-IP wird dabei vom DNS-Relay nicht übermittelt. Der DNS-Resolver entschlüsselt die Anfrage und leitet diese dann an einen der Upstream-DNS-Server weiter. Das Ergebnis der DNS-Abfrage wird dann in umgekehrter Reihenfolge wieder an den Client PC übermittelt. Das folgende Bild zeigt wiederum vereinfacht den Ablauf:

Anonymisiertes DNS mit Pi-hole/dnscrypt-proxy
Anonymisiertes DNS mit Pi-hole/dnscrypt-proxy

Bis zum DNS-Relay ist die Quell-IP des Clients bekannt (blauer Bereich). Bei der Übergabe an den DNS-Resolver wird diese allerdings nicht weiter gegeben, so dass alle dahinter liegenden Systeme keine Kenntnis über die Quell-IP mehr haben (roter Bereich). Durch diese Vorgehensweise und die Verschlüsselung der DNS-Abfrage bis zum DNS-Resolver ist nun keine Partei in Kenntnis aller Informationen:

  • Der Relay-Server kennt die Quell-IP der DNS-Anfrage, aber nicht deren Inhalt (da verschlüsselt).
  • Der DNS-Resolver kennt den Inhalt der DNS-Abfrage (da dieser wieder entschlüsselt), nicht aber die Quell-IP.

Grundlage für diese Mechanismen bilden die Protokolle DNSCrypt und Oblivious DNS-over-HTTPS (ODoH). Im Rahmen von dnscrypt-proxy spricht man hierbei von anonymisiertem DNS (anonymized DNS).

Das Ziel des Artikels ist nun:

  • Installation von dnscrypt-proxy.
  • Konfiguration von dnscrypt-proxy, so dass DNSCrypt und ODoH genutzt werden.
  • Einbinden von dnscrypt-proxy in eine bestehende Pi-hole Instanz.

Installation dnscrypt-proxy

dnscrypt-proxy ist bereits in den Paketquellen aller gängigen Distributionen enthalten. Allerdings ist dies meist nur eine recht alte Version. Da die Entwicklung von dnscrypt-proxy recht schnell voran schreitet und viele sinnvolle Features erst mit neueren Versionen dazu gekommen sind, empfehle ich eine manuelle Installation des Programms.
Auf der GitHub-Release-Seite des Projekts kann die jeweils aktuelle Version ermittelt werden.

Dazu laden wir uns zunächst einmal die aktuellste Version herunter (als dieser Artikel entstanden ist, war dies die Version 2.1.1). dnscrypt-proxy gibt es für so gut wie jedes Betriebssystem/CPU-Architektur. Hier gilt es, die passende Version für den Download zu wählen (in diesem Fall “Linux x86_64”):

wget https://github.com/DNSCrypt/dnscrypt-proxy/releases/download/2.1.1/dnscrypt-proxy-linux_x86_64-2.1.1.tar.gz

Als nächstes wird dieses Archiv entpackt und in den Ordner verschoben, in dem das Programm installiert werden soll:

tar -xf dnscrypt-proxy-linux_x86_64-2.1.1.tar.gz
mv linux-x86_64/ /opt/dnscrypt-proxy

Damit ist die grundsätzliche Installation bereits abgeschlossen.

Konfiguration dnscrypt-proxy

Für die Konfiguration wechseln wir in das soeben angelegte Verzeichnis und kopieren uns die Beispiel-Konfiguration:

cd /opt/dnscrypt-proxy
cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml

Diese muss nun angepasst werden:

nano dnscrypt-proxy.toml

Die Einstellungen sind sehr umfangreich, daher ist die Konfiguration entsprechend lang. Aus diesem Grund habe ich die komplette Konfiguration in einem git-Repository auf Codeberg zur Verfügung gestellt:

DecaTec / dnscrypt-proxy-config @ Codeberg

Alle Einstellungen, die hier von den Standard-Vorgaben abweichen, habe ich dabei mit Kommentaren versehen (#DecaTec: …).


Folgende Optionen sind hier wichtig:

  • server_names = […]
    Hier werden die zu nutzenden Resolver-DNS-Server hinterlegt. Die Namen der Server sind hier nicht zufällig, sonder werden im Abschnitt [sources] definiert (s.u.).
  • listen_addresses = [‘127.0.0.1:65054’, ‘[::1]:65054’]
    Gibt an, dass dnscypt-proxy nur über die lokale IP-Adresse unter Port 65054 erreichbar ist. Besonders der Port ist hier wichtig, da dies normalerweise Port 53 ist, dieser aber schon durch Pi-hole belegt ist. Hier kann natürlich auch ein anderer freier Port genutzt werden.
  • ipv6_servers = true
    DNS-Server sollen auch über IPv6 angesprochen werden. Diese Option sollte nur aktiviert werden, wenn auch tatsächlich IPv6 genutzt wird, d.h. der Pi-hole eine IPv6 Adresse hat.
  • odoh_servers = true
    Es sollen Server genutzt werden, die das Oblivious DoH Protokoll unterstützen.
  • require_dnssec = true
    Zu nutzende DNS-Server müssen DNSSEC unterstützen.
  • lb_strategy = ‘p2’
    Es sollen nur die schnellsten zwei DNS-Server genutzt werden.
  • Sektion [sources]:
    Hier werden die DNS-Resolver und DNS-Relays definiert. Hier gibt es bereits vorgefertigte Listen, die hier direkt per Link eingebunden werden können. Wichtig ist nur, dass es jeweils eigene Resolver/Relays für DNSCrypt und ODoH gibt, daher sind die zwei getrennte Blöcke.
  • skip_incompatible = true
    Nicht kompatible DNS-Server sollen nicht genutzt werden.
  • Sektion [anonymized_dns]:
    Hier entsteht nun die “Magie” von dnscrypt-proxy. Angegeben wird hier, welche DNS-Resolver über welche DNS-Relays angesprochen werden sollen.
    Wichtig: Dieser Bereich ist standardmäßig auskommentiert und daher sind anonymisierte DNS-Anfragen nicht aktiv. Daher ist es an dieser Stelle wichtig, Routen zu konfigurieren und anzugeben.
    Der server_name stellt dabei immer den DNS-Resolver dar, unter via werden ein oder mehrere DNS-Relays angegeben.

Die auf Codeberg bereit gestellte Konfiguration ist dabei optimiert für die Nutzung von DNS-Resolvern/-Relays aus Deutschland. Diese sollten hierzulande die geringsten Antwortzeiten haben. Wer andere Server nutzen möchte, kann einen Blick auf die umfangreiche Liste des DNSCrypt-Projekts werfen (wichtig, hier sollten nur Server gewählt werden, die DNSCrypt oder ODoH unterstützen).

Bei der Definition der Routen (also der Verbindung zwischen DNS-Resolvern und -Relays) sollte man nach Möglichkeit Server wählen, die nicht vom gleichen Anbieter betrieben werden (denn dieser kennt ja “beide Seiten” und könnte in der Theorie die Anonymisierung wieder umgehen). Aus diesem Grund nutze ich hier keine Wildcards bei der Definition der Routen (was dnscrypt-proxy durchaus unterstützt).

Wer maximalen Wert auf Anonymität legt, sollte am besten Resolver und Relays aus unterschiedlichen Ländern wählen. Der Nachteil ist dann allerdings, dass die DNS-Abfragen länger dauern werden, da weit entfernte Server in der Regel größere Antwortzeiten haben.

Test der Funktion

Nach der Konfiguration kann man nun dnscypt-proxy manuell starten:

cd /opt/dnscrypt-proxy
./dnscrypt-proxy

Wie man nun an der Ausgabe erkennt, probiert das Programm sämtliche Kombinationen von DNS-Resolvern und -Relays durch, um die kürzesten Antwortzeiten zu ermitteln. Dies dauert einen Moment, aber am Ende sollten dann folgende Meldungen sichtbar sein:

[2021-11-20 13:33:00] [NOTICE] Sorted latencies:
[2021-11-20 13:33:00] [NOTICE] -    21ms dnswarden-eu-uncensor-dcv4
[2021-11-20 13:33:00] [NOTICE] -    22ms moulticast-de-ipv4
[2021-11-20 13:33:00] [NOTICE] -    23ms cs-dus3
[2021-11-20 13:33:00] [NOTICE] -    24ms odoh-cloudflare
[2021-11-20 13:33:00] [NOTICE] -    24ms sicher-surfen-de
[2021-11-20 13:33:00] [NOTICE] -    25ms dns.watch
[2021-11-20 13:33:00] [NOTICE] -    26ms cs-berlin
[2021-11-20 13:33:00] [NOTICE] -    29ms cs-de
[2021-11-20 13:33:00] [NOTICE] -    32ms dnscrypt-de-blahdns-ipv4
[2021-11-20 13:33:00] [NOTICE] -    35ms cs-dus4
[2021-11-20 13:33:00] [NOTICE] -    36ms cs-dus1
[2021-11-20 13:33:00] [NOTICE] -    40ms cs-dus2
[2021-11-20 13:33:00] [NOTICE] -    45ms odoh-koki-ams
[2021-11-20 13:33:00] [NOTICE] Server with the lowest initial latency: dnswarden-eu-uncensor-dcv4 (rtt: 21ms)
[2021-11-20 13:33:00] [NOTICE] dnscrypt-proxy is ready - live servers: 13

Nun kann man (auf der gleichen Maschine) einen ersten Test durchführen, ob die DNS-Auflösung korrekt funktioniert:

dig @127.0.0.1 -p 65054 decatec.de

Hier sollte nun die IP 85.13.128.144 ermittelt werden können.

Nach diesem ersten Test kann das Programm nun mittels STRG+C wieder beendet werden.

Einrichtung von dnscrypt-proxy als systemd-Unit

dnscrypt-proxy soll natürlich bei jedem Systemstart automatisch ausgeführt werden. Dazu liefert das Programm gleich einen “Installer” mit, den wir nun einfach ausführen können:

./dnscrypt-proxy -service install

Die systemd-Unit kann daraufhin auch gleich gestartet werden:

service dnscrypt-proxy start

Der Start dauert wieder eine kurze Zeit. Anschließend sollte aber folgender Befehl eine ähnliche Erfolgsmeldung wie schon beim manuellen Start anzeigen (s.o.):

service dnscrypt-proxy status

dnscrypt-proxy ist nun fertig konfiguriert und wird automatisch mit dem System gestartet.
Es fehlt nur noch die Einbindung in Pi-hole.

Pi-hole: Hinzufügen vondnscrypt-proxy

dnscrypt-proxy bringt erst einmal keine Funktionen zum Blocken von Werbung o.ä. mit. Zwar kann man DNS-Resolver nutzen, die ein gewisses Filtering anbieten, dennoch hat man hier keine Kontrolle darüber, welche Domains geblockt werden. Daher soll an dieser Stelle dnscrypt-proxy als Upstream-DNS-Server für unseren Pi-hole eingerichtet werden.

Dies geschieht unter Settings > DNS > Upstream DNS Servers. Hier kann man nun dnscrypt-proxy mit 127.0.0.1#65054 (IPv4) bzw. ::1#65054 (IPv6) angeben:

dnscrypt-proxy als Upstream DNS-Server (IPv4/IPv6) von Pi-hole
dnscrypt-proxy als Upstream DNS-Server (IPv4/IPv6) von Pi-hole

Links sieht man hier nun unsere dnscrypt-proxy Instanz als Upstream DNS-Server von Pi-hole (Port 65054). Auf der rechten Seite ist übrigens stubby als alternativer DNS-Upstream konfiguriert (Port 65053).

Mit einem Klick auf Save werden die Einstellungen übernommen. Nun profitiert das ganze Netzwerk sowohl vom anonymisierten DNS durch dnscrypt-proxy, als auch durch das Herausfiltern von Werbung und Tracking durch Pi-hole selbst.

dnscrypt-proxy vs. stubby

Im ursprünglichen Artikel über Pi-hole wurde stubby als Upstream-DNS für Pi-hole verwendet (siehe hier). Daher soll an dieser Stelle noch kurz auf die Unterschiede zwischen stubby und dnscrypt-proxy eingegangen werden.

stubby ist ein sog. Stub-Resolver für DNS over TLS (DoT). D.h. die DNS-Anfragen werden stets über TLS verschlüsselt. Dennoch wird hier die Quell-IP nicht gegenüber dem eigentlichen DNS-Server geheim gehalten (wie es beim anonymisierten DNS bei dnscrypt-proxy der Fall ist). Daher sollte man bei der Verwendung von stubby ein genaues Augenmerk auf die Upstream-DNS-Server werfen: Hier ist ein gewisses Vertrauen in die Betreiber der DNS-Server notwendig, dass diese nicht auf Grund von DNS-Anfragen gewisser Quell-IPs Profile erstellen, etc.

Dies ist der große Unterschied zu dnscrypt-proxy: Sobald hier anonymisiertes DNS mit Routen aus DNS-Resolvern und -Relays genutzt werden, ist das Vertrauen in den DNS-Resolver überhaupt nicht notwendig/relevant, da die eigene IP jederzeit durch die DNS-Relays “geschützt” ist. So ist es bei dnscrypt-proxy nicht bedenklich, wenn man DNS-Dienste von Google, Cloudflare oder anderen großen Konzernen(als DNS-Resolver!) nutzt, wenn diese Kommunikation durch DNS-Relays geschützt werden. Bei stubby wäre dies aus Gründen des Datenschutzes/der Privatsphäre nicht empfehlenswert.

Es spricht übrigens nichts dagegen, dnscrypt-proxy und stubby parallel in Pi-hole als Upstream-DNS-Server zu verwenden (siehe Screenshot oben). Die Praxis zeigt allerdings, dass dnscrypt-proxy etwas effizienter arbeitet: Pi-hole nutzt bei der Verwendung mehrerer Upstream-DNS-Server bevorzugt den Server, der die geringste Antwortzeit aufweist. In dem meisten Fällen ist dies dnscrypt-proxy, auch wenn bei anonymisiertem DNS immer noch ein zusätzlicher “Hop” bei den Anfragen notwendig ist. Dies kann man recht einfach in der Übersicht von Pi-hole unter Upstream servers erkennen: Deutlich mehr Anfragen werden über dnscrypt-proxy behandelt, als über stubby.

Fazit

Die Kombination von Pi-hole mit dnscrypt-proxy arbeitet nach der Optimierung der Einstellungen von dnscrypt-proxy sehr effizient und hält Werbung und Tracker aus dem Netzwerk fern. Darüber hinaus wird die Privatsphäre bei DNS-Abfragen dank anonymisierter DNS-Kommunikation über DNSCrypt bzw. ODoH optimal geschützt.

Meine beiden Pi-hole Instanzen laufen nun schon seit einiger Zeit mit dnscrypt-proxy und ich konnte bisher noch keine Probleme feststellen.

Wie schaut es bei euch aus? Nutzt ihr auch schon dnscrypt-proxy in Verbindung mit eurem Pi-hole? Wie sind eure Erfahrungen mit dieser Kombination? Hinterlasst mir dazu doch gern einen Kommentar!

Weiterführende Artikel

Links

, , , , , , , , ,

Kommentare: 9

  • Hans sagt:

    Hallo Jan,

    danke für den Artikel und die darin genannten Empfehlungen.

    Eine Frage hierzu, Wenn ich das richtig lese ist deine Empfehlung klar zu dnscrypt-proxy. Stubby kann bei einer Neuinstallation des pi-hole dann weggelassen werden?

    Danke

    Gruß Hans

    • Jan sagt:

      Hi Hans,

      dnscrypt-proxy läuft bei mir äußerst gut. stubby lasse ich noch “nebenbei” laufen, eben als weiterer DNS-Upstream von Pi-hole. Das würde ich für “Umsteiger” auch erst einmal empfehlen. Wenn dnscrypt-proxy dann zufriedenstellend läuft, kann stubby ja bei Bedarf wieder schnell entfernt werden.

      Gruß,
      Jan

  • Christian sagt:

    Hallo Jan!
    Danke für die Doku, war sehr einfach umzusetzen.
    Wenn ich den dnscrypt-proxy bei mir zuhause stehen habe, weiß doch der Resolver trotzdem, wo die Anfrage herkommt? Und er kennt den Inhalt der Abfrage. Wer weniger weiß als vorher ist der DNS UPstream Server. EIn vertrauenswürdiger DNS-Cryptserver der im Netz verfügbar ist, und von mehreren genutzt wird, wäre wahrscheinlich ne Nummer sicherer.

    • Jan sagt:

      Hi Christian,

      dnscrypt-proxy läuft bei dir zu Hause (sorgt dafür, dass du DNSCrypt und ODoH nutzen kannst), Relay- und Resolver-Server sind aber externe Server.
      Der Relay-Server kennt deine IP-Adresse, gibt diese aber nicht an den Resolver weiter. Aus Sicht des Resolvers ist die Quell-IP die des Relay-Server.
      Relay- und Resolver-Server werden ja von unzähligen Leuten genutzt, daher kann man hier wohl auch keine Rückschlüsse auf Einzelne ziehen.

      Gruß,
      Jan

  • David sagt:

    Hallo Jan,

    schön dass du diese Anleitung geschrieben hast. Neben deiner Nextcloud und Matrix Anleitung eine willkommene Ergänzung und eine wirkliche Bereicherung.

    Das Thema pihole (mittlerweile adguard home) + dnscrypt-proxy habe ich jetzt seit einigen Jahren verfolgt und selbst auf vielen kleinen raspberrypi’s umgesetzt.

    Ich würde deine Anleitung gerne mit den zusätzlichen Funktionen des Proxys erweitern, wie Anonymized DNS und Cloaking oder das Automatische Aktualisieren. Dabei kann ich auf die Besonderheiten der verschiedenen OS Versionen(x86x64 /armv7/8 / freebsd (opnsense) Bezug nehmen.

    Bei mir läuft mittlerweile adguard home, da ich GUI moderner empfinde und gefühlt alles etwas schneller geht; besonders das herunterladen der filterlisten. Interessant ist vielleicht auch die Konfiguration als DHCP Server, aber dafür nutze ich hier immer noch die FritzBox.

    Ich freue mich auf deine Rückmeldung.

    David

  • Jan sagt:

    Danke für den Artikel.

    DNSCrypt hat gleich mal mein altes System ersetzt.

    Ich finde die Umsetzung auf Dockerbasis recht praktisch da ich damit alle Server gescriptet in der Versionsverwaltung habe. Somit ist auch das Thema Sicherung des Raspi erledigt.

    Ich frage mich ob das auch noch praktikabel ist, wenn die EU auf ihrem Internetkurs fortfährt und das DNS System wie RU zentralisiert?

    AdGuard hatte ich gar nicht auf dem Schirm wirkt recht sympathisch.
    Kann mehr, zeigt weniger Schnickschnack an und wirkt sauberer umgesetzt.
    Ich bleib erstmal dabei.

    • Jan sagt:

      Hi,

      Ich frage mich ob das auch noch praktikabel ist, wenn die EU auf ihrem Internetkurs fortfährt und das DNS System wie RU zentralisiert?

      Hast du dazu vielleicht eine Quelle? Stelle mir das ganze nur schwer umsetzbar vor. Man könnte in diesem Fall ja auf Nicht-EU DNS-Server (Schweiz, UK) umsteigen.

      Gruß,
      Jan

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.