Pi-hole ist ein netzwerkweiter DNS-Filter, der Werbung, Tracking-Domains und unerwünschte Verbindungen bereits auf DNS-Ebene blockieren kann. Der große Vorteil: Nicht jedes Gerät braucht einen eigenen Adblocker. Stattdessen nutzen Clients im Heimnetz oder Homelab einfach Pi-hole als DNS-Server.

In dieser Anleitung wird Pi-hole auf einem Ubuntu Server installiert. Danach wird zusätzlich Unbound eingerichtet. Unbound ist ein rekursiver DNS-Resolver. Das bedeutet: Pi-hole leitet DNS-Anfragen nicht mehr an klassische Upstream-DNS-Anbieter wie Google, Cloudflare oder den Provider weiter, sondern fragt die DNS-Hierarchie selbst ab – beginnend bei den Root-Servern. Dadurch entsteht eine unabhängige, datenschutzfreundlichere DNS-Lösung im eigenen Netzwerk.


1. Voraussetzungen

Für diese Anleitung wird folgendes benötigt:

  • Ubuntu Server, zum Beispiel als VM, LXC oder physischer Mini-Server
  • feste IP-Adresse für den Server
  • Root- oder sudo-Rechte
  • Zugriff per SSH
  • Internetverbindung
  • optional: Zugriff auf den Router oder DHCP-Server

Beispiel für diese Anleitung:

TEXT
Pi-hole Server IP: 192.168.1.10
Gateway / Router: 192.168.1.1
Netzwerk:         192.168.1.0/24

Die IP-Adresse musst du natürlich an dein eigenes Netzwerk anpassen.


2. System aktualisieren

Zuerst wird das Ubuntu-System aktualisiert.

BASH
sudo apt update
sudo apt upgrade -y
sudo reboot

Nach dem Neustart erneut per SSH verbinden.

BASH
ssh benutzername@192.168.1.10

3. Feste IP-Adresse prüfen oder setzen

Ein DNS-Server sollte immer eine feste IP-Adresse haben. Wenn sich die IP-Adresse ändert, finden die Clients den DNS-Server nicht mehr.

Die aktuelle IP-Konfiguration kannst du so prüfen:

BASH
ip a
ip route

Bei Ubuntu Server wird die Netzwerkkonfiguration häufig über Netplan verwaltet.

BASH
ls /etc/netplan/

Eine typische Netplan-Datei kann zum Beispiel so bearbeitet werden:

BASH
sudo nano /etc/netplan/00-installer-config.yaml

Beispielkonfiguration:

YAML
network:
  version: 2
  ethernets:
    ens18:
      addresses:
        - 192.168.1.10/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses:
          - 1.1.1.1
          - 8.8.8.8

Wichtig: ens18 muss durch den Namen deiner Netzwerkkarte ersetzt werden. Diesen findest du mit:

BASH
ip a

Danach die Konfiguration anwenden:

BASH
sudo netplan apply

Verbindung testen:

BASH
ping -c 4 8.8.8.8
ping -c 4 google.com

4. Pi-hole installieren

Pi-hole stellt einen offiziellen One-Step-Installer bereit. Dieser kann direkt über die Shell gestartet werden.

BASH
curl -sSL https://install.pi-hole.net | bash

Hinweis: Das direkte Ausführen von Scripts aus dem Internet sollte man grundsätzlich bewusst machen. Wer es sauber prüfen möchte, kann das Script vorher herunterladen und ansehen.

Während der Installation fragt Pi-hole mehrere Optionen ab.

Empfohlene Auswahl:

TEXT
Interface:        Deine Netzwerkkarte, z.B. ens18
Static IP:        Ja
Upstream DNS:     vorerst Cloudflare, Google oder Quad9
Blocklisten:      Standardliste aktiv lassen
Webinterface:     installieren
Webserver:        installieren
Query Logging:    aktivieren
Privacy Mode:     nach Wunsch

Der Upstream-DNS wird später auf Unbound geändert.

Nach der Installation wird dir ein Admin-Passwort angezeigt. Falls du es ändern möchtest:

BASH
pihole setpassword

Das Webinterface erreichst du anschließend über:

TEXT
http://192.168.1.10/admin

5. Pi-hole im Netzwerk als DNS-Server verwenden

Damit alle Geräte im Netzwerk Pi-hole nutzen, muss der DNS-Server im Router oder DHCP-Server angepasst werden. Die Clients sollten per DHCP Pi-hole als DNS-Server erhalten.

Typische Einstellung im Router:

TEXT
Lokaler DNS-Server: 192.168.1.10

Bei einer Fritz!Box befindet sich diese Einstellung typischerweise unter:

TEXT
Heimnetz
→ Netzwerk
→ Netzwerkeinstellungen
→ IPv4-Konfiguration
→ Lokaler DNS-Server

Danach sollten Clients ihre Netzwerkverbindung trennen und neu verbinden oder einen neuen DHCP-Lease beziehen.

Auf einem Windows-Client kannst du das so erzwingen:

POWERSHELL
ipconfig /release
ipconfig /renew
ipconfig /flushdns

Prüfen kannst du den verwendeten DNS-Server mit:

POWERSHELL
nslookup google.com

Wenn alles korrekt ist, sollte als DNS-Server die IP deines Pi-hole angezeigt werden.


6. Alternative: Pi-hole als Container über Community Scripts

Wenn du Proxmox verwendest, kannst du Pi-hole alternativ auch als LXC-Container bereitstellen. Dafür gibt es die bekannten Proxmox VE Helper Scripts beziehungsweise Community Scripts. Diese stellen für viele Dienste vorbereitete LXC-Installer bereit, darunter auch Pi-hole.

Empfohlenes Vorgehen:

  1. Proxmox Weboberfläche öffnen
  2. Node auswählen
  3. Shell öffnen
  4. Auf der Community-Scripts-Seite nach Pi-hole suchen
  5. Den aktuellen Installationsbefehl kopieren
  6. Script in der Proxmox-Shell ausführen
  7. Default oder Advanced Setup wählen
  8. Container-IP fest vergeben
  9. Nach Abschluss Pi-hole-Webinterface öffnen

Wichtig: Community Scripts sind praktisch, aber nicht Teil des offiziellen Pi-hole-Projekts. Deshalb sollte man Scripts vor der Ausführung prüfen und nicht blind auf produktiven Systemen starten.


7. Was ist Unbound?

Standardmäßig arbeitet Pi-hole als DNS-Filter und leitet erlaubte Anfragen an einen Upstream-DNS-Server weiter. Das kann zum Beispiel Cloudflare, Google, Quad9, der Provider-DNS oder der Router sein.

Mit Unbound ändert sich diese Architektur.

Ohne Unbound:

TEXT
Client → Pi-hole → externer DNS-Anbieter → Internet

Mit Unbound:

TEXT
Client → Pi-hole → Unbound → Root/TLD/Authoritative DNS-Server

Unbound ist ein rekursiver DNS-Resolver. Er fragt DNS-Informationen selbstständig über die DNS-Hierarchie ab. Dadurch muss Pi-hole nicht mehr einem einzelnen externen DNS-Anbieter vertrauen.


8. Unbound installieren

Unbound wird direkt aus den Ubuntu-Paketquellen installiert.

BASH
sudo apt update
sudo apt install unbound -y

Danach wird eine eigene Konfigurationsdatei für Pi-hole erstellt.

BASH
sudo nano /etc/unbound/unbound.conf.d/pi-hole.conf

Diesen Inhalt einfügen:

TEXT
server:
    verbosity: 0

    interface: 127.0.0.1
    port: 5335

    do-ip4: yes
    do-udp: yes
    do-tcp: yes

    do-ip6: yes
    prefer-ip6: no

    harden-glue: yes
    harden-dnssec-stripped: yes

    use-caps-for-id: no

    edns-buffer-size: 1232

    prefetch: yes
    num-threads: 1

    so-rcvbuf: 1m

    private-address: 192.168.0.0/16
    private-address: 172.16.0.0/12
    private-address: 10.0.0.0/8
    private-address: 169.254.0.0/16
    private-address: fd00::/8
    private-address: fe80::/10

Datei speichern und schließen.

Danach Unbound neu starten:

BASH
sudo systemctl restart unbound
sudo systemctl enable unbound

Status prüfen:

BASH
sudo systemctl status unbound

9. Unbound testen

Jetzt wird geprüft, ob Unbound auf Port 5335 antwortet.

BASH
dig @127.0.0.1 -p 5335 google.com

Falls dig nicht vorhanden ist:

BASH
sudo apt install dnsutils -y

Ein erfolgreicher Test zeigt eine DNS-Antwort mit einer IP-Adresse.

Zusätzlich kann DNSSEC geprüft werden:

BASH
dig @127.0.0.1 -p 5335 dnssec.works

Wenn Unbound korrekt funktioniert, kann Pi-hole auf Unbound umgestellt werden.


10. Pi-hole auf Unbound umstellen

Im Pi-hole-Webinterface:

TEXT
Settings
→ DNS

Dort alle bisherigen Upstream-DNS-Server deaktivieren.

Bei Custom DNS Server eintragen:

TEXT
127.0.0.1#5335

Speichern.

Danach Pi-hole DNS neu starten:

BASH
pihole restartdns

Test über den Pi-hole selbst:

BASH
dig @127.0.0.1 google.com

Oder von einem Client:

POWERSHELL
nslookup google.com 192.168.1.10

Wenn die Antwort funktioniert, läuft die Kette:

TEXT
Client → Pi-hole → Unbound → DNS-Hierarchie

11. Eigene Blocklisten in Pi-hole hinzufügen

Pi-hole arbeitet mit Blocklisten. Diese Listen enthalten Domains, die blockiert werden sollen. Pi-hole lädt diese Listen herunter und baut daraus seine Gravity-Datenbank.

Im Webinterface:

TEXT
Adlists / Listen
→ Add a new adlist

Dort wird die URL einer Blockliste eingetragen.

Beispiel:

TEXT
https://example.com/blocklist.txt

Eine Blockliste enthält normalerweise eine Domain pro Zeile, zum Beispiel:

TEXT
ads.example.com
tracking.example.net
telemetry.example.org

Nach dem Hinzufügen muss Gravity aktualisiert werden.

Im Webinterface:

TEXT
Tools
→ Update Gravity

Oder per SSH:

BASH
pihole -g

Danach werden die neuen Listen aktiv verwendet.


12. Domains direkt über den Query Log blockieren

Der Query Log ist einer der praktischsten Bereiche in Pi-hole. Dort sieht man, welche Geräte welche Domains angefragt haben.

Im Webinterface:

TEXT
Query Log

Dort kannst du nach auffälligen Domains suchen. Wenn eine Domain erlaubt wurde, aber blockiert werden soll, kann sie direkt aus dem Query Log auf die Denylist gesetzt werden.

Typischer Ablauf:

TEXT
Query Log öffnen
→ Domain suchen
→ Aktion Block / Deny / Blacklist auswählen
→ bestätigen

Alternativ kann eine Domain auch per Shell blockiert werden.

Beispiel:

BASH
pihole deny ads.example.com

Mehrere Domains:

BASH
pihole deny ads.example.com tracker.example.net telemetry.example.org

Eine Domain wieder entfernen:

BASH
pihole deny remove ads.example.com

Wenn eine eigentlich gewünschte Seite nicht mehr funktioniert, lohnt sich immer ein Blick in den Query Log. Oft sieht man dort sofort, welche Domain blockiert wurde.


13. Eigene lokale DNS-Einträge hinzufügen

Pi-hole kann nicht nur Werbung blockieren, sondern auch lokale DNS-Namen bereitstellen. Das ist praktisch für Geräte im Heimnetz oder Homelab.

Beispiele:

TEXT
nas.home.arpa       → 192.168.1.20
proxmox.home.arpa   → 192.168.1.30
printer.home.arpa   → 192.168.1.40
switch.home.arpa    → 192.168.1.50

Im Webinterface:

TEXT
Local DNS
→ DNS Records

Dort eintragen:

TEXT
Domain:     nas.home.arpa
IP Address: 192.168.1.20

Speichern.

Danach testen:

BASH
nslookup nas.home.arpa 192.168.1.10

Oder unter Windows:

POWERSHELL
nslookup nas.home.arpa

Wenn der Client Pi-hole als DNS-Server nutzt, sollte die lokale IP-Adresse zurückgegeben werden.


14. Sinnvolle Tests nach der Einrichtung

DNS-Auflösung testen

BASH
dig @192.168.1.10 google.com

Blockierung testen

BASH
dig @192.168.1.10 doubleclick.net

Wenn die Domain blockiert wird, liefert Pi-hole je nach Blocking Mode keine normale Ziel-IP zurück.

Pi-hole Status prüfen

BASH
pihole status

DNS-Dienst neu starten

BASH
pihole restartdns

Gravity aktualisieren

BASH
pihole -g

15. Wichtige Sicherheitshinweise

Pi-hole sollte niemals offen aus dem Internet erreichbar sein. Ein öffentlich erreichbarer DNS-Resolver kann missbraucht werden.

Empfohlen:

TEXT
DNS Port 53 nur im lokalen Netzwerk erlauben
Admin-Webinterface nicht öffentlich veröffentlichen
SSH nur für Administratoren erlauben
regelmäßig Updates installieren

Falls ufw verwendet wird, können lokale Freigaben zum Beispiel so gesetzt werden:

BASH
sudo ufw allow from 192.168.1.0/24 to any port 53 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 53 proto udp
sudo ufw allow from 192.168.1.0/24 to any port 80 proto tcp
sudo ufw allow ssh
sudo ufw enable

Die Netzadresse 192.168.1.0/24 muss an dein eigenes Netzwerk angepasst werden.


Fazit

Mit Pi-hole bekommt man eine sehr praktische netzwerkweite DNS-Filterlösung. Werbung, Tracking und unerwünschte Domains können zentral blockiert werden, ohne jedes Gerät einzeln konfigurieren zu müssen.

In Kombination mit Unbound wird die Lösung noch interessanter. Pi-hole filtert die DNS-Anfragen, während Unbound die erlaubten Domains rekursiv selbst auflöst. Dadurch ist man weniger abhängig von klassischen Upstream-DNS-Anbietern und bekommt eine sehr saubere DNS-Lösung für Heimnetz, Homelab oder kleine IT-Umgebungen.

Besonders praktisch sind zusätzlich die eigenen Blocklisten, die direkte Blockierung aus dem Query Log und lokale DNS-Einträge für interne Geräte. Damit wird Pi-hole nicht nur zum Werbeblocker, sondern zu einem kleinen zentralen DNS-Werkzeug für das eigene Netzwerk.


Weiterführende Links

  • Pi-hole Dokumentation: <https://docs.pi-hole.net/>
  • Pi-hole Installation: <https://docs.pi-hole.net/main/basic-install/>
  • Pi-hole mit Unbound: <https://docs.pi-hole.net/guides/dns/unbound/>
  • Pi-hole Allowlist und Denylist: <https://docs.pi-hole.net/guides/misc/allowlist-denylist/>
  • Community Scripts für Proxmox VE: <https://community-scripts.github.io/ProxmoxVE/>