Freorit

Open Source & Security Practitioner
DNS Privacy Raspberry Pi Linux ca. 20 Min. Lesedauer Mittlere Schwierigkeit Stand: 2025

Pi-hole + Unbound: DNS ohne externen Mittelsmann

Werbung blocken ist gut. Aber selbst mit Pi-hole sehen externe DNS-Anbieter jeden Domainnamen, den Ihr Netzwerk auflöst. Dieser Guide zeigt, wie Unbound als rekursiver Resolver diesen letzten Datentransfer eliminiert — und warum sich das nicht nur für das Homelab lohnt.

Das DNS-Privacy-Problem

Jedes Mal, wenn ein Gerät in Ihrem Netzwerk eine Website aufruft, fragt es zuerst einen DNS-Server: "Welche IP-Adresse hat diese Domain?" Diese Anfragen verraten mehr als es auf den ersten Blick scheint.

Selbst ohne den eigentlichen Seiteninhalt zu kennen, entsteht aus DNS-Logs ein detailliertes Profil: welche Dienste genutzt werden, zu welchen Zeiten, wie häufig. Das betrifft Privatpersonen — und Unternehmen noch mehr.

Relevant für kleine Unternehmen und Selbstständige

Wer seinen DNS-Verkehr über externe Resolver wie 8.8.8.8 (Google), 9.9.9.9 (Quad9) oder 1.1.1.1 (Cloudflare) laufen lässt, gibt diesen Drittanbietern Einblick in alle aufgerufenen Domains — inklusive interner Dienste, Cloud-Anbieter, Partner-APIs und geschaeftlicher Recherchen. Ein Raspberry Pi 4 kostet rund 70 Euro und reicht als DNS-Server für kleine Netzwerke bis zu etwa 50 Geräten problemlos aus. Die Investition ist überschaubar, der Datenschutzgewinn erheblich.

Die häufig empfohlene Lösung — Pi-hole — löst einen Teil des Problems, nicht das Ganze.

Pi-hole allein: gut, aber nicht vollständig

Pi-hole ist ein DNS-Filter: Es empfängt alle DNS-Anfragen aus dem Netzwerk und blockiert bekannte Werbe- und Tracking-Domains, bevor eine Verbindung zustande kommt. Das ist wirksam und empfehlenswert.

Pi-hole löst DNS-Anfragen selbst aber nicht auf. Es leitet nicht blockierte Anfragen an einen konfigurierten Upstream-Resolver weiter — zum Beispiel Quad9 oder Cloudflare. Dieser externe Resolver sieht dann alle Anfragen, die Pi-hole durchlässt.

Hinweis: nicht 8.8.8.8 verwenden

Google DNS (8.8.8.8) ist der meistgenutzte öffentliche Resolver — und einer der datenschutzfeindlichsten. Wenn überhaupt ein externer Resolver verwendet wird: Quad9 (9.9.9.9) mit DNSSEC-Validierung oder Cloudflare (1.1.1.1) sind deutlich bessere Alternativen. Besser noch: Unbound.

Das grundsätzliche Problem bleibt: Ein Dritter im Loop sieht Ihren DNS-Verkehr. Unbound löst das.

Unbound: die elegante Lösung

Unbound ist ein validierender, rekursiver DNS-Resolver. Statt eine Anfrage an einen externen Anbieter weiterzuleiten, fragt Unbound selbst bei den autoritativen Nameservern nach — beginnend bei den DNS-Root-Servern.

Der Ablauf: Unbound fragt zuerst einen Root-Server (a.root-servers.net etc.), der antwortet mit dem zuständigen TLD-Nameserver (z.B. für .de). Dieser verweist auf den autoritativen Nameserver der Domain. Unbound löst die Anfrage vollständig auf, ohne jemals eine vollständige Anfrage an einen einzelnen externen Anbieter zu stellen. Das Ergebnis wird gecacht.

Kein externer DNS-Anbieter sieht damit den vollständigen DNS-Verkehr Ihres Netzwerks.

Architektur und Datenpfad

Der Datenpfad nach diesem Setup:

Pi-hole ist der einzige DNS-Listener im Netzwerk (Port 53). Sein Upstream zeigt ausschliesslich auf 127.0.0.1#5533 — Unbound auf demselben Gerät. Unbound selbst ist nur über Localhost und das lokale Netz erreichbar, nicht öffentlich.

Installation

1

Pi-hole installieren

Falls Pi-hole noch nicht installiert ist, verwendet das offizielle Installer-Skript den bewährten Weg:

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

Während der Installation bei der Upstream-DNS-Konfiguration einen beliebigen Wert auswählen — dieser wird im naechsten Schritt durch Unbound ersetzt. Pi-hole kann auch nachträglich über die Admin-Oberfläche umkonfiguriert werden.

2

Unbound installieren

Unbound ist in den Standard-Repositories aller gängigen Debian-basierten Systeme enthalten:

Terminal
sudo apt update
sudo apt install unbound

Nach der Installation prüfe den Status:

Terminal
sudo systemctl status unbound

Unbound startet nach der Installation mit einer minimalen Standardkonfiguration. Diese wird im naechsten Schritt durch eine gehärtete Konfiguration ersetzt.

3

Root-Hints aktualisieren

Unbound benötigt eine Liste der DNS-Root-Server. Diese Datei sollte gelegentlich aktualisiert werden:

Terminal
sudo wget -O /etc/unbound/named.root \
https://www.internic.net/domain/named.root

Die Datei enthält die aktuellen IP-Adressen der 13 Root-Server-Gruppen.

Unbound konfigurieren

Die folgende Konfiguration basiert auf einem produktiven Homelab-Setup. Alle sicherheitsrelevanten Optionen sind aktiviert und kommentiert. Erstellen oder ersetzen Sie die Konfigurationsdatei:

/etc/unbound/unbound.conf.d/pi-hole.conf
server:
# ──────────────────────────────────────────────
# Netzwerk: nur auf Localhost hören
# Pi-hole leitet intern weiter, externe Geräte
# sprechen Unbound nie direkt an.
# ──────────────────────────────────────────────
interface: 127.0.0.1
port: 5533
do-ip4: yes
do-ip6: no
prefer-ip4: yes

# Zugriffskontrolle:
# Standardmäßig alles ablehnen, dann selektiv freigeben.
access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.0/8 allow
access-control: 192.168.1.0/24 allow    # LAN-Subnetz anpassen

# ──────────────────────────────────────────────
# Identität verbergen
# Niemand soll erfahren, welche Software oder
# Version hier laeuft.
# ──────────────────────────────────────────────
hide-identity: yes
hide-version: yes

# ──────────────────────────────────────────────
# QNAME-Minimierung (RFC 7816)
# Unbound sendet pro Anfrage nur den minimal
# nötigen Teil des Domainnamens an jeden
# Nameserver — kein Server sieht die vollständige
# Anfrage ausser dem autoritativen Nameserver.
# ──────────────────────────────────────────────
qname-minimisation: yes
qname-minimisation-strict: yes

# ──────────────────────────────────────────────
# DNSSEC-Härtung
# Antworten werden kryptografisch validiert.
# Manipulierte oder gefälschte Antworten werden
# erkannt und verworfen.
# ──────────────────────────────────────────────
harden-glue: yes
harden-dnssec-stripped: yes
harden-below-nxdomain: yes
harden-referral-path: yes
harden-algo-downgrade: yes
harden-large-queries: yes
harden-short-bufsize: yes

# DNSSEC Trust Anchor (automatisch aktualisiert)
auto-trust-anchor-file: "/var/lib/unbound/root.key"

# ──────────────────────────────────────────────
# Performance
# prefetch: nahezu ablaufende Cache-Einträge
# werden vorab erneuert, bevor sie ablaufen.
# serve-expired: während der Aktualisierung
# wird der abgelaufene Eintrag noch geliefert
# statt den Client warten zu lassen.
# cache-min-ttl: verhindert, dass Einträge mit
# sehr kurzer TTL den Cache unnötig belasten.
# ──────────────────────────────────────────────
prefetch: yes
serve-expired: yes
cache-min-ttl: 4400
edns-buffer-size: 1232

# ──────────────────────────────────────────────
# Weitere Sicherheitsoptionen
# use-caps-for-id: 0x20-Encoding als Schutz
# gegen Cache-Poisoning-Angriffe.
# aggressive-nsec: DNSSEC NSEC-Records werden
# genutzt um negative Antworten zu bestätigen,
# ohne den autoritativen Server erneut anzufragen.
# ──────────────────────────────────────────────
use-caps-for-id: yes
aggressive-nsec: yes
unwanted-reply-threshold: 10000

# ──────────────────────────────────────────────
# Root-Hints und lokale Zonen
# ──────────────────────────────────────────────
root-hints: "named.root"
do-not-query-localhost: no
insecure-lan-zones: yes
local-zone: "168.192.in-addr.arpa." nodefault

# ──────────────────────────────────────────────
# Systempfade
# ──────────────────────────────────────────────
tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt"
username: "unbound"
directory: "/etc/unbound"

Konfiguration testen und Dienst neu starten:

Terminal
sudo unbound-checkconf
sudo systemctl restart unbound
sudo systemctl enable unbound
LAN-Subnetz anpassen

Den Wert bei access-control auf das eigene LAN-Subnetz setzen, z.B. 10.0.0.0/24 oder 192.168.0.0/24. Alles andere wird von Unbound mit refuse abgewiesen.

Pi-hole auf Unbound zeigen

Damit Pi-hole Unbound als Upstream verwendet, muss der benutzerdefinierte DNS-Server in Pi-hole eingetragen werden.

Pi-hole v6 (pihole.toml)

In Pi-hole v6 wird die Konfiguration über /etc/pihole/pihole.toml verwaltet. Den Upstream-DNS-Abschnitt anpassen:

/etc/pihole/pihole.toml
[dns]
# Unbound auf demselben Gerät, Port 5533
upstreams = [ "127.0.0.1#5533" ]

Pi-hole v5 (Admin-Oberfläche)

In Pi-hole v5 über die Admin-Oberfläche: Settings → DNS → Upstream DNS Servers. Alle vorhandenen Haken entfernen, unter "Custom 1 (IPv4)" den Wert 127.0.0.1#5533 eintragen und speichern.

Wichtig: kein weiterer Upstream

Sicherstellen, dass keine anderen Upstream-DNS-Server konfiguriert sind (weder Quad9 noch Cloudflare). Pi-hole soll ausschliesslich Unbound verwenden — sonst gehen Anfragen weiterhin teilweise an externe Resolver.

Pi-hole neu starten, damit die Änderung wirksam wird:

Terminal
sudo systemctl restart pihole-FTL

Netzwerk-Härtung: UFW und TCP Wrappers

Pi-hole und Unbound sollten nur aus dem eigenen Netzwerk erreichbar sein. Die folgenden Regeln zeigen eine typische Konfiguration, die nur LAN-Zugriff erlaubt.

UFW Firewall

UFW (Uncomplicated Firewall) auf Debian/Ubuntu setzt iptables-Regeln ohne komplexe Syntax. Ziel: alle eingehenden Verbindungen verweigern, nur LAN explizit erlauben.

Terminal
# Standardregeln
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH nur aus dem LAN (Subnetz anpassen)
sudo ufw allow from 192.168.1.0/24 to any port 22

# DNS: Pi-hole auf Port 53
sudo ufw allow from 192.168.1.0/24 to any port 53

# Unbound direkt (optional, falls Debugging benötigt)
sudo ufw allow from 192.168.1.0/24 to any port 5533

# Pi-hole Admin-Oberfläche (Port 80/443)
sudo ufw allow from 192.168.1.0/24 to any port 80,443 proto tcp

# UFW aktivieren
sudo ufw enable
sudo ufw status verbose
Warum Unbound in UFW freigeben?

Port 5533 muss nicht zwingend via UFW erreichbar sein, da Pi-hole Unbound nur über Localhost (127.0.0.1) anspricht. Die Regel ist optional und kann für gelegentliches Debugging von anderen Geräten aus nützlich sein. In einem hochgehärteten Setup kann sie entfallen.

TCP Wrappers (hosts.allow / hosts.deny)

TCP Wrappers ist eine weitere Zugriffskontrollschicht, die unabhängig von der Firewall arbeitet. Die Kombination aus beiden erhöht die Sicherheitstiefe.

/etc/hosts.allow
# Alle Dienste: Zugriff nur aus dem LAN erlaubt
ALL: 192.168.1.0/24
/etc/hosts.deny
# PARANOID: Hosts ablehnen, deren Hostname nicht
# zur aufgelösten IP-Adresse passt (Reverse-DNS-Prüfung).
# Schützt vor Spoofing-Versuchen.
ALL: PARANOID
hosts.deny: PARANOID statt ALL

ALL: PARANOID lehnt Verbindungen ab, bei denen der Hostname nicht zur IP-Adresse passt — ein Schutz gegen DNS-Spoofing. ALL: ALL wäre strenger (blockiert alle, die nicht in hosts.allow stehen), aber PARANOID ist in den meisten Homelab-Szenarien der sinnvollere Kompromiss.

Verifikation

Nach der Konfiguration prüfen, ob alles wie erwartet funktioniert.

Unbound direkt testen

Auf dem Pi selbst eine Anfrage direkt an Unbound stellen:

Terminal (auf dem Pi)
dig google.com @127.0.0.1 -p 5533
Erwartete Ausgabe:

Die Antwort enthält status: NOERROR und aufgelöste IP-Adressen im ANSWER SECTION. Das Flag ad (Authenticated Data) zeigt an, dass DNSSEC-Validierung erfolgreich war.

Pi-hole als DNS testen

Von einem Gerät im Netzwerk die Pi-hole-IP als DNS verwenden:

Terminal (von anderem Gerät im LAN)
# IP des Pi anpassen
dig google.com @192.168.1.x

Unbound-Status prüfen

Terminal
sudo systemctl status unbound
sudo journalctl -u unbound -n 50 --no-pager

DNSSEC-Validierung testen

Diese Domain ist absichtlich mit einem fehlerhaften DNSSEC-Record signiert und sollte von einem korrekten Resolver nicht aufgelöst werden:

Terminal
dig sigfail.verteiltesysteme.net @127.0.0.1 -p 5533
Erwartetes Ergebnis:

status: SERVFAIL — Unbound hat die fehlerhafte Signatur erkannt und die Antwort verworfen. Das ist das korrekte Verhalten.

Setup vollständig

Wenn beide Tests bestehen — erfolgreiche Auflösung normaler Domains und SERVFAIL für die DNSSEC-Testdomain — funktioniert Pi-hole + Unbound mit DNSSEC-Validierung korrekt.

Bonus: WireGuard als weitere Schutzschicht

Auch mit Unbound sieht der Internet Service Provider (ISP) den DNS-Verkehr, den Unbound nach außen schickt — inklusive der angefragten Domainnamen im Klartext. DNS ist standardmäßig unverschlüsselt.

WireGuard löst auch das: Wenn der DNS-Datenverkehr über einen WireGuard-Tunnel geleitet wird, sieht der ISP nur verschlüsselten WireGuard-Traffic, nicht die DNS-Anfragen selbst. Der VPN-Endpunkt (z.B. ein VPS in einem Rechenzentrum) wird zum sichtbaren Absender der DNS-Anfragen.

Sinnvoll je nach Bedrohungsmodell

Fur die meisten Heimnetzwerke und kleinen Büros bietet Unbound allein schon erheblichen Datenschutzgewinn — kein DNS-Anbieter sieht mehr den vollständigen Verkehr. WireGuard ist eine optionale weitere Schicht für Anwendungsfälle, bei denen auch die Verbindungsmetadaten gegenüber dem ISP verborgen bleiben sollen. Ein dedizierter WireGuard-Guide folgt in dieser Reihe.

Fazit

Pi-hole ohne Unbound ist wie ein Briefkasten mit Schloss, dessen Schlüssel bei der Post liegt. Erst Unbound macht das System vollständig.

Was dieser Setup konkret bringt

  • Kein externer Resolver: Kein DNS-Anbieter sieht den vollständigen Netzwerkverkehr. Pi-hole filtert, Unbound löst selbst auf.
  • DNSSEC-Validierung: DNS-Antworten werden kryptografisch geprüft. Manipulierte Antworten (DNS-Spoofing, Cache-Poisoning) werden erkannt und verworfen.
  • QNAME-Minimierung: Jeder Nameserver entlang der Auflösung erhält nur den Teil des Namens, den er sehen muss — kein Server kennt die vollständige angefragte Domain.
  • Gehärtete Netzwerkschicht: UFW und TCP Wrappers stellen sicher, dass Pi-hole und Unbound nur aus dem eigenen Netzwerk erreichbar sind.
  • Günstiges Setup: Ein Raspberry Pi 4 (~70 Euro) trägt diesen Stack problemlos für kleine Netzwerke mit bis zu 50 Geräten. Keine Cloud, keine Abonnements, keine Abhängigkeiten von Drittanbietern.
  • Erweiterbar: Mit WireGuard lässt sich der DNS-Verkehr verschlüsseln und die Domainnamen vor dem ISP verbergen.

Verwendete Open-Source-Projekte