Pi-Hole – DNS über HTTPS (DoH) mit nignx

Hier ist einmal Version 1 meiner Anleitung, um die DNS-Abfragen zum Pi-Hole via HTTPS zu verschlüsseln.
Ich habe schon einmal eine Anleitung für DNS-over-TLS gemacht.
Diese Anleitung knüpft an diese an, kann aber auch komplett getrennt genutzt werden.
Diese Anleitung ist dann Sinnvoll, wenn dein DNS-Server im Internet erreichbar ist.
DoH in diesem Aufbau für Zuhause ist nicht gut, da die DNS-Abfragen ab dem Pi-Hole wieder unverschlüsselt durchs Netz wandern!

Mit DoH lassen sich all unsere DNS-Abfragen über den Port 443 schicken und gleichzeitig mit SSL verschlüsseln.

WARNUNG: Das hier ist aktuell Version 1! Es gibt ggf. noch Verbesserungsbedarf.
Es ist aktuell eine „kopiere alles ab und erfreue dich“-Anleitung. Ich erkläre nur die notwendigen Änderungen, gehe aber nicht tiefer darauf ein.

Los gehts!

Vorraussetzung:
Eine laufende Pi-Hole-Installation
nginx als Webserver
– Eine Domain die auf den Server aufgeschaltet ist
– Etwas freier Speicher auf dem Server
– Root-Rechte

Schritt 1: Installieren von Golang

Wir brauchen Golang, damit wir die neuste Version de DoH-Server erstellen können.
Ist GO bei dir schon installiert, kannst du den Schritt überspringen.
Zuerst besorgen wir uns GO.

# wget https://dl.google.com/go/go1.13.8.linux-amd64.tar.gz
# tar xvfz go1.13.8.linux-amd64.tar.gz
# mv go /usr/local/go

Wir fügen Go in unsere Umgebungsvariablen hinzu:
(Alles abkopieren und als eine Befehlszeile abschicken!)

# cat << 'EOF' >> ~/.bashrc
export GOROOT=/usr/local/go
export GOPATH=$HOME/goProjects
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

Nun noch 3 Befehle und wir sind fertig:

# mkdir ~/goProjects
# source ~/.bashrc
# go version

Schritt 2: DoH installieren

Nun installieren wir unseren DNS over HTTPS Server.

# apt install curl software-properties-common build-essential -y
# wget https://github.com/m13253/dns-over-https/archive/v2.2.1.zip
# unzip v2.2.1.zip
# cd dns-over-https-2.2.1/
# make
# make install

Wir müssen nun die Config noch Anpassen.

# nano /etc/dns-over-https/doh-server.conf

Editiere hier die Upstream-Server auf deine Wünsche. Hast du nur ein Pi-Hole, trage z.B. nur die Localhost-Adresse ein.

upstream = [
    "udp:127.0.0.1:53",
]

Nun lässt sich unser DoH-Server auch schon starten!

# systemctl restart doh-server

Schritt 3: Lets Encryp installieren und ein Zertifikat ausstellen

Wir brauchen ein gültiges Zertifikat, damit wir sichere Abfragen ohne Hindernis machen können.

# apt install certbot -y
# certbot certonly -d deine.domain.de

Schritt 4: Die nginx-Config

Hier ist eine Beispiel-Config für nginx.
Sie muss nun von dir noch etwas angepasst werden. Die FETT markierten Stellen, müssen auf jeden Fall angepasst werden.
Was muss angepasst werden?
server_name → Deine genutzte Domain eintragen
ssl_certificate + ssl_certificate_key → Pfad zu deinem Zertifikat anpassen
access_log + error_log → Pfad anpassen

# apt install nginx
# nano /etc/nginx/sites-enabled/doh</code>
Hier die Beispiel-Config:
<code>upstream dns-backend {
    server 127.0.0.1:8053;
    keepalive 30;
}
server {
    listen 80;
    listen [::]:80;

    location /.well-known/acme-challenge {
        alias /var/www/dehydrated;
    }
    root /var/www/html;

    server_name deine.domain.de;
    return 301 https://$host;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    location /.well-known/acme-challenge {
      alias /var/www/dehydrated;
    }
    ssl_certificate /etc/letsencrypt/live/deine.domain.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/deine.domain.de/privkey.pem;

    # enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # disables all weak ciphers
    ssl_ciphers 'AES128+EECDH:AES128+EDH';

    ssl_prefer_server_ciphers on;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name deine.domain.de;
    access_log /var/log/nginx/deine.domain.de-access.log;
    error_log /var/log/nginx/deine.domain.de-error.log;

    location /dns-query {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Connection "";
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_redirect off;
        proxy_set_header        X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
        proxy_pass http://dns-backend/dns-query;
    }

}

Nun noch kurz nginx testen und dann neu starten:

# nginx -t
# service nginx restart

Tipp: Wenn du das Webinterface von Internet aus erreichen möchtest, setzte eine weitre Passwortabfrage via nginx davor (zwecks Bruteforce-Schutz) und nutze ein anderen Port (z.B. 8443).
Ich würde den Admin-Bereich zur Sicherheit nicht auf die gleiche Adresse / Port legen, unter dem auch der DoH-Server erreichbar ist.

Damit sind wir fertig!
Nun kannst du mit z.B. dem Firefox testen, ob DNS-Abfragen über HTTPS möglich sind.
Wir können die Funktion auch so testen, indem wir direkt den Server mit einer Aufgabe ansteuern.
Rufe dazu einfach folgende URL auf:

https://dein-pihole.de/dns-query?name=hoerli.net&amp;type=A

Du solltest ein Ausgabe im JSON-Format erhalten.

Viel Spaß mit DoH und Pi-Hole!


Denke auch daran GO und DoH von Zeit zur Zeit zu aktualisieren.
Einfach die Pakete neu herunterladen, den GO-Ordner einfach entfernen und gegen das neue Archiv ersetzen.
DoH kann dann einfach “neu” installiert werden. Einfach drüber bügeln und den Dienst neu starten lassen.

2 Kommentare

  1. Servus,
    Ich bekomme leider beim testen, also im letzten Schritt die Fehlermeldung: SSL received a record that exceeded the maximum permissible length. (Error code: ssl_error_rx_record_too_long). Ich benutze für DoH dasselbe Zertifikat wie für DoT und DoT funktioniert ohne Probleme. Kann mir da evtl. Jemand helfen?

    • Hi!
      Vielleicht ist bei der Zertifikatsausstellen was schief gelaufen oder die Konfiguration ist falsch.
      ssl_error_rx_record_too_long deutet meist auf ein ungültiges (ggf. zum Hostname) Zertifikat hin.

Schreibe einen Kommentar

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


CAPTCHA-Bild
Bild neu laden

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