PiHole Installation & Config

Zielsetzung

Ziel soll sein, dass auf einem vorhandenen Raspberry Pi (oder ähnliches Gerät) ein installiertes PiHole mit davorgeschaltetem DNSCrypt-Proxy alle DNS-Anfragen aus dem internen Netzwerk zu einem DNS-oder-HTTPS Server verschlüsselt überträgt und dabei so viel Werbung und Trecker wie möglich direkt per DNS-Blocking filtert.

Um dies zu erreichen, muss ein bisschen konfiguriert werden, aber ich hoffe, dass diese Anleitung für jeden verständlich ist.

Voraussetzungen

  • Ein mit einem Linux Betriebssystem installierter Raspberry Pi (oder ähnliches Gerät)
    • Ich nutze hierfür Ubuntu, es kann aber auch ein anderes Linux genutzt werden
  • Der Pi muss im Netzwerk eingebunden sein und eine statische oder per DHCP zugewiesene IP-Adresse haben
    • Der Internetzugang muss funktionieren
  • Ein SSH Zugang zum Raspberry Pi muss bestehen
  • Ich habe mich absichtlich gegen eine Installation per Docker entschieden, weil dies für Laien bei Problemen eher kompliziert wird

Aufbau der Konfiguration

Um es einfach zu halten, vorab erst mal eine grafische Darstellung, wie die Zielsetzung am Ende aussehen soll:

Folgendes passiert:

  • Alle Clients bekommen vom Router eine DHCP Adresse zugewiesen, als DNS-Server wird aber nicht der Router hinterlegt, sondern der Raspberry Pi
  • Jeder Client, der eine Internetanfrage stellt, sendet seine DNS-Anfrage an den PiHole und dieser sendet diese wiederum an den DNSCrypt-Proxy. Von dort wird die Anfrage via DNS-over-HTTPS verschlüsselt ins Internet gestellt und die Antwort läut dann auf dem gleichen Weg zurück
  • Sollte der PiHole über die Sperrlisten Werbung oder Trecker blockieren, wird die Seite entweder nicht geöffnet, oder halt ohne Werbung angezeigt

Installation PiHole

Zuerst muss das Ubuntu Universe-Repository eingerichtet werden (sofern noch nicht vorhanden):

sudo add-apt-repository universe

Im Anschluss werden erst mal alle Updates auf dem Raspberry Pi installiert

sudo apt update && sudo apt upgrade

Nun folgt der Download des Installationsscripts für PiHole. Dafür wechselt man in seinen Download-Ordner:

cd /home/Benutzer/Download/

Dort führt man dann per wget den Download des Scripts aus:

wget -O basic-install.sh https://install.pi-hole.net

Sobald der Download abgeschlossen ist, kann man die Installation von PiHole starten:

sudo bash basic-install.sh
  • Hier werden nun diverse Abhängigkeiten geprüft und wenn diese passen, dann startet die Installation.
  • Es erfolgt ein Hinweis darauf, dass der Raspberry Pi eine statische IP-Adresse haben muss (ich habe oben bereits darauf hingewiesen).
  • Während der Installation wird der Upstream-DNS-Provider abgefragt. Da wir noch einiges nachkonfigurieren, kann hier einfach z.B. Cloudflare ausgewählt werden.
  • Die folgende Auswahl der Sperrlisten kann auch einfach bestätigt werden, da wir diese auch nachpflegen
  • Die Frage nach der Überwachung von IPv4 und IPv6 sollte beides aktiviert werden. Wenn z.B. IPv6 nicht genutzt wird, hat das keine Auswirkungen auf die Funktion
  • Die folgende Abfrage nach der Installation der Weboberfläche MUSS man aktivieren, da man sonst alle per Terminal konfigurieren muss und das möchte niemand ;-)
  • Auch die folgende Abfrage nach der Installation des Webservers MUSS ausgewählt werden, da sonst die Weboberfläche nicht installiert werden kann
  • Die Nachfrage ob man die Queries loggen möchte sollte man in jedem Fall aktivieren

Nun startet die Installation.

Am Ende der Installation wird das Initialkennwort des Admins angezeigt. Dieses müsst ihr unbedingt aufschreiben!
Macht ihr das nicht, müsst ihr alles deinstallieren und erneut installieren!

Da das Initialkennwort natürlich generisch ist, ändert ihr dies direkt nach der abgeschlossenen Installation per Terminal:

pihole -a -p

Einfach ein neues Kennwort vergeben und dies mit erneuter Eingabe bestätigen.

Nun könnt ihr euer PiHole per Webbrowser ansprechen:

http://IPdesPi/admin/

Nach Eingabe des eben vergebenen Kennworts öffnet sich die Benutzeroberfläche des PiHole.
Glückwunsch! Ihr habt schon einen großen Schritt gemacht :-)

DNS auf Clients einstellen

Da der PiHole nun ja für alle DNS Anfragen der Clients genutzt werden soll, muss nun im Netzwerk einiges an Konfiguration vorgenommen werden.

Da hier jedes Netzwerk unterschiedlich konfiguriert ist gebe ich nur zwei Beispiele:

  1. Fritz!Box
    1. Unter "Heimnetz -> Netzwerk -> Netzwerkeinstellungen -> IPv4-Einstellungen" legt ihr einfach die IP-Adresse des PiHole als "Lokaler DNS Server" fest
    2. Nach einem Neustart eurer Computer/Handys/weiterer Geräte, ziehen sich diese automatisch den neuen DNS Server
  2. Manuelles Festlegen
    1. Ihr könnt auch jeden Client manuell anfasst
    2. Je nach Gerät müsst ihr in den jeweiligen Netzwerkeinstellungen hinterlegen, dass die IP-Adresse des PiHole der DNS Server sein soll

Ich empfehle euch, dass ihr den DNS-Server per DHCP vergeben lasst. Dies sollte eh in jedem Heimnetzwerk Standard sein Wer ein komplexes Netzwerk zu Hause betreibt, weiß aber sicherlich die beste Option um den DNS-Server an die Clients zu verteilen ;-)

Test des PiHole

Ihr könnt das PiHole nun testen, indem ihr z.B. https:/www.bild.de aufruft. Normalerweise erkennt die Webseite sofort, dass ein Werbeblocker wie PiHole eingesetzt wird und zeigt einen entsprechenden Fehler.

Parallel könnt ihr über die Weboberfläche des PiHole über das Menü "Query Log" schauen, ob eure Anfrage an Bild.de dort aufgelistet wird. Wenn ja, dann habt ihr alles richtig gemacht.

DoH per DNSCrypt-Proxy installieren/aktivieren

Zuerst wechselt ihr wieder über das Terminal in euer Download-Verzeichnis, da ihr die Installationsdateien erst mal runterladen müsst:

cd /home/Benutzer/Download/

Nun wechselt ihr im Browser auf folgende Seite:

https://github.com/DNSCrypt/dnscrypt-proxy/releases

Hier schaut ihr, welche Version ihr für euren Raspberry Pi nutzen müsst. Ihr habe einen Raspberry Pi 4 und fahre unter Ubuntu mit dnscrypt-proxy-linux_arm-2.1.4.tar.gz sehr gut.

Nun gebt ihr im Terminal folgenden Befehl für den Download ein (bitte ggf. den Link austauschen):

wget https://github.com/DNSCrypt/dnscrypt-proxy/releases/download/2.1.4/dnscrypt-proxy-linux_arm-2.1.4.tar.gz

Als nächstes wird das heruntergeladene Archiv entpackt:

tar -xf dnscrypt-proxy-linux_arm-2.1.4.tar.gz

Im Anschluss muss das entpackte Archiv an den Bestimmungsort verschoben werden:

sudo mv linux-arm/ /opt/dnscrypt-proxy

Damit ist die eigentliche Installation abgeschlossen. Allerdings läuft der Service damit noch nicht und es gibt auch keine funktionierende Konfiguration. Also weiter gehts.

DNSCrypt-Proxy konfigurieren

Wir wechseln nun in das eben angelegt Verzeichnis:

cd /opt/dnscrypt-proxy

Dort legen wir eine Config an:

cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml

Und diese öffnen wir nun:

sudo nano dnscrypt-proxy.toml

Damit es für euch einfacher ist, werde ich euch zeigen, wie meine Config aussieht. Tragt dafür einfach die folgenden Punkte in der Config ein:

# Servernamen für die DNS Auflösung
server_names = ['nextdns', 'nextdns-ipv6', 'dns.digitalsize.net']

# Die Adressen, auf die DNSCrypt-Proxy lauschen soll (den Port könnt ihr theoretisch frei vergeben)
listen_addresses =  ['127.0.0.1:5454','[::1]:5454']

# Hier folgen nun diverse Einzeleinstellungen, die ihr bitte in der Datei sucht und entsprechend eintragt:
ipv4_servers = true
ipv6_servers = true
dnscrypt_servers = false
doh_servers = true
odoh_servers = false
require_dnssec = true
require_nolog = true
require_nofilter = true
force_tcp = false
http3 = true
lb_strategy = 'p2'
lb_estimator = true
log_level = 6
log_file = '/home/Benutzer/dnscrypt-proxy.log' (hier bitte "Benutzer" durch euren Benutzernamen im Pi austauschen)
bootstrap_resolvers = ['9.9.9.9:53', '84.200.69.80:53']
ignore_system_dns = true
netprobe_address = '9.9.9.9:53'
block_ipv6 = false

# Cache abschalten, weil dieser nicht wirklich benötigt wird
cache = false

Alternativ könnt ihr euch auch einfach meine Config hier herunterladen. Ihr müsst dann nur drauf achten, dass ihr folgende Zeile ändert:

log_file = '/home/Benutzer/dnscrypt-proxy.log'

und dort "Benutzer" mit eurem Username austauscht.

DNSCrypt-Proxy starten und testen

Wechselt nun wieder in das Verzeichnis des DNSCrpyt-Proxy:

cd /opt/dnscrypt-proxy

Dort führt ihr folgenden Befehl aus, um den Proxy zu starten:

sudo ./dnscrypt-proxy

Hier müsste nun am Ende der Ausgabe irgendwas stehen von:

dnscrypt-proxy is ready

Um nun DNSCrypt-Proxy zu testen, kann man folgenden Befehl nutzen:

dig @127.0.0.1 -p 5454 wutti.com

Das Ergebnis sollte wie folgt aussehen und als Antwort die IP "188.68.47.155" ausgeben:

; <<>> DiG 9.18.12-0Benutzer0.22.04.2-Benutzer <<>> @127.0.0.1 -p 5454 wutti.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33223
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;wutti.com.         IN  A

;; ANSWER SECTION:
wutti.com.      86400   IN  A   188.68.47.155

;; Query time: 31 msec
;; SERVER: 127.0.0.1#5454(127.0.0.1) (UDP)
;; WHEN: Sat Jul 22 16:36:23 CEST 2023
;; MSG SIZE  rcvd: 54

Wenn das soweit passt, habt ihr alles richtig gemacht. Nun richten wir DNSCrypt-Proxy noch als Dienst ein, der bei jedem Systemstart mitstartet.

Hierfür muss folgender Befehl eingegeben werden:

sudo ./dnscrypt-proxy -service install

Im Anschluss starten wir den Dienst:

sudo systemctl start dnscrypt-proxy

Um zu schauen ob der Dienst sauber läuft, einfach folgenden Befehl eingeben:

sudo systemctl status dnscrypt-proxy

Das Ergebnis sollte dann wie folgt aussehen:

dnscrypt-proxy.service - Encrypted/authenticated DNS proxy
     Loaded: loaded (/etc/systemd/system/dnscrypt-proxy.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2023-07-22 16:34:21 CEST; 5min ago
   Main PID: 175798 (dnscrypt-proxy)
      Tasks: 9 (limit: 4430)
     Memory: 5.7M
        CPU: 1.796s
     CGroup: /system.slice/dnscrypt-proxy.service
             └─175798 /opt/dnscrypt-proxy/dnscrypt-proxy -config dnscrypt-proxy.toml

Jul 22 16:34:21 Benutzer systemd[1]: Started Encrypted/authenticated DNS proxy.

Glückwunsch. Nun läuft auch DNSCrypt-Proxy.

Weiter gehts mit der Einbindung in PiHole.

DNSCrypt-Proxy in PiHole einbinden

Wechselt nun bitte auf die Webseite des PiHole und dort unter "Settings -> DNS".
Links unter den Punkt "Upstream DNS Servers" nehmt ihr alle Haken raus und tragt rechts unter "Custom 1 (IPv4)" folgendes ein:

127.0.0.1#5454

Unter "Custom 3 (IPv6)" tragt ihr folgendes ein:

::1#5454

Etwas weiter unten auf der Seite setzt ihr bitte folgende Haken:

  • Allow only local requests
  • Never forward non-FQDN A and AAAA queries
  • Never forward reverse lookups for private IP ranges

Den Haken "Use DNSSEC" dürft ihr auf keinen Fall setzen, da dies direkt durch DNSCrypt-Proxy gemacht wird.

Ihr könnt nun testen, ob NextDNS als DNS-Resover genutzt wird und ob DNSSEC funktioniert.
Über https://dnsleaktest.com/ könnt ihr per Standard-Test anzeigen lassen, ob NextDNS als DNS genutzt wird.
Über https://dnscheck.tools/ könnt ihr abfragen, ob DNSSec genutzt wird. In der Ergebnisübersicht müsste folgender Text auftauchen:

Great! Your DNS responses are authenticated with DNSSEC

Dann wisst ihr, dass ihr alle richtig gemacht habt.

PiHole Adlists hinzufügen und Gravity updaten

Damit ihr euren PiHole so richtig ausnutzen könnt, benötigt ihr noch etwas mehr als die Standard-Adlists, die vom System eh schon hinterlegt sind.

Ich habe euch unter https://wutti.com/pihole-installation-config/pihole-addlists eine Übersicht über eine Menge Listen erstellt. Diese könnt ihr entweder alle übernehmen, oder einfach die raussuchen, die für euch sinnig sind.
Beachtet bitte, dass ihr bei Nutzung aller Listen Zeit in die Pflege von Whitelists stecken müsst, da sonst viele Webseiten nicht mehr funktionieren.

Einbinden könnt ihr die Adlists über die Weboberfläche des PiHole links unter dem Menü "Adlists" und dort unter "Address:" tragt ihr eine Liste nach der anderen ein und klickt darunter auf "Add".

Wenn ihr das abgeschlossen habt, wechselt ihr im Menü links auf "Tools -> Update Gravity" und klickt dort auf "Update".

Wenn das Update läuft, dürft ihr die Seite erst mal nicht verlassen, bis diese meldet, dass das Update erfolgreich abgeschlossen wurde!

Nach Abschluss des Updates könnt ihr ins Dashboard zurück und müsstet dort dann eine Menge "Domains on Adlists" sehen.

Nun habt ihr ein konfiguriertes PiHole.

Wenn ihr noch ein bisschen basteln wollt, könnt ihr noch in eurem Router bzw. DHCP Server festlegen, dass eure Clients immer die gleiche IP-Adresse bekommen und im Menü links unter "Local DNS -> DNS Records" die Geräte mit IP-Adresse im PiHole hinterlegen, damit die Identifizierung einfacher wird.
Aber das ist wirklich optional.

PiHole updaten

Wenn unten auf der Seite des PiHole ein Update angezeigt wird, wechselt man einfach per SSH auf den Raspberry Pi und gibt folgendes im Terminal ein:

pihole -up

Damit führt PiHole alle Updates aus und installiert diese. Im Anschluss wird der PiHole-Dienst neu gestartet und alles läuft wieder.

DNSCrypt-Proxy updaten

Hier muss man leider gelegentlich mal die Seite des Projektes aufrufen und schauen, ob eine neue Version vorhanden ist. Wenn dies der Fall ist, führt man folgende Schritte aus:

# Ins Download-Verzeichnis wechseln
cd /home/Benutzer/Download/

# Release herunterladen
wget https://github.com/DNSCrypt/dnscrypt-proxy/releases/download/aktuelle Version/dnscrypt-proxy-linux_arm-aktuelle Version.tar.gz

# Datei entdecken
tar -xf dnscrypt-proxy-linux_arm-aktuelle Version.tar.gz

# Dienst stoppen
sudo systemctl stop dnscrypt-proxy

# Dateien aktualisieren
sudo mv linux-arm/ /opt/dnscrypt-proxy

# Dienst starten
sudo systemctl start dnscrypt-proxy

Über folgenden Befehl kann man nun schauen, ob DNSCrypt-Proxy wieder läuft:

sudo systemctl status dnscrypt-proxy

Wenn als Ergebnis in der Ausgabe folgendes steht:

Active: active (running)

hat das Update funktioniert.

Über

Hier soll es um Technik, Politik und meine persönliche Meinung gehen. Da ich meinen RaspberryPi mit PiHole sehr mag und daran gerne bastle, versuche ich hier auch immer Neuigkeiten darum zu teilen.

Politisch links-neutral und ich glaube fest daran, dass alle Menschen einfach nur Menschen sind.