Adguard Home oder Pi-Hole?

Das Blocken von unerwünschter Werbung oder schäbigen Trackern ist für viele Menschen ein Grundbedürfnis geworden. Mittel und Möglichkeiten gibt es daher in Hülle und Fülle. Wer zu Hause einen Raspberry Pi herumstehen hat oder einen leistungsstarken Homeserver sein Eigen nennen kann, sollte sich mit DNS-Sinkholing auseinandersetzen.

Hierbei werden die DNS-Einträge zu Werbenetzwerken, bekannten Malwareschleudern oder Analysetools schlicht und ergreifend nicht aufgelöst. Marktführer in diesem Bereich sind Adguard Home und Pi-Hole. Beide Lösungen sind kostenfrei und können auf so gut wie jeder Linuxdistribution installiert werden. Auch Container-Images stehen zum Download bereit.

Hier nehmen sich beide Open-Source-Projekte nichts. Dem ist aber nicht in jedem Punkt so. Welche Lösung hat am Ende also die Nase vorn und kommt deshalb bei mir und meiner Community zum Einsatz? In diesem Beitrag erfährst du es. Außerdem werde ich noch kurz darauf eingehen, wie du ein hochverfügbares DNS-Cluster bauen kannst. Ohne Namensauflösung bist du schließlich offline.

Welche Lösung ist besser?

In der grundlegenden Arbeitsweise unterscheiden sich beide Produkte nicht. Man kann mit ihnen fertige Filterlisten nutzen und zusätzlich noch benutzerdefinierte Filterregeln erstellen. Ebenfalls können beide Services zusätzlich als DHCP-Server agieren. Auch in puncto DNS-SEC gibt sich keine Lösung die Blöße. Wie so oft in der Informatik findet man die Unterschiede etwas versteckter unter der Haube.

So kann der AdGuard Home beispielsweise ohne Root-Rechte ausgeführt werden. Des Weiteren werden hier DNS over TLS wie auch DNS over HTTPS unterstützt. Die Anfragen werden dabei sowohl lokal als auch ins Internet verschlüsselt übertragen. Gesagt sei an dieser Stelle aber gleich, dass man für verschlüsselte DNS-Requests im LAN ein valides SSL-Zertifikat benötigt.

Darüber hinaus bietet der Adguard Home noch ein paar nette Features wie das Erzwingen der sicheren Suche in Google, Bing oder DuckDuckGo. Außerdem kann man in der Weboberfläche mit einem einzigen Klick soziale Netzwerke, Shopping-Seiten und andere große Dienste blocken. Bei der Benutzerfreundlichkeit liegt Adguard Home also leicht vorne.

Im Großen und Ganzen sind beide Lösungen empfehlenswert. Ich selbst habe bis Anfang des Jahres Pi-Hole genutzt. Da ich aber meine DNS-Anfragen lieber verschlüsselt ins Internet senden möchte, bin ich auf Adguard Home umgestiegen. Dank der kostenlos erhältlichen Let’s Encrypt Zertifikate sind inzwischen sogar meine internen DNS-Anfragen chiffriert. Sicherheit geht bei mir eben vor.

Alle Vor- als auch Nachteile der beiden DNS-Adblocker lassen sich in einer Tabelle am besten vergleichen. Aufgrund dessen habe ich zum Abschluss dieser Passage noch eine solche Übersicht erstellt:

FeaturePi-HoleAdGuard Home
Blockieren von Werbung, Trackern & Malware
Blocklisten erstellen & anpassen
Integrierter DHCP-Server
Verschlüsselte externe und interne DNS-Anfragen
Sichere Suche erzwingen
Ausführbar ohne Root-Rechte
Eigene DNS-Einträge anlegen
Konfiguratioinen für bestimmte Clients

Wie kann man ein Cluster bauen?

Namensauflösung ist ein elementarer Dienst in jedem Netzwerk. Fällt dieser aus, kann man beispielsweise nicht mehr im Internet surfen oder erreicht gar die eigenen Geräte im lokalen Netz nicht mehr. Deshalb sollte man nach Möglichkeit immer ein DNS-Cluster sein Eigen nennen können. Meist ist ja gar kein plötzlich auftretendes Hardware- oder Softwareproblem Schuld am DNS-Ausfall.

Gerade Heimanwender vergessen den Punkt Updates ganz gerne bei ihren Überlegungen. Eine Aktualisierung des Kernels kann beispielsweise zu einem Reboot des Servers führen. Manchmal kann ein Update des gesamten Systems auch schiefgehen und der DNS-Dienst lässt sich einfach nicht mehr starten. In diesem Moment ist die Not groß. Abhilfe schafft hier ein DNS-Cluster.

Damit ist allerdings nicht gemeint, dass man einfach 2 Instanzen mit den gleichen Einstellungen installiert und deren IPs in seinen Clients einträgt. Sollte eine der beiden Maschinen nämlich Probleme machen, funktioniert die Namensauflösung wieder nicht. Leider werden bei mehreren eingetragenen DNS-Servern nicht mal die Anfragen gleichmäßig verteilt.

Selbstredend prüft ein Client dann auch nicht, ob einer der DNS-Server offline ist. Im eigenen Netzwerk muss diese Funktion also selbst bereitgestellt werden. Das Zauberwort hierfür lautet Loadbalancer-Pärchen. Das mag für viele erstmal fremd und noch dazu kompliziert klingen. Dem ist aber zum Glück nicht so. Wie ich mein Adguard-Home-Cluster betreibe, erfährst du im Folgenden.

2 Loadbalancer + 2 DNS-Server = Hochverfügbarkeit

Die Zwischenüberschrift verrät dir natürlich schon, wie man im Handumdrehen ein funktionierendes DNS-Cluster mit Pi-Hole oder Adguard Home umsetzen kann. Ich selbst bin dabei so simpel wie nur möglich vorgegangen. Ich habe einfach 2 DNS-Instanzen auf Basis von Rocky 9 und Adguard Home in Betrieb genommen. Auf beiden Servern sind alle Einstellungen dabei vollends identisch.

Wer hier eine Synchronisation umsetzen möchte, kann mit Tools wie lsyncd arbeiten. Darauf habe ich bei mir aber verzichtet, da ich einfach kein Einsatzszenario dafür habe. Wer zum Beispiel eine große Menge eigener DNS-Records im Einsatz hat, sollte sich durchaus Gedanken über eine automatisierte Synchronisation machen. DNS-Zonen-Transfers gibt es nämlich nicht als Feature.

# Installation von Adguard Home:
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v

# Einrichtung von Iptables:
yum -y install iptables iptables-services

vi /etc/sysconfig/iptables

-A Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
-A Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 853 -j ACCEPT
-A Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3000 -j ACCEPT

systemctl enable --now iptables.service

# Implementierung von Lego:
wget https://github.com/go-acme/lego/releases/download/v4.10.2/lego_v4.10.2_linux_386.tar.gz
tar -xzf lego_v4.10.2_linux_386.tar.gz -C /usr/local/bin

Jeder andere ist mit dem Aufsetzen der DNS-Server an diesem Punkt aber fertig. Etwas länger dürfte nun noch die Installation der beiden Loadbalancer ausfallen. Da hier nicht nur mit dem TCP-Protokoll, sondern auch mit UDP-Paketen gearbeitet wird, habe ich mich für 2 Nginx-Server entschieden. Die Konfiguration ist dabei wieder sehr banal gehalten.

Jeglicher Traffic an die Ports 53, 443 sowie 853 wird dabei an die DNS-Server weiter geleitet. Um jetzt noch die Hochverfügbarkeit zwischen den beiden Loadbalancern sicherstellen zu können, braucht es noch eine VIP bzw. Floating IP. Umgesetzt habe ich dies mittels Keepalivd. Ein kleines Bash-Skript überwacht dabei, ob es einen Nginx-Prozess gibt. Ist dem nicht so, wird Keepalived gestoppt.

Damit kann der Secondary-Loadbalancer die VIP nutzen und es kommt damit zu keiner Störung beim DNS-Dienst. Weiterhin wird auch noch überwacht, ob ein Backend-Server vollends ausgefallen ist. Kann keine Verbindung auf den jeweiligen Ports hergestellt werden, wird der entsprechende DNS-Server ausgeschlossen und erhält keine weiteren DNS-Anfragen mehr.

# Einrichtung von Iptables auf beiden Servern:
yum -y install iptables iptables-services

vi /etc/sysconfig/iptables

-A Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
-A Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 853 -j ACCEPT
-A Firewall-1-INPUT -p vrrp -j ACCEPT

systemctl enable --now iptables.service

# Installation von Nginx auf beiden Instanzen:

# Repo-Datei ertellen, um die neueste Nginx-Version nutzen zu können:
vi /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

# Nginx-Repo aktivieren:
yum-config-manager --enable nginx-stable

# Nginx installieren:
dnf install nginx -y

Nginx starten und in den Autostart packen:
systemctl enable --now nginx

# Loadbalancer-Konfiguration vornehmen:
vi /etc/nginx/nginx.conf

worker_processes 2;

stream {
    upstream dns_53 {
        # IP-Adressen der beiden DNS-Server:
        server 1.2.3.4:53 max_fails=3 fail_timeout=60s;
        server 1.2.4.5:53 max_fails=3 fail_timeout=60s;
    }
    server {
        listen 0.0.0.0:53 udp;
        listen 0.0.0.0:53;
        proxy_pass dns_53;
    }

     upstream dns_853 {
         # IP-Adressen der beiden DNS-Server:
         server 1.2.3.4:853 max_fails=3 fail_timeout=60s;
         server 1.2.4.5:853 max_fails=3 fail_timeout=60s;
     }
     server {
         listen 0.0.0.0:853;
         proxy_pass dns_853;
     }

}

Nginx-Konfiguration prüfen:
nginx -t

Nginx neuladen:
systemctl reload nginx

# Installation von Keepalived:
dnf install keepalived -y

# Konfiguration von Keepalived:
vi /etc/keepalived/keepalived.conf

# Konfiguration für den Primary-Loadbalancer:

! Configuration File for keepalivedglobal_defs {
...
}vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2
    weight 50
}vrrp_instance VI_1 {
    state MASTER
    interface ens18 # Bitte noch anpassen
    virtual_router_id 50
    priority 110
    advert_int 1
    virtual_ipaddress {
	1.3.5.7/24
    }
    track_script {
        check_nginx
    }
}

# Konfiguration für den Secondary-Loadbalancer:

! Configuration File for keepalivedglobal_defs {
...
}vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2
    weight 50
}vrrp_instance VI_1 {
    state BACKUP
    interface ens18 # Bitte noch anpassen
    virtual_router_id 50
    priority 100
    advert_int 1
    virtual_ipaddress {
	1.3.5.7/24
    }
    track_script {
	check_nginx
    }
}

# Skript zum Prüfen, ob der Nginx-Dienst läuft:
vi /etc/keepalived/check_nginx.sh

#!/bin/sh

if [ -z "`/bin/pidof nginx`" ]; then
	systemctl stop keepalived.service
	exit 1
fi

# Das Skript ausführbar machen:
chmod +x /etc/keepalived/check_nginx.sh

# Keepalived starten und in den Autostart packen
systemctl enable --now keepalived

Wer im Heimnetzwerk DNS over TLS vernünftig nutzen möchte, braucht natürlich noch valide Zertifikate für die Strecke zwischen Client und eigenen DNS-Servern. Diese kann man sich beispielsweise mit den Tools Acme.sh oder Lego generieren lassen. Wichtig zu wissen ist hierbei noch, dass man eine eigene Domain und das natürlich mit unterstützter DNS-API braucht.

Nur so kann man sich kostenlose Let’s Encrypt Zertifikate über eine DNS-Challenge ausstellen lassen. Dabei wird ein TXT-Eintrag in der DNS-Zone des autoritären Name-Servers hinterlegt, um zu beweisen, dass man der Besitzer der jeweiligen Domain ist. Aber um die Ausstellung von kostenlosen Let’s Encrypt Zertifikaten soll es in diesem Beitrag nicht gehen.

Loadbalancer sind sinnvoll, aber nicht zwingend notwendig

Viele von euch werden sich beim Lesen sicherlich gedacht haben, dass man Keepalived auch direkt auf den beiden DNS-Servern installieren kann. Und das ist auch absolut richtig. Da im Heimgebrauch der Punkt Skalierbarkeit keine allzu große Rolle spielt und Hardware teuer ist, kann man ruhig so vorgehen. Ich selbst brauche allerdings in Zukunft öfter mal Loadbalancer für Testaufbauten.

Daher habe ich diesen Weg genutzt. Netter Nebeneffekt ist dabei noch, dass beide Instanzen Anfragen erhalten und so kein DNS-Server ungenutzt herumsteht. Da die beiden Loadbalancer aber mittels NAT arbeiten, sehe ich die IP-Adressen der anfragenden Clients nicht. Abhilfe würde hier der Einsatz von Direct Server Return (DSR) schaffen. Hier ist dann aber mehr Konfigurationsaufwand nötig.

Von Fabian Wüst

Er ist leidenschaftlicher Open-Source-Benutzer und ein begeisterter Technologie-Enthusiast. Als kreativer Kopf hinter Homelabtopia bringt Fabian hier seine umfangreiche Erfahrung als Linux-Admin ein. Um sicherzustellen, dass du aus seinen Beiträgen den größtmöglichen Nutzen ziehen kannst, führt er ausgiebige Tests durch und errichtet dafür immense Setups.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert