Pi-Hole – DNS-over-TLS (DoT) mit nginx

Seit Android 9 unterstützen Smartphones die eingabe von eigenen DNS-Servern. Hierbei nutzt Android aber nur DNS-over-TLS statt eine normale DNS-Abfrage oder DNS-over-HTTPS.
Auch mit dem PC lässt sich DNS-over-TLS nutzen, soweit man die Browser dazu zwingt.
Vorteile von Pi-Hole und DNS-over-TLS sind:
– Abfragen werden verschlüsselt übertragen
– Werbung wird in Android-Apps besser geblockt
– Keine weiteren Apps mehr für Verbindungsaufbau zum DNS-Anbieter ab Android 9 mehr notwendig

Unser Ziel:

DNS-Abfragen werden via DoT an unser Pi-Hole übermittelt, um Werbung effizienter zu blocken und DNS-Abfragen zu verschlüsseln.
Hierbei nutzen wir nginx als DoT-Proxy

Diese Anleitung beschreibt aber nur die Installation des DNS-over-TLS-Supports. Sie baut auf schon bisheriges auf!

Was brauchen wir?

nginx als Webserver
Eine laufende Pi-Hole-Installation
– Eine Domain (auch Sub-Domain möglich)
– Let‘s Encrypt
– Am besten eine statische IP
– Port 853
– Vollen Zugriff auf den nginx-Server

Los gehts!

1. Installiert nginx als Webserver für das Pi-Hole.
Wie das funktioniert, habe ich HIER schon einmal niedergeschrieben.

2. Legt ein neuen Ordner für die Konfiguration bei nginx an:

# mkdir /etc/nginx/streams/

3. Erstellt ein Zertifikat für eure Domain mit dem Certbot

certbot certonly -d deine.domain.de

4. Legt eine neue Konfigurationsdatei in dem gerade erstellten Ordner an:

# nano /etc/nginx/streams/dns-over-tls

5. Diese befüllen wir mit folgendem Inhalt:

upstream dns-servers {
	server    127.0.0.1:53;
	}
server {
	listen 853 ssl; # managed by Certbot
	ssl_certificate /etc/letsencrypt/live/DEINE.DOMAIN.DE/fullchain.pem; # managed by Certbot
	ssl_certificate_key /etc/letsencrypt/live/DEINE.DOMAIN.DE/privkey.pem; # managed by Certbot
	ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
	ssl_protocols        TLSv1.2 TLSv1.3;
	ssl_ciphers          HIGH:!aNULL:!MD5;

	ssl_handshake_timeout 10s;
	ssl_session_cache shared:SSL:20m;
	ssl_session_timeout 4h;
	proxy_pass dns-servers;
}

Ändert die fett markierten Werte ab.
server = Tragt hier die IP inkl. Port eures Pi-Holes ein.
Solltet ihr mehrere Pi-Holes nutzen, könnt ihr diese einfach darunter einfügen, indem ihr den Eintrag kopiert.
ssl_certificate = Tragt hier den Pfad zu den SSL-Zertifikaten ein (es reicht eigentlich, wenn ihr nur die Domain abändert, soweit ihr den Speicherort nicht geändert habt)

6. Bindet die neue Konfiguration in der nginx.conf nun ein.
Am einfachsten ganz unten hinzufügen.

nano /etc/nginx/nginx.conf
stream {
include /etc/nginx/streams/*;
}

7. Testen die Config und startet dann nginx neu

# nginx -t
# systemctl restart nginx

Es dürfte kein Fehler beim Neustarten auftreten, soweit ihr alles richtig gemacht habt.
Solltest du keine DHPARAM-Datei besitzen, kannst du diese noch schnell anlegen und an den korrekten Pfad verschieben.

# openssl dhparam -out dhparams.pem 4096
# mv dhparams.pem /etc/letsencrypt/ssl-dhparams-4096.pem
# chmod 600 /etc/letsencrypt/ssl-dhparams-4096.pem

Nun können DoT-Anfragen an euer Server senden.
Tragt hierzu z.B. bei Android in den DNS-Einstellungen eure.Doiman.de ein und drückt auf OK.
Schon laufen alle DNS-Anfragen über DoT an euer Pi-Hole!


Update – 01.10.2021

Bei Lets Encrypt sind Zertifikate ausgelaufen.
Browser haben damit kein Problem, doch Android Geräte bauen über “Privater DNS” keine Verbindung mehr auf.
Warum?
Die Zertifikatskette passt nicht mehr ganz.
Wie lösen wir das Problem?
Wir müssen die aktuellste Certbot-Version installieren und alle Zertifikate einmal neu ausstellen lassen.
Danach geht es wieder.

Hier die paar für die Variante über snap Befehle. Einfach abkopieren, abschicken und sicher sein!

# nginx -t
# apt remove certbot -y
# apt install snapd -y
# snap install core
# snap refresh core
# snap install --classic certbot
# ln -s /snap/bin/certbot /usr/bin/certbot
# apt autoremove -y
# certbot renew --preferred-chain "ISRG Root X1" --force-renewal

Wer es lieber gerne direkt mit Python mag, kann diese Befehle hier nutzen:

# nginx -t
# apt remove certbot -y
# apt install python3 python3-venv libaugeas0 -y
# python3 -m venv /opt/certbot/
# /opt/certbot/bin/pip install --upgrade pip
# /opt/certbot/bin/pip install certbot certbot-nginx
# ln -s /opt/certbot/bin/certbot /usr/bin/certbot
# apt autoremove -y
# certbot renew --preferred-chain "ISRG Root X1" --force-renewal

Eine schöne ausführliche Analyseanleitung, gibt es HIER auf englisch zu lesen.


Zu faul DoT einzurichten oder keine eigene Domain / Server im Internet?
Nutze doch einfach mein Pi-Hole inkl. DNS-over-TLS-Support!
Alle weiteren Infos zum Pi-Hole gibts HIER.
Garantiert kein Logging und keine Werbung!

18 Kommentare

  1. Hallo,
    könntest du auch noch eine Anleitung für Einrichtung von DoH DNS-over-HTTPS bereitstellen? FireFox z.B. bietet nur die Möglichkeit über DoH an (DoT wird da nicht unterstützt).

  2. Pingback:Pi-Hole – DNS über HTTPS (DoH) mit nignx - Hoerli.NET

  3. Hi Hoerli. Super Idee und Anleitung. Möchte gerate meinen Pi-Hole mit nginx für mein Handy unterwegs zugänglich machen. Mein Pi-Hole ist bereits mit DOT (mittels unbound) eingerichtet (Anleitung von fotooase und kuketz) und als dns-adresse ist der localhost mit 127.0.0.1:5353 im pi-hole als custom dns server angegeben (forward in pi-hole.conf hinterlegt). Mir ist unklar, welche server Adresse (IP) ich nun in deiner obigen nginx Konfiguration eingeben muss… Muss ich am Router Port 853 an den Raspi weiterleiten (öffnen)? Oder wie ist das mit der ip und dem Port gemeint?

    • Von Außen muss Port 853 für die DNS-Anfragen und Port 443 für das SSL-Zertifikat erreichbar sein. Port 80 noch zum erstellen des Zertifikates.
      Am Endgerät muss eine Domain eingegeben werden, mit IP-Adressen geht das nicht. (z.B. pihole.hoerli.net)
      Ich empfehle aber nicht, ein DNS-Server von Zuhause aus für die Welt zu betreiben. Kann unter Umständen und bei Falschkonfiguration ausgenutzt werden.

  4. Hallo.
    Danke für die tolle und verständliche Anleitung.

    Leider bekomme ich einen Fehler, wenn ich nginx -t eingebe:

    nginx: [emerg] unknown directive “stream” in /etc/nginx/nginx.conf:94
    nginx: configuration file /etc/nginx/nginx.conf test failed

    Mein System: Dietpi (basierend auf Buster)
    Nginx habe ich von dem “dietpi-software” Befehl aus installiert.

    Kann mir da jemand helfen?

    Vielen Dank

  5. Ich habe die Lösung des Problems schon gefunden.

    Für alle die Diet-Pi auf dem Raspi nutzen.

    Installieren Sie zusätzlich dieses Modul: libnginx-mod-stream

    sudo apt install libnginx-mod-stream

    Danach sollte der o.g. Fehler behoben sein

  6. Entschuldigen Sie, das ich so viel Kommentiere. Aber ich habe noch eine Frage:

    Nachdem nun alles installiert ist, funktioniert die Android Private DNS.
    Aber ich bekomme bei allen Seiten, ausser bei Google fehler.
    Es kann keine Seite mehr aufgerufen werden.
    Wenn ich Private DNS deaktiviere, kann ich wieder alle Seiten aufrufen.

    In meinem Router ist der Port 80, 443 und 853 geöffnet.

    • Hier gibt es mehrere Fehlerquellen, daher kann ich nur einmal Anhaltspunkte geben.
      – Ist ein gültiges SSL-Zertifikat vorhanden?
      – Sind alle Ports sauber erreichbar? (Ich rate allerdings davon ab, einen DNS-Server am privaten Internetanschluss zu betreiben. Der kann Missbraucht werden!)
      – Läuft nginx sauber?
      – Ist im Pi-Hole DNSsec aktiv? -> Wenn die Uhrzeit auf dem Pi nicht passt, werden keine DNS-Anfragen via DNSsec aufgelöst und erreicht keine Seiten mehr.

      Am besten mal in den Serverlog gucken, was dort ggf. zu erkennen ist.

  7. Danke für das Tutorial,
    aber irgendwie klappt das bei mir nicht bei allen Geräten. Am Handy (Android 12) geht das, bei meinem Tablet (Android 10) wird gesagt, das die Verbindung nicht möglich ist, dennoch kann ich alles im Internet machen. Aber ich habe auch Geräte, mit denen ich dann garnichts mehr im Internet machen kann. Woran kann das liegen? So alt sind die Geräte auch nicht (Ausser das Tablet).

    • Hi Paul!
      Ich kenne das Problem, bin aber noch nicht dahinter gestiegen.
      Mit LineageOS hab ich des öfteren das Problem, das angeblich keine Verbindung aufgebaut werden kann.
      Nutze ich aber Apps wie Nebulo & Co. und bau darüber eine DoT-Verbindung auf, funktioniert alles wunderbar.
      Mit einer normalen Samsung-Stock-ROM funktioniert alles hingegen wunderbar mit DoT.

      Ich habe mal versucht dem Smartphone via Wireshark zuzuhören und hab festgestellt, das beim Verbindungsaufbau irgendwann keine Rückantworten der Pakete mehr kommen.
      Konnte bisher im Internet noch keine Lösung oder minimum eine Erklärung dazu finden.
      Ob es ein Android-Problem oder eine falsche Konfiguration ist, kann ich nicht sagen.
      Da es aber mit Apps wunderbar funktioniert, schließe ich ein Konfigurationsproblem ehr aus.

      Hier kannst du testen, ob dein Server funktioniert: https://dnsclient.net/

  8. bei mir kommt da immer eine Fehler
    nginx: [emerg] BIO_new_file(“/etc/letsencrypt/ssl-dhparams.pem”) failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen(‘/etc/letsencrypt/ssl-dhparams.pem’,’r’) error:2006D080:BIO routines:BIO_new_file:no such file)
    nginx: configuration file /etc/nginx/nginx.conf test failed

    • Hi Sven!
      Scheinbar fehlt dir hier der dhparams-Schlüssel.
      Lass dir einfach einen mit folgendem Befehl erstellen und passe den Pfad in der nginx-Config an:
      openssl dhparam -out dhparams.pem 4096

  9. Okay hab ich gemacht der fahler ist nun weg aber es kommt kein https an was kann das liegen

    • Dein Fehler ist hierbei, das du versuchst, DNS über TLS mit Hilfe von HTTPS zu testen, was nicht funktioniert.
      Diese Anleitung beschreibt lediglich die Installation, um DNS über TLS bereitstellen zu können und diese Anfragen an ein Pi-Hole zu leiten.
      Diese Anleitung beschreibt nicht, wie man mit Hilfe von nginx auf sein Pi-Hole zugreifen kann.
      Hierfür gibt es folgende Anleitung: https://hoerli.net/pi-hole-nginx-als-webserver/

      Um die Funktionalität deines DNS-über-TLS-Servers zu testen, nutze ein System, was DoT kann, oder verwende diese Webseite zum testen: https://dnsclient.net/

  10. Ich hab die Anleitung genutzt die sie mir geschickt haben

Schreibe einen Kommentar

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

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.