Project Rebel Homebase: Teil 3
Die Hardware steht, jetzt bekommt die Rebellion ihr Gehirn. Warum „zwei Pi-holes im DHCP“ kein Cluster sind und wie wir mit Keepalived, Unbound und einer virtuellen IP echte digitale Souveränität bauen. Schluss mit Werbung, Tracking und Google DNS. Der „Stormtrooper“ erwacht.
Der erste Meilenstein ist erledigt. Die Hardware aus Teil 1 (Die Idee) und Teil 2 (Die Hardware) steht. Die ersten beiden Blades sind montiert, das Netzwerk leuchtet. Alles bereit für Kubernetes und die großen Container-Schlachten, oder?
Falsch.
Wenn diese Homebase mehr sein soll als ein Spielplatz für ein paar Wochen, dann braucht sie verlässliche Basissysteme. Das Schwierigste erledigt? Träumt weiter. Was jetzt kam, hat mein Verständnis von Infrastruktur extrem vorangebracht.
Was euch heute erwartet
Ein Erlebnisbericht, eine Dokumentation und Anleitung.
Zielgruppe 1: Neugierige Nicht-Admins mit Leidensfähigkeit.
Zielgruppe 2: Erfahrene Admins zur Unterhaltung und zum Schmunzeln.
Dieser Text ist kein klassischer kurzer Blogartikel und kein kompaktes How-To. Er ist furchtbar lang. Und langweilig. Und das ist nötig. Er ist ein Protokoll gescheiterter Annahmen und (so hoffe ich) eine vollständige, reproduzierbare Dokumentation.
Er richtet sich an Menschen, die sich mit selbst betriebener souveräner Infrastruktur auseinandersetzen, sich durchbeißen, immer wieder scheitern und trotzdem weitermachen. Wenn du erwartest, dass Dinge „einfach funktionieren“: falscher Text. So war es nicht.
Einordnung: Ich bin kein Admin (und du vielleicht auch nicht)
Wenn du diesen Text liest, bist du wahrscheinlich kein gelernter Systemadministrator. Ich bin es auch nicht.
Ich kann mir Dinge erarbeiten. Ich kann Zusammenhänge verstehen. Aber ich scheitere regelmäßig an Stellen, an denen Dokumentationen einfach voraussetzen, dass man weiß, warum man gerade etwas tut. Dieser Artikel ist deshalb absichtlich langsam, pedantisch und vollständig. Nicht, weil DNS kompliziert sein muss, sondern weil es unforgiving ist. Es verzeiht keine Fehler. Und bitte ... testet immer. Ich habe jeden einzelnen Schritt recht mühselig lernen müssen.
Warum wir rebellieren
„Jede Rebellion beginnt mit Hoffnung.“
Das wissen wir von Cassian Andor.
Spätestens seit Rogue One.
Aber worauf hoffen wir hier, wenn wir Server in den Keller schrauben? Wir hoffen auf Autonomie. Und dasss Menschen dazulernen können.
Bevor wir tief in Config-Dateien abtauchen, müssen wir kurz klären, warum wir das hier tun. Warum nutzen wir nicht einfach Google DNS (8.8.8.8) oder Cloudflare (1.1.1.1)? Das wäre bequem. Es wäre kostenlos. Es wäre in 5 Sekunden eingerichtet.
Aber Bequemlichkeit ist der Käfig, den Big Tech erfolgreich um uns gebaut hat.
Jedes Mal, wenn wir die Infrastruktur der großen Hyperscaler nutzen, zahlen wir mit dem einzigen, was wir wirklich besitzen: unseren Daten und unserer Unabhängigkeit.
- Closed Source ist eine Blackbox. Wir wissen nicht, was darin passiert.
- Hyperscaler zentralisieren das Internet. Wenn
us-east-1hustet, bekommt das halbe Internet eine Lungenentzündung. - Digitale Souveränität bedeutet, dass ich entscheide, ob mein Fernseher nach Hause telefoniert, nicht der Hersteller (dazu kommen wir auch noch).
Wir bauen diese Homebase nicht, weil es einfacher ist. Wir bauen sie, weil es notwendig ist, um ein Stück Freiheit zurückzuerobern. Wer seine Basisinfrastruktur (DNS) aus der Hand gibt, hat den Kampf schon verloren, bevor er begonnen hat. Und Dezentralisierung ist der einzige Weg zu wirklicher Resilienz.
Das hier ist kein Hobby-Projekt. Es ist der Bau eines digitalen Schutzraums.
It’s always DNS... oder wie ich lernte, meinen Router nicht mehr anzubrüllen
Hand aufs Herz: Wie oft hieß es schon „Das Internet geht nicht!“, nur um festzustellen, dass eigentlich nur der DNS-Server klemmt? AWS, Microsoft und Cloudflare hatten Ende 2025 mehrere leidvolle Episoden dieser Art, ihr werdet euch erinnern.
DNS und Zeit (NTP) sind keine „Nice-to-Haves“. Sie sind:
- Die Grundlage für alles, was später kommt (Matrix, OpenCloud/Nextcloud, Authentifizierung etc.).
- Der Single Point of Failure in 99 % aller Heimnetze.
- Und gleichzeitig eines der am meisten unterschätzten Probleme.
Wer hier pfuscht, baut ein Kartenhaus.
Meine Infrastruktur-Grundsätze (oder: Warum wir es kompliziert machen)
Warum installiere ich nicht einfach AdGuard Home auf dem Router und fertig? Warum nicht gleich alles in den Kubernetes-Cluster werfen?
Weil ich Infrastruktur-Grundsätze definiert habe, die über „es funktioniert gerade irgendwie“ hinausgehen.
1. Trennung der Gewalten (Die Hardware-Wahl)
Ich nutze für DNS und NTP zwei dedizierte Raspberry Pi CM4 Blades (Blade 01 & 02).
- Warum CM4 mit 8 GB RAM? Ist das nicht Overkill für DNS? Ja. Aber DNS darf nie aus Speichermangel oom-killed (Out of Memory) werden. Es muss atmen können.
- Warum nicht im Kubernetes-Cluster? Henne-Ei-Problem. Wenn der Cluster crasht (und das wird er am Anfang), brauche ich ein funktionierendes DNS, um ihn zu reparieren. Basisinfrastruktur muss unterhalb der Anwendungsebene liegen.
Mit Kanonen auf Spatzen schießen? Vielleicht. Aber dieser Spatz (Werbung & Tracker) ist danach definitiv tot. Oder anders gesagt: Overengineering ist nur ein anderes Wort für 'Ich will nachts ruhig schlafen'.
2. Zeit ist Wahrheit (Warum NTP wichtig ist)
Ein Raspberry Pi hat keine BIOS-Batterie (RTC) wie ein PC oder ein Handy. Nach einem Stromausfall denkt er, es ist 1970. Moderne Sicherheit (Kerberos, SSL-Zertifikate, 2FA) bricht sofort zusammen, wenn die Uhren nicht synchron sind. Logs werden nutzlos, wenn die Zeitstempel falsch sind. Deshalb werden diese beiden Nodes auch meine NTP-Server für das gesamte Netz.
3. Digitale Souveränität (Open Source only & No Cloud)
Keine Abhängigkeit von Google DNS, keine Abhängigkeit von Cloudflare für interne Auflösung. Wenn das Internetkabel durchgeschnitten wird, muss mein Haus intern weiter zu 100 % funktionieren.
Die Strategie der Namen: Domains & Identität
Ein Punkt, über den ich lange gegrübelt habe, ist das Naming.
Warum feste IPs und FQDNs?
In vielen Heimnetzen heißt der Server raspberrypi.local und hat irgendeine DHCP-Adresse. Das ist für ein Rebel Setup inakzeptabel.
- Feste IPs sind wie Hausnummern im Grundbuch. Unveränderlich.
- FQDN (Fully Qualified Domain Names): Wir nutzen
dns1.pandolin.onlinestatt nurdns1. Warum? Weil wir später vielleicht echte SSL-Zertifikate wollen. Und Zertifizierungsstellen validieren keine.localDomains.
Das Zwei-Welten-Prinzip (.io vs. .online)
Ich trenne meine digitale Identität strikt:
pandolin.io: Das ist meine öffentliche Visitenkarte. Mein Blog, Cloud-Dienste, E-Mail. Das liegt im „bösen“ Internet.pandolin.online: Das ist meine Homebase. Meine Lab-Umgebung. Meine Daten. Betonung auf "mein".
Split-Horizon DNS (Der heilige Gral)
Der Clou an diesem Setup: Ich nutze intern wie extern für die Homebase dieselbe Domain (*.pandolin.online).
- Bin ich unterwegs, löst
home.pandolin.onlineauf meine öffentliche VPN-IP auf. - Bin ich zu Hause, löst
home.pandolin.onlinedirekt auf die interne LAN-IP (192.168.1.x) auf.
Das bedeutet: Meine Geräte müssen nie umkonfiguriert werden. Egal wo ich bin, die Dienste heißen gleich. Das nennt man „Split Horizon DNS“ – und genau das bauen wir heute.
Das Zielbild
Am Samstag habe ich beschlossen, dem Spuk ein Ende zu bereiten und den nächsten Schritt zu gehen. Mein Ziel: Eine hochverfügbare DNS-Infrastruktur mit Ad-Blocking und voller Datensouveränität. Wenn ein Server ausfällt, soll der andere nahtlos übernehmen – ohne dass Netflix auch nur ruckelt.
Die Zielsetzung war simpel formuliert – und komplex umzusetzen:
- Linux only (Ubuntu 24.04 LTS)
- Split-Horizon: Gleiche Namen intern wie extern
- Transparenz: Ich will sehen, welches Gerät welche Tracker aufruft (Pi-hole)
- Souveränität: Eigener rekursiver Resolver (Unbound) statt Google
- Echte Redundanz: Nicht einfach zwei IP-Adressen im Router eintragen (das ist Glücksspiel), sondern eine virtuelle IP, die immer antwortet.
In diesem Abenteuer-Guide nehme ich dich/euch mit auf die Reise durch mein Setup mit Ubuntu 24.04 LTS, Pi-hole, Unbound und Keepalived. Wir bauen nicht nur, wir lernen auch, denn ich bin in ein paar fiese Fallstricke getreten. Damit du es hoffentlich nicht musst.

Warum DNS immer der erste echte Schmerz ist
Hand aufs Herz:
Wie oft hieß es schon „Das Internet geht nicht“, und am Ende war es nur DNS?
Ende 2024 / 2025 hatten AWS, Microsoft, Cloudflare und andere mehrere massive Ausfälle. Nicht wegen Hardware, sondern wegen DNS.
DNS ist:
- unsichtbar
- selbstverständlich
- und wenn es kaputt ist, fühlt sich alles andere auch kaputt an
Genau deshalb habe ich beschlossen, hier zuerst professionell zu werden.
Erste naive Annahme: Zwei Pi-holes reichen
Meine erste Idee war simpel:
Ich baue zwei Pi-holes. Trage beide im Router ein. Fertig ist die Redundanz.
Das ist falsch.
Warum?
Ein Client (Windows, macOS, Linux, Fernseher, Handy):
- bekommt mehrere DNS-Server
- entscheidet selbst, welchen er fragt
- wechselt nicht zuverlässig, wenn einer nicht antwortet
Das Ergebnis geht es manchmal, manchmal hängt alles, niemand weiß warum.
Zwei DNS-Server im DHCP sind wie zwei Kassen im Supermarkt: Wenn an der ersten die Kassiererin einschläft, wartest du trotzdem erst mal stur fünf Minuten, bevor du die Schlange wechselst.
Definieren wir das Zielbild
Bevor wir irgendetwas installieren, muss klar sein, wie es sich anfühlen soll, wenn es fertig ist.
Ziel:
- Alle Geräte im Haus kennen nur eine DNS-Adresse
- Diese Adresse funktioniert immer
- Wenn ein Server ausfällt, merkt es niemand
Diese eine Adresse nennt man VIP, die virtuelle IP.
Sie gehört nicht fest zu einem Server. Sie wird dynamisch übernommen. Von dem Server, der gerade gesund ist. Eine wandernde Hausnummer.
In diesem Setup ist die VIP die 192.168.1.5
Alle Clients und Services reden mit nur .5.
Welcher der existierenden DNS-Server antwortet, ist egal.
Schritt 1: Zwei Server, die sich selbst korrekt benennen können
Wir beginnen nicht mit DNS. Wir beginnen mit Namen.
Warum?
Weil Logs ohne Namen nutzlos sind, Reverse DNS später sonst Chaos produziert und man sonst nie weiß, welcher Server gerade antwortet.
Ausgangspunkt
- 2× Raspberry Pi Blades mit CM4, 8 GB Ram, 256 Gb Nvme, 1 GBit Anbindung
- Ubuntu 24.04 LTS Server
- Netzwerk funktioniert grundsätzlich (Internet geht, IP-Adressen werden verteilt etc.)
Wir nennen sie:
dns1.pandolin.online
dns2.pandolin.online
Der erste echte Stolperstein: Ubuntu 24.04 & cloud-init
Fast jede Anleitung sagt dir: „Bearbeite /etc/hosts.“ Das funktioniert nicht dauerhaft unter Ubuntu 24.04.
Warum?
Ubuntu nutzt cloud-init, auch auf Bare Metal. Ein Self-Healing. Diese Komponente überschreibt /etc/hosts beim Booten.
Das merkst du so:
- Du trägst etwas ein
- Es funktioniert
- Du rebootest
- Alles ist weg und auf dem Ausgangszustand.
- Grmpf.
Die korrekte Lösung (eine Stunde später)
Wir bearbeiten das Template, nicht die Datei selbst.
Auf dns1:
sudo hostnamectl set-hostname dns1.pandolin.online
Jetzt das Template öffnen:
sudo nano /etc/cloud/templates/hosts.debian.tmpl
Inhalt minimal und bewusst:
127.0.0.1 localhost
127.0.1.1 dns1.pandolin.online dns1
Warum 127.0.1.1?
Weil Ubuntu diesen Eintrag intern erwartet, und alles andere später zu Warnungen führt.
Speichern, dann:
sudo reboot
Test: Hat es wirklich funktioniert?
Nach dem Neustart:
hostname
hostname -f
Erwartung:
dns1.pandolin.online
Wenn hier noch irgendetwas anderes steht dann nicht weitermachen. Zurück. Das hier ist die Basis. Wenn es klappt, das selbe bitte mit korrespondierenden Werten auf dns2.
Schritt 2: Feste IP-Adressen – warum „automatisch“ hier dein Feind ist
Bis hierhin haben wir nur Namen gesetzt.
Jetzt kommt der nächste Punkt, an dem viele Anleitungen lakonisch sagen: „Vergib eine statische IP.“ Das klingt banal. Ist es nicht. Server ohne feste IP sind wie Hotelgäste. Bald wieder weg.
Warum feste IPs zwingend notwendig sind
Ein DNS-Server mit wechselnder IP ist wie ein Telefonbuch, das jede Nacht umzieht. Du kannst darauf aufbauen, aber du wirst es später bereuen.
Für unser Setup gilt deshalb:
dns1.pandolin.online→ 192.168.1.3dns2.pandolin.online→ 192.168.1.4- die virtuelle IP (VIP) kommt später (
192.168.1.5)
Diese 3 IPs dürfen sich niemals ändern.
Wie Ubuntu 24.04 Netzwerke konfiguriert (kurz, aber wichtig)
Ubuntu nutzt Netplan.
Das ist kein Dienst, sondern ein Konfigurationsformat, das beim Booten Netzwerkinterfaces, IP-Adressen, Gateways und DNS-Resolver setzt.
Das Entscheidende: Wenn Netplan falsch ist, hast du kein Netzwerk. Und damit auch oft auch keinen SSH-Zugriff mehr.
Deshalb hier langsam und bewusst voran.
Die Netplan-Datei erstellen
Auf dns1:
sudo nano /etc/netplan/01-static.yaml
Falls die Datei nicht existiert: kein Problem, neu anlegen.
Inhalt für dns1:
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
addresses:
- 192.168.1.3/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses:
- 9.9.9.9
- 149.112.112.112
Was passiert hier im Detail?
dhcp4: no„Nein, ich möchte keine automatische IP.“addressesDas ist unsere Identität im Netz.via: 192.168.1.1Das ist mein Router (DreamWall).nameserversDas ist nur temporär. Später ersetzt Pi-hole das. Jetzt brauchen wir es, damit das System selbst DNS kann.
Der Moment der Wahrheit
sudo netplan apply
Wenn jetzt keine Fehlermeldung kommt und die SSH-Verbindung nicht abbricht passt alles.
Wenn die Verbindung abbricht, ruhig bleiben, Tippfehler suchen.
Tests - und bitte nicht überspringen:
ip a
Du willst dieses Ergebnis:
inet 192.168.1.3/24
Dann:
ping -c 3 192.168.1.1
Wenn das klappt, dann:
ping -c 3 9.9.9.9
Danach:
ping -c 3 heise.de
Erst wenn alle 3 Tests funktionieren, ist Schritt 2 erledigt.
Auf dem dns2 machen wir exakt dasselbe nur mit der 192.168.1.4.
Schritt 3: Unbound. Was ein Resolver ist (und warum wir ihn brauchen)
Jetzt kommt der erste Punkt, an dem man sich fragen kann:
„Warum der ganze Aufwand? Pi-hole kann doch DNS.“
Ja. Aber Pi-hole ist kein Resolver, sondern "nur" ein ausgezeichneter Filter.
Kurz gesagt:
Pi-hole entscheidet, ob eine Anfrage erlaubt ist, Unbound entscheidet, woher die Antwort kommt.
Wenn du Pi-hole direkt auf Google, Cloudflare oder deinen ISP zeigen lässt, hast du diverse Abhängigkeiten, keine echte Kontrolle, keinen klaren Trennstrich.
Ein Fallback zu Google DNS ist kein Sicherheitsnetz. Es ist eine Kapitulation.
Unbound macht dich souverän. Der Name ist Programm.
Installation
Auf beiden DNS-Servern:
sudo apt update &&
sudo apt install -y unbound unbound-anchor`
Warum Unbound nicht auf Port 53 läuft
Port 53 gehört später Pi-hole. Unbound läuft lokal, versteckt, auf Port 5335.
Das ist Absicht. Keine Clients sprechen direkt mit Unbound. Pi-hole ist der einzige Zugang.
Konfigurationsdatei anlegen
sudo nano /etc/unbound/unbound.conf.d/pi-hole.conf
Inhalt:
server:
interface: 127.0.0.1
port: 5335
do-ip4: yes
do-udp: yes
do-tcp: yes
hide-identity: yes
hide-version: yes
access-control: 127.0.0.0/8 allow
forward-zone:
name: "."
forward-addr: 9.9.9.9
forward-addr: 149.112.112.112`
Was bedeutet das nun genau?
127.0.0.1Nur dieser Rechner darf fragen.port 5335Kollisionsfrei mit Pi-hole.forward-zone "."„Alles, was ich nicht selbst weiß, frage bei folgendem DNS-Anbieter.“
Ich nutze Quad9, weil europäisch/schweizerisch, datenschutzfokussiert, perfekte Malware-Filter.
Mein nächster Stolperstein: Trust Anchor
Unbound braucht eine Root-Vertrauensbasis. Manchmal ist die doppelt konfiguriert. Wie bei mir.
Wenn Unbound also nicht startet, prüfe:
grep -R "trust-anchor\|auto-trust-anchor-file" \ /etc/unbound/unbound.conf /etc/unbound/unbound.conf.d/* 2>/dev/null`
Wenn du zwei Treffer siehst, einen entfernen.
Initialisierung & Start
sudo unbound-anchor -a /var/lib/unbound/root.key
sudo chown unbound:unbound /var/lib/unbound/root.key
sudo chmod 0644 /var/lib/unbound/root.key
sudo unbound-checkconf
sudo systemctl enable --now unbound
Test (wie immer sehr wichtig)
dig @127.0.0.1 -p 5335 heise.de
Wenn du eine Antwort bekommst läuft Unbound, Dein DNS funktioniert unddu kannst weitermachen. Yeah!
Wenn nicht: Nicht mit Pi-hole anfangen. Erst hier reparieren.
Schritt 4: Pi-hole – und warum die GUI dich anlügt (nicht absichtlich, aber zuverlässig)
Jetzt kommt der Punkt, an dem viele Anleitungen wieder fröhlich sagen:
„Installiere Pi-hole, klick dich durch den Wizard, fertig.“
Und ja:
Pi-hole lässt sich leicht installieren und Pi-hole lässt sich extrem leicht falsch betreiben.
Die GUI ist freundlich. Die Defaults wirken plausibel. Und genau deshalb ist Pi-hole gefährlich für Menschen wie uns.
Was Pi-hole ist – und was nicht
Bevor wir irgendetwas installieren, eine Klarstellung:
Pi-hole ist kein DNS-Server im klassischen Sinn. Pi-hole ist ein DNS-Filter. Damit entscheidet Pi-hole Fragen wie: Darf diese Anfrage raus? Oder blocke ich sie?
Pi-hole löst nicht selbst rekursiv auf. Das macht Unbound, den wir im letzten Schritt gebaut haben.
Warum doch gleich noch mal so kompliziert? Wenn du das nicht trennst, wirst du später Logs nicht verstehen, Reverse DNS hassen und bei Fehlern nicht wissen, wo du suchen musst.
Installation: ja, das ist der einfache Teil
Auf dns1 (und dann identisch auf dns2 - ich habs in 2 Fenstern parallel gemacht):
curl -sSL https://install.pi-hole.net | bash
Der Installer ist textbasiert, interaktiv, (erinnert an Borlands Turbo Vision, kennt das noch jemand?). Und voll von Entscheidungen, die man falsch treffen kann. Ich gehe sie eine nach der anderen durch.

Installer-Schritt für Installer-Schritt
1. Netzwerkschnittstelle
Q: „Which interface should Pi-hole use?“
A: eth0
Warum? Das ist dein LAN. No network magic. Keine VLAN-Spielchen (bei mir noch nicht)
2. Upstream DNS Server – hier beginnt der Ärger
Pi-hole zeigt dir jetzt:
- Cloudflare
- OpenDNS
- Quad9
- Custom
Ja, wir wollen langfristig Quad9, trotzdem hier niemals einfach etwas anhaken.
A: Custom**
Dann trägst du exakt ein: 127.0.0.1#5335
Warum? 127.0.0.1 ist der lokale Rechner, #5335 → der Port, auf dem Unbound lauscht
Damit erzwingen wir: Alle DNS-Anfragen laufen: Client → Pi-hole → Unbound → Internet
Wenn du hier Google auswählst, hebelst du deine gesamte Souveränität wieder aus.
3. Blocklists
A: Yes
Wir wollen Pi-hole ja genau deshalb.
4. Query Logging
A: Yes
Wichtig, gerade am Anfang. Warum? Du wirst Dinge debuggen. Du willst sehen, wer fragt was und Du willst später verstehen, warum etwas blockiert wurde. Datenschutzdiskussionen führen wir nachdem es funktioniert. Oder im Heimnetzwerk etwas laxer sehen :-)
5. Privacy Mode
A: Level 0
Das ist absichtlich. Level 0 heißt volle Sichtbarkeit, maximale Transparenz, kein Rätselraten. Später kannst du das bei Bedarf härter drehen.
6. Web Interface & Web Server
A:Beides Yes
Du willst das Dashboard, die Logs, all die schicken Statistiken.
7. Passwort merken!
Pi-hole zeigt dir jetzt ein Admin-Passwort an.
Mach einenScreenshot. Oder aufschreiben. Nicht ignorieren. Screenshot ist sicherer.
Danach kannst (und solltest) du es ändern:
sudo pihole setpassword
Nein, bitte nicht dein Ubuntu-User-Passwort verwenden.
Der erste (falsche) Eindruck: „Es läuft doch!“
Nach der Installation sagt Pi-hole: „Pi-hole blocking is enabled“
Und tatsächlich, die Webseiten laden, Werbung ist weg,alles scheint gut zu sein
Jetzt bitte einmal innehalten. Pi-hole läuft. Aber noch völlig falsch für unser Ziel.
Der wichtigste GUI-Schritt (den fast jeder übersieht)
Einmal bitte auf die Weboberfläche ...
http://192.168.1.3/admin
... und Login mit dem gesetzten Passwort.
Gehe zu:
Settings → DNS
Jetzt kommt der Punkt, an dem die GUI dich anlügt. Oder zumindest etwas weglässt.
Upstream DNS Server (oberer Bereich)
Du siehst:
- Cloudflare
- OpenDNS
- Quad9
- etc.
Nimm ALLE HÄKCHEN RAUS.
Warum? Weil Pi-hole sonst (parallel zu Unbound) externe Resolver fragt und du nie sicher bist, woher Antworten kommen.

Custom DNS Servers (unterer Bereich)
Hier muss stehen: 127.0.0.1#5335
Und nur das. Kein zweiter Eintrag. Kein Fallback. Keine „für alle Fälle“-DNS.
Merksatz:
Ein Fallback-DNS ist kein Backup, sondern ein Bypass.
Interface Settings
Hier bitte bewusst wählen:
Allow only local requests
Warum? Pi-hole beantwortet Anfragen aus deinem LAN, nicht aus dem Internet, nicht aus fremden Netzen. Wir wollen doch keine Türen in finstere fremde Dimensionen öffnen ...
Speichern & Neustart
Nach Änderungen:
pihole restartdns
4.1: Test - Funktioniert Pi-hole überhaupt?
Auf dns1 selbst:
dig heise.de
Wenn du eine Antwort bekommst: Pi-hole → Unbound → Internet funktioniert.
Wenn nicht: Nicht weitermachen. Fixen!
4.2: Dashboard-Check: Siehst du Queries im Dashboard?
Öffne das Dashboard. Du solltest Queries, Domains, Clients (wenn auch nur bisher IP's) sehen.
Wenn hier nichts auftaucht, wird Pi-hole nicht genutzt oder oder lauscht nicht korrekt.

Warum wir hier noch keinen Client anschließen
Bis hierhin haben wir erreicht dass
- Pi-hole läuft,
- Unbound läuft und
- DNS funktioniert
- Webseiten laden ohne Werbung
Schön. Aber:
- Namen sind noch nicht sauber
- Reverse DNS fehlt
- Hochverfügbarkeit fehlt
- Failover fehlt
Wenn wir jetzt schon Clients auf Pi-hole schicken sammeln wir Logs, die später wertlos sind, verunsichern bei Fehlern und erschweren das Debugging
Deshalb: Erst das Fundament fertiggiessen, dann folgt der Straßenverkehr.
Schritt 5: Reverse DNS, PTR & der pi.hole-Fluch
(oder: Warum Logs ohne Namen dich langsam wahnsinnig machen)
Irgendwas passt noch nicht. Spätestens dann, wenn du ins Pi-hole-Dashboard schaust, siehst Du es. Oder eben nur ...
Das erste Symptom: „Warum sehe ich nur IP-Adressen?“
Im Dashboard siehst du: 192.168.1.23, 192.168.1.42, 192.168.1.101 aber keine Namen.
Oder noch schlimmer wie in meinem Fall. Plötzlich taucht überall pi.hole auf, also bei Reverse Lookups, in Logs und in Tools wie nslookup. Hier habe ich die längste und frustrierendste Zeit verbracht.
Das ist der Moment, in dem viele denken: „Ach egal, Hauptsache es geht.“
Tu dir selbst einen Gefallen: Nein.
Warum Reverse DNS hier entscheidend ist
Reverse DNS beantwortet nicht: „Wie heißt google.com?“ sondern „Wer bist du eigentlich?“
Also:
Wer steckt hinter 192.168.1.3?
Welcher Server antwortet gerade?
Welcher Client fragt hier ständig Unsinn?
Ohne Reverse DNS sind Logs sind anonym, Debugging ist mühsam, Hochverfügbarkeit ist nicht nachvollziehbar.
Mit Reverse DNS dagegen erkennst du sofort, wer was tut, Du siehst im Failover, welcher Node aktiv ist und die werden Dashboards endlich lesbar.
Was wir erreichen wollen
Diese Tests sollen und müssen alle funktionieren:
nslookup dns1.pandolin.online 192.168.1.3
nslookup 192.168.1.3 192.168.1.3````
Erwartung:
- Forward: `dns1.pandolin.online → 192.168.1.3`
- Reverse: `192.168.1.3 → dns1.pandolin.online`
**Und nirgendwo darf/soll `pi.hole` auftauchen.**
___
## Schritt 5.1: Lokale DNS-Records in Pi-hole setzen
Das machen wir **bewusst zuerst über die GUI**.
#### Öffne die Pi-hole Web-Oberfläche
````nginx
http://192.168.1.3/admin
Gehe zu:
Local DNS → DNS Records und trage ein:
| Domain | IP |
|---|---|
dns1.pandolin.online |
192.168.1.3 |
dns2.pandolin.online |
192.168.1.4 |
| Und ... speichern. |
Test! (Forward DNS)
Auf dns1:
nslookup dns1.pandolin.online 192.168.1.3
Wenn du jetzt keine Antwort bekommst, dann die übliche Runde. Tippfehler prüfen und nicht weitermachen bevor alles klappt.
Schritt 5.2: PTR Records (Reverse DNS) setzen
Jetzt der Teil, den viele übersehen.
In der Pi-hole GUI:
Local DNS → PTR Records
| IP | Hostname |
|---|---|
192.168.1.3 |
dns1.pandolin.online |
192.168.1.4 |
dns2.pandolin.online |
Und nochmal ... speichern.
Test! (Reverse DNS)
nslookup 192.168.1.3 192.168.1.3
Jetzt kommt der Moment Deiner Wahrheit.
Wenn jetzt pi.hole zurückkommt: Willkommen im Fluch
Wie bei mir. Sehr wahrscheinlich siehst du immer noch Name: pi.hole
Oder Pi-hole taucht in Logs auf, obwohl du alles korrekt eingetragen hast.
Du hast nichts falsch gemacht. Das ist ein Default-Verhalten von Pi-hole, das nicht über die GUI steuerbar ist. Und genau hier scheitern die meisten Anleitungen.
Ich glaube das waren bei mir 2 Stunden und 4 Tassen Kaffee.
Die eigentliche Ursache (endlich erklärt)
Pi-hole hat intern eine Einstellung: „Was soll ich als PTR-Namen zurückgeben, wenn ich selbst angesprochen werde?“
Standardantwort: PI.HOLE
Egal, was du in der GUI einträgst. Das ist historisch gewachsen, schlecht bis gar nicht dokumentiert und war für mich extrem verwirrend.
Die Lösung liegt nicht in der GUI
Sie liegt in einer Datei, die kaum erwähnt wird: /etc/pihole/pihole.toml
Schritt 5.3: Der entscheidende Fix (piholePTR)
Auf dns1:
sudo nano /etc/pihole/pihole.toml
Suche nach piholePTR. Wenn der Eintrag nicht existiert, füge ihn hinzu.
Setze exakt:
piholePTR = "HOSTNAMEFQDN"
Ganz wichtig:
Nicht dns1.pandolin.online.
Nicht PI.HOLE
Nicht irgendetwas „logisches“
Sondern genau dieser String. Warum? Weil Pi-hole sich daraus automatisch den FQDN des Systems zieht. Trägst du hier etwas anderes ein, fällt Pi-hole stumm auf PI.HOLE zurück.
Dienst neu starten
sudo systemctl restart pihole-FTL`
Tests (jetzt zur Abwechselung bitte alle!)
Auf dns1:
nslookup 192.168.1.3 192.168.1.3
nslookup dns1.pandolin.online 192.168.1.3
Und vom Client (explizit):
nslookup google.com 192.168.1.3
nslookup 192.168.1.3 192.168.1.3`
Erwartung ist nun kein pi.hole, nur echte Namen, Logs werden lesbar.
Warum das so wichtig war (und keine reine Kosmetik)
Ohne diesen Fix sehen wir im Failover nicht, welcher Node aktiv ist, sehen Logs aus wie anonymisierte Unfallberichte, baust Du Frust auf, verlierst du Vertrauen in dein eigenes Setup.
Mit diesem Fix erkennen wir DNS-Flüsse sofort, können Probleme einordnen und baust auf einer sauberen Identität auf.
Schritt 6: Hochverfügbarkeit, virtuelle IP
… und warum plötzlich alles kaputt ist, obwohl nichts kaputt ist
Bis hierher haben wir zwei funktionierende DNS-Server. Saubere Namen (Forward & Reverse). Pi-hole + Unbound laufen stabil. Schwer genug wars.
Was wir noch nicht haben, ist Hochverfügbarkeit. Wir habenzwei Server, aber noch keine gemeinsame Identität.
Das Kernproblem ist, ein Client (PC, Handy, Fernseher, etc) merkt sich eine DNS-Adresse und erwartet, dass diese immer antwortet. Er interessiert sich nicht dafür, warum sie gerade nicht antwortet. Wenn wir ihm nun zwei DNS-Adressen geben ist das keine Redundanz sondern eine Einladung zum unkontrollierten Chaos
Was wir brauchen, ist eine Adresse, die immer existiert. Egal, welcher Server dahinter steht.
Jetzt sind wir endlich bei der VIP angekommen, der virtuellen IP.
Das Ziel dieser Etappe wird sein ...
Alle Clients sprechen nur mit 192.168.1.5. Diese IP gehört immer genau einem Server, Wenn dieser Server ausfällt:
- übernimmt der andere automatisch
- ohne Umkonfiguration
- ohne Client-Neustart
- ohne jeden manuellen EIngriff
Wie das technisch funktioniert?
Wir nutzen keepalived. Damit nutzen wir nutzt das VRRP-Protokoll. Das lässt Server untereinander sagen: „Lebst du noch?“ und anhand von Priorität + Gesundheitszustand entscheidet es dann wer die virtuelle IP tragen darf.
Wichtig: keepalived prüft nicht automatisch, ob DNS funktioniert. Das müssen wir ihm beibringen.
Schritt 6.1: keepalived installieren
Auf dns1 und dns2:
sudo apt update &&
sudo apt install -y keepalived
Noch passiert gar nichts. keepalived läuft noch nicht.
Schritt 6.2: Der Healthcheck – ohne den ist alles sinnlos
Das ist einer der wichtigsten Punkte. Wenn wir keepalived nicht sagen, wann DNS „gesund“ ist, passiert Folgendes: Ein Server kann tot sein, keepalived hält trotzdem die VIP. Die Clients laufen ins Leere und wir denke uns "Was für ein komplizierter Mist. Von wegen VIP."
Das ist kein Bug, das ist fehlende Information.
Wir bauen einen eigenen DNS-Gesundheitstest
Auf beiden Servern:
sudo nano /usr/local/bin/check_dns.sh
Inhalt bitte komplett einkopieren:
#!/bin/bash
# Prüft, ob DNS lokal antwortet.
# Wenn nicht -> keepalived gibt die VIP ab.
dig +time=1 +tries=1 @127.0.0.1 google.com >/dev/null 2>&1
exit $?`
Was passiert hier? Wir fragen lokal DNS ab, nicht über das Netzwerk, nicht über die VIP. Wenn das fehlschlägt ist unser DNS kaputt.
Jetzt ausführbar machen:
sudo chmod +x /usr/local/bin/check_dns.sh
Schritt 6.3: keepalived konfigurieren (dns1 = Master)
Jetzt kommt die erste Konfigurationsdatei.
Auf dns1:
sudo nano /etc/keepalived/keepalived.conf
Kompletter Inhalt:
vrrp_script chk_dns {
script "/usr/local/bin/check_dns.sh"
interval 2
fall 2
rise 2
timeout 2
}
vrrp_instance DNS_VIP {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass supersecret
}
virtual_ipaddress {
192.168.1.5/24
}
track_script {
chk_dns
}
}
Was du hier wichtig ist : priority 150 bedeutet dns1 ist bevorzugt. Die virtual_router_id muss auf beiden gleich sein. Dastrack_script, das ist der Healthcheck. Die IP 192.168.1.5 ist unsere VIP.
Schritt 6.4: keepalived konfigurieren (dns2 = Backup)
Auf dns2:
sudo nano /etc/keepalived/keepalived.conf`
Inhalt:
vrrp_script chk_dns {
script "/usr/local/bin/check_dns.sh"
interval 2
fall 2
rise 2
timeout 2
}
vrrp_instance DNS_VIP {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass supersecret
}
virtual_ipaddress {
192.168.1.5/24
}
track_script {
chk_dns
}
}
Deja vu? Einziger Unterschied: state BACKUP und eine niedrigere priority.
Schritt 6.5: keepalived starten
Auf beiden Servern:
sudo systemctl enable --now keepalived`
Jetzt prüfen:
ip a | grep 192.168.1.5`
Erwartung:
Auf dns1 siehst du: inet 192.168.1.5/24 scope global secondary eth0, auf auf dns2: nichts.
So weit so gut.
Und jetzt: der Moment, an dem plötzlich nichts mehr ging
Alles fertig. Dachte ich. Wenn ich jetzt jetzt auf einem Client testete:
nslookup google.com 192.168.1.5
bekam ich den berühntenDNS request timed out.
Und das obwohl die VIP existiert, der- Pi-hole läuft, keepalived läuft und alles andere auch korrekt aussieht.
In dem Moment, das war so gegen 2 Uhr nachts, habe ich Pi-hole verflucht, habe überlegt ob ich alles hinwerfen will oder anfange neu zu installieren. Ich habs nicht getan. Und im Gegensatz zu Windows kann man bei Linux immer alles reparieren!
Das Problem ist NICHT DNS. Es ist ARP.
Die Kurzfassung ist: Netzwerke merken sich „Welche MAC-Adresse gehört zu welcher IP?“
Diese Zuordnung wird gecached.
UniFi-Geräte und Windows sind hier besonders… selbstbewusst.
Wenn die VIP neu erscheint erkennt der Client das nicht zuverlässig,
Anfragen landen im Nirwana, Tiimeouts kommen und mein DNS wirkt „kaputt“, ist es aber nicht.
Die Lösung: Aggressives Gratuitous ARP (GARP)
Wir müssen keepalived mitgeben: „Sag dem Netzwerk mehrfach und möglichst laut, dass diese IP jetzt hier wohnt.“
Schritt 6.6: ARP-Fix in keepalived
Auf beiden Servern in der conf Datei ergänzen.:
sudo nano /etc/keepalived/keepalived.conf`
vrrp_script chk_dns {
script "/usr/local/bin/check_dns.sh"
interval 2
fall 2
rise 2
timeout 2
}
vrrp_instance DNS_VIP {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
garp_master_delay 1
garp_master_repeat 5
garp_master_refresh 10
garp_master_refresh_repeat 2
authentication {
auth_type PASS
auth_pass supersecret
}
virtual_ipaddress {
192.168.1.5/24
}
track_script {
chk_dns
}
}
Danach auf beiden:
sudo systemctl restart keepalived
WICHTIG: Client-Cache leeren (sonst lügt er)
Auf Windows (als Administrator) arp -d * ipconfig /flushdns und danach erneut testen:nslookup google.com 192.168.1.5
Wenn jetzt eine Antwort kommt: Yes. You did it!
Der eigentliche Aha-Moment: Bis hierhin war alles richtig konfiguriert. Der Fehler war nicht logisch, sondern physikalisch. Das Netzwerk wusste nicht, wo diese IP eigentlich lebt.
Schritt 7: Tests, Failover & die DreamWall
… oder: Wann man endlich aufhören darf, alles zu hinterfragen
Wir haben jetzt 2 DNS-Server (dns1, dns2) mit einer virtuellen IP (192.168.1.5). Pi-hole + Unbound laufen stabil. Reverse DNS sauber. keepalived läuft mit Healthcheck. Meine ARP-Probleme sind final geklärt.
Alles fertig?
Jetzt müssen wir beweisen, dass das Ganze nicht nur theoretisch, sondern praktisch hochverfügbar ist. Eine letzte ...
Wichtige Teststrategie!
Wir testen bewusst in Stufen:
- Direkt gegen die VIP
- Vom Client, ohne DHCP
- Vom Client, mit DHCP
- Failover unter Last
- Rückkehr des Masters
Wenn ein Test fehlschlägt, wie immer, nicht weiter. Ursache klären, Fehler beseitigen.
Test 7.1: Direkter Test gegen die virtuelle IP
Auf irgendeinem Rechner im LAN (oder dns1 selbst):nslookup heise.de 192.168.1.5
Erwartung:
- schnelle Antwort, ohne Timeout
Dann:nslookup 192.168.1.5 192.168.1.5
Entscheidend hier ist weniger das Ergebis aber keine Hänger, keine Timeouts.
Wenn das nicht funktioniert heisst es den ARP-Cache prüfen, ip a auf dns1/dns2 prüfen und den keepalived-Status checken-
Test 7.2: Client-Test ohne DNS der Dreamwall (kontrolliert!)
Bevor wir an die DreamWall und das Fundament unserer Welt umbauen gehen, testen wir gezielt einen Client.
Beispiel: Windows
Netzwerkeinstellungen:
- IP: automatisch
- DNS: manuell
192.168.1.5
Dann:nslookup heise.de
Danach im Browser:
- ein paar normale Webseiten
- ein paar Seiten mit viel Werbung wie Chip oder ähnlich
- Pi-hole Dashboard beobachten
Jetzt sollten:
- Queries beim Pi-hole reinkommen
- Clients erscheinen
- Namen sind sauber
Wenn das unwahrscheinlicherweise nicht funktioniert: Nicht an der DreamWall drehen.
Test 7.3: Der eigentliche Härtetest – Failover
Jetzt kommt der Teil, für den wir das alles gebaut haben. The final hour!
Variante A: Dienst stoppen (sauber)
Auf dns1:sudo systemctl stop pihole-FTL
Was jetzt passieren sollte ist dass der check_dns.sh fehlschlägt. Damit senkt keepalived senkt die Priorität und VIP 192.168.1.5 wandert zu dns2.
Prüfen wir das mit ip a | grep 192.168.1.5. Auf dns2 sollte sie jetzt erscheinen.
Variante B: Brutaltest (Stecker ziehen)
Ja. Wirklich. Der Asteroid ist eingeschlagen. Oder das Kind hat am Stecker gespielt. Netzwerkkabel raus oder oder Maschine ausschalten. Bei den Blades ist es wegen PoE das selbe.
Wenn dein Client jetzt weiter surfen kann, keine DNS-Ausfälle zeigt und das Pi-hole-Dashboard auf dns2 weiterläuft besteht unser Failover.
Test 7.4: Rückkehr des Masters
Jetzt dns1 wieder starten:
sudo systemctl start pihole-FTL
Nach kurzer Zeit gewinnt dns1 wieder wegen höherer Priorität, die VIP wandert zurück und dns2 hält sich wieder bereit im Hintergrund. Kontrollierter Wechsel. Ziel erreicht.
Schritt 8 (final): DNS-Verteilung über die UniFi Dream Wall
Ziel:
Alle Clients im Netz nutzen direkt deine hochverfügbare VIP. Die Dream Wall bleibt DHCP-Server. Aber wir zwingen sie dazu, nicht sich selbst als DNS anzubieten, sondern direkt unsere VIP 192.168.1.5 an die Clients zu verteilen.
Warum?
Damit sprechen alle Clients direkt mit unserem Cluster. So sehen wir im Pi-hole Dashboard genau, welches Gerät (TV, Handy, Laptop) welche Anfrage stellt, anstatt dass alles anonym über den Router läuft.
Da muss ich doch noch was einstellen ...
UniFi Network → Networks → Default
DHCP Mode
✅ DHCP Server (bleibt an)
❌ DHCP Relay (aus)
Warum? Die Dream Wall bleibt der einzige DHCP-Master. Pi-hole macht kein DHCP. Punkt.
DNS-Einstellungen im Netzwerk
❌ Auto DNS Server → AUS
✅ Manuelle DNS Server → AN
IPv4 DNS Server: 192.168.1.5
❌ KEIN zweiter DNS
❌ KEIN 8.8.8.8
❌ KEIN 9.9.9.9
Warum so strikt? Mehrere DNS = Clients entscheiden selbst. Clients failovern nicht sauber. Debugging wird unmöglich. Eine VIP ist der Kontrollpunkt. Redundanz passiert hinter dieser IP, nicht davor.
Domain Name (optional, aber empfohlen)
Domain Name: pandolin.online
Warum? Für saubere FQDNs im Netz, konsistente Logs, gleiche Namen intern & extern.

Fazit
Das war ein richtig langer und harter, manchmal trockener Ritt.
Ich bin für euch in jeden Rechen getreten, der im hohen Gras lag.
Was hier steht, ist kein Bastelprojekt mehr.
Es ist:
- souverän
- redundant
- debugbar
- stabil
- und irgendwie langweilig.
Und genau so muss Infrastruktur sein.
Langweilig.
Belastbar.
Nicht der Maserati sondern der VW Passat, der seine 350.000 Kilometer ohne Mucken fährt.
Happy Digital Independence Day 🐧
P.S. Wer hat so lange durchgehalten? Dann ist es Dir vielleicht aufgefallen, NTP habe ich nicht mehr geschafft. Folgt beim nächsten Mal.