Pi-hole mit DNS over HTTPS

Anmerkung

Update Juni 2020 (Version 2): Überarbeitete Anleitung mit Umstellung auf DNSCrypt-Proxy.

Pi-Hole ist eine freie Software mit der Funktion eines Tracking- und Werbeblockers sowie eines optionalen DHCP-Servers. Bei mir ist dieser schon länger im Einsatz und sollte nun mit der Funktion von DNS over HTTPS gekoppelt werden. Hierbei werden die DNS-Anfragen über einen verschlüsselten HTTPS-Kanal gesendet, was dazu führt, das diese (theoretisch) nicht abgefangen werden können und somit auch diese anonym bleiben.

Verwendung von DNSCrypt-Proxy

Da der cloudflard ab und an Probleme bereitet hat, bin ich auf dnscrypt-proxy umgestiegen. Dort wird auch bereits eine Anleitung für das Einbinden in Pi-Hole bereitgestellt.

Neben DoH kann DNSCrypt-Proxy auch noch andere verschlüsselte DNS Protokolle wie DNSCrypt v2 und auch der Anonymized DNSCrypt. Diese werden automatisch verwendet.

Installation cloudflared

Um diese Funktion zu verwenden, nutze ich das Programm „cloudflared“ von Cloudflare. Dieses kann vorkompiliert von der Webseite des Anbieters heruntergeladen werden. In meinem Fall verwende ich einen Raspberry Pi und benötige hierfür das Paket für einen ARM und Debian.

wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.deb
sudo apt-get install ./cloudflared-stable-linux-arm.deb

Sollte die Meldung „package architecture (arm) does not match system (armhf)“ erscheinen, habe ich am Ende dieser Anleitung eine Lösung für dieses Problem beschrieben.

Einrichten des Systemdaemons

Nach der Installation müssen wir den Systemdaemon einrichten. Hierfür sind verschiedene Schritte notwendig.

Aus Sicherheitsgründen lassen wir den cloudflared unter einen eigenen Benutzer laufen. Diesen müssen wir als erstes anlegen. Dies geschieht mit folgenden Befehl:

sudo useradd -s /usr/sbin/nologin -r -M cloudflared

Als nächstes legen wir eine Konfigurationsdatei an, in der wir die Standardparameter angeben. Hier wird auch der Port definiert, auf dem der Daemon später lauscht. Da wir einen eigenen Benutzer verwenden, müssen wir einen sogenannten Higher Port verwenden (über 1024). Da DNS normalerweise den Port 53 nutzt, verwende ich hier einfach 5353. Die Konfigurationsdatei liegt unter /etc/default/cloudflared.

# Parameter für cloudflared
CLOUDFLARED_OPTS=--port 5353 --upstream https://1.1.1.1/dns-query

Im nächsten Schritt passen wir die Berechtigungen an und übereignen sowohl das Programm als auch die Konfiguration unserem vorhin angelegten Benutzer.

sudo chown cloudflared:cloudflared /etc/default/cloudflared
sudo chown cloudflared:cloudflared /usr/local/bin/cloudflared

Zum Abschluss müssen wir dafür sorgen, dass der Daemon auch gestartet wird. Dies geschieht über ein systemd-Skript. Dieses legen wir unter dem Dateinamen /etc/systemd/system/cloudflared.service an:

[Unit]
Description=cloudflared DNS over HTTPS proxy
After=syslog.target network-online.target

[Service]
Type=simple
User=cloudflared
EnvironmentFile=/etc/default/cloudflared
ExecStart=/usr/local/bin/cloudflared proxy-dns $CLOUDFLARED_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

Diesen Daemon starten wir nun und sorgen ebenfalls dafür, dass er zukünftig automatisch gestartet wird.

sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflared

Funktionstest

Ist der Daemon eingerichtet, so sollten wir die Funktion überprüfen. Dies geschieht einfach mit dem Befehl dig, welchen wir auf unseren lokalen, gerade eingerichteten cloudflared abschicken. Das Ganze sollte dann wie folgt aussehen:

dig @127.0.0.1 -p 5353 tobias-bauer.de

; <<>> DiG 9.11.5-P4-5.1-Raspbian <<>> @127.0.0.1 -p 5353 tobias-bauer.de
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9592
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1452
; PAD: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ("................................................................")
;; QUESTION SECTION:
;tobias-bauer.de.               IN      A

;; ANSWER SECTION:
tobias-bauer.de.        1639    IN      A       109.235.58.69

;; Query time: 36 msec
;; SERVER: 127.0.0.1#5354(127.0.0.1)
;; WHEN: Fri Oct 11 09:09:28 CEST 2019
;; MSG SIZE  rcvd: 143

Einbinden in Pi-hole

Als Nächstes müssen wir unseren Pi-hole Server so konfigurieren, dass er unseren Daemon verwendet. Dazu gehen wir im Webinterface in den Punkt „Settings“ und wählen dort den Reiter „DNS“ aus. Bei den Upstream-DNS-Servern entfernen wir alle Hacken.

Unter unter „Custom 1 (IPv4)“ tragen wir nun unseren Server ein. Also in unserem Fall den Wert „127.0.0.1#5353“.

Nach dem Klick auf “Save” und ggf. einem Neustart des Pi-Hole Daemons sollten die DNS-Abfragen über HTTPS laufen.

Fehler „package architecture (arm) does not match system (armhf)“ beheben

Erscheint bei der Installation der Fehler „package architecture (arm) does not match system (armhf)“, so läuft das lokale Debian unter armhf und nicht unter der reinen arm-Architektur. Dies kann ganz einfach dadurch behoben werden, dass zum System arm als Architektur hinzugefügt wird. Dies geschieht mit folgendem Befehl:

sudo dpkg --add-architecture arm

Danach sollte sich der cloudflared ohne Probleme installieren lassen.

Probleme kann es jetzt allerdings geben, wenn man ein Update mittels apt-get ausführt. Hier wird dann der Fehler angezeigt, dass die Pakete auf den Servern nicht für arm vorhanden sind. Aber auch dieses Problem kann man relativ leicht beheben, indem man einfach in den Sourcen die Architektur mit angibt.

Dazu editiert man im Verzeichnis /etc/apt/sources.list.d die Dateien und fügt dort in jede Zeile ein [arch=armhf] ein. Eine Datei schaut dann beispielsweise wie folgt aus:

deb [arch=armhf] http://archive.raspberrypi.org/debian/ buster main ui

Hat man alle Dateien abgeändert, funktioniert ein apt-get wieder ohne Probleme.

Probleme

DNSSEC-Problem

Ich hatte das Problem, dass bei mir nach einiger Zeit die Auflösung via DNSSEC nicht mehr sauber funktioniert hat. Hier gab es eine einfache Lösung. DNSCrypt-Proxy arbeitet intern mit DNSSEC. Das heißt, die Validierung ist hier sichergestellt. Die Probleme traten in der Kommunikation zweischen DNSCrypt-Proxy und Pi-Hole auf. Deaktiviert man in Pi-Hole DNSSEC funktioniert die Auflösung ohne Probleme.

Cloudflare Problem

Ich habe immer wieder, nicht nur hier, Auflösungsprobleme mit Cloudflare. Die einzige Lösung für mich war, Cloudflare zu sperren und nicht mehr zu verwenden. Das geht mit dem Proxy relativ einfach mit folgender Konfigurationseinstellung:

disabled_server_names = ['cloudflare']

Kommentare: