Pi-hole: Einrichtung und Konfiguration mit unbound – AdBlocker Teil2

1. unboundPi-hole mit unbound

Im ersten Teil der Artikelserie »AdBlocker« wurde gezeigt, wie man ein Pi-hole in das (Heim-)Netzwerk einer Fritz!Box integriert. Nach der Umsetzung werden Werbung, Tracker, Affiliates, Telemetrie, Malware, Scam etc. zuverlässig herausgefiltert – das Internet wird für Clients im Netzwerk ein Stück sauberer.

Der vorliegende Artikel beschreibt, wie man den rekursiven DNS-Server unbound auf einem Pi-hole konfiguriert. Dadurch wird nicht nur die Abhängigkeit von öffentlichen DNS-Servern aufgehoben, sondern auch die DNS-Abfragen werden schneller beantwortet. Die Konfiguration richtet sich an fortgeschrittene Benutzer – Anfängern empfehle ich, das Setup aus dem ersten Teil zu verwenden.

Dieser Beitrag ist Teil einer Artikelserie:

2. Was wir erreichen wollen

Voraussetzung für die Installation bzw. Konfiguration von unbound ist ein bereits funktionierender Pi-hole, wie er im ersten Teil vorgestellt wurde. Habt ihr dieses Setup umgesetzt, könnt ihr nahtlos mit den folgenden Schritten fortgefahren. Vor der Umsetzung empfehle ich, den ersten Teil noch einmal in Ruhe zu lesen.

Unbound ändert nichts am ursprünglichen Ziel: ausgehende DNS-Anfragen an Werbe- und Tracking-Domains zu blockieren. Wir verzichten jedoch auf den Mittelsmann – den vorgeschalteten DNS-Server – und beseitigen damit die Abhängigkeit von einem Anbieter. Durch die Installation von unbound werden wir sozusagen zu unserem eigenen DNS-Server-Anbieter.

Du kannst den Blog aktiv unterstützen!

Unabhängig. Kritisch. Informativ. Praxisnah. Verständlich.

Die Arbeit von kuketz-blog.de wird vollständig durch Spenden unserer Leserschaft finanziert. Sei Teil unserer Community und unterstütze unsere Arbeit mit einer Spende.

Mitmachen ➡

2.1 Vor- und Nachteile von unbound

Unbound ist ein validierender (DNSSEC), rekursiver DNS-Server, der Anfragen in einem Cache zwischenspeichert. Entwickelt wird die Software von NLnet Labs – der Quellcode ist vollständig auf GitHub verfügbar und steht unter der BSD-Lizenz. Unbound läuft auf allen Linux- und BSD-Distributionen sowie auf macOS. Es ist in allen Standard-Repositories der gängigen Linux-Distributionen enthalten.

Was ändert sich aber durch den Einsatz von unbound auf einem Pi-hole? Diese Frage wird im Folgenden näher beleuchtet. Starten wir mit einem Zitat aus der Pi-hole Dokumentation:

Pi-hole enthält einen DNS-Server zur Zwischenspeicherung und Weiterleitung, der als FTLDNS bekannt ist. Nach Anwendung der Sperrlisten leitet er die von den Clients gestellten Anfragen an konfigurierte Upstream-DNS-Server weiter. Wie jedoch von mehreren Benutzern in der Vergangenheit erwähnt wurde, führt dies zu einigen Bedenken hinsichtlich des Datenschutzes, da sich letztlich die Frage stellt: Wem kann man vertrauen? In letzter Zeit sind immer mehr kleine (und nicht so kleine) DNS-Upstream-Anbieter auf dem Markt aufgetaucht, die mit kostenlosen und privaten DNS-Diensten werben, aber woher weiß man, dass sie ihre Versprechen halten? Richtig, man kann es nicht.

Lasst uns das Problem klar benennen: Es geht um Vertrauen. Wir müssen darauf vertrauen, dass unser DNS-Server-Anbieter unsere DNS-Anfragen nicht aufzeichnet und/oder analysiert. Persönlich halte ich die DNS-Server-Anbieter in der Empfehlungsecke für vertrauenswürdig, möchte aber betonen, dass ich nicht mit absoluter Sicherheit sagen kann, dass keiner dieser Anbieter jemals sein Versprechen bricht und beispielsweise DNS-Anfragen protokolliert.

Mit unbound lösen wir die Abhängigkeit zu einem DNS-Server-Anbieter auf. Daraus ergeben sich folgende Vorteile:

  • Privatsphäre: Unbound wird die Namensauflösung über einen Root-Nameserver starten und sich bis zum zuständigen autoritativen Nameserver »durchfragen«, der den Domainnamen in die zugehörige IP-Adresse übersetzen kann. Wir verzichten also auf einen zentralen DNS-Mittelsmann, der unsere DNS-Anfragen aufzeichnen und/oder analysieren könnte.
  • Geschwindigkeit: Pi-hole selbst hat bereits einen Cache für DNS-Anfragen integriert. Mit unbound und den entsprechenden Konfigurationsparametern (bswp. aggressive-nsec, prefetch, serve-expired etc.) lassen sich die Antwortzeiten abermals minimieren.

Der Verzicht auf einen DNS-Mittelsmann geht allerdings auch mit folgendem Nachteil einher:

  • Keine Verschlüsselung: Anfragen an die Root-Nameserver bzw. autoritativen Nameserver erfolgen unverschlüsselt via UDP/TCP über Port 53. Es besteht also die Möglichkeit, dass jemand die DNS-Anfragen mitliest und auswertet. Um dieses Risiko zu verringern, wird im ersten Teil ein Setup beschrieben, bei dem die DNS-Anfragen via DNS over TLS (DoT) verschlüsselt werden. Diese Möglichkeit können wir im folgenden Setup leider nicht anwenden. Unbound unterstützt zwar DNS over TLS (DoT) und auch DNS over HTTPS (DoH), aber die Root-Nameserver unterstützen diese Protokolle (noch) nicht. Wenn wir also auf einen DNS-Mittelsmann verzichten wollen, müssen wir auch auf die Verschlüsselung unserer DNS-Anfragen verzichten. Der Einsatz von DNSSEC unter unbound stellt aber zumindest sicher, dass die zurückgelieferten Daten echt (Authentizität) und unverändert (Integrität) sind.

Hinweis

In diesem Zusammenhang möchte ich noch einmal an meinen Hinweis im ersten Teil erinnern. Wer wirklich Gefahr läuft, dass sein Surfverhalten mitgelesen und ausgewertet wird, sollte auf den Tor-Browser zurückgreifen und bestimmte Verhaltensregeln beachten.

2.2 Ablauf einer DNS-Abfrage unbound | Pi-hole

Nachfolgend ist der Ablauf einer DNS-Abfrage von unbound in Kombination mit Pi-hole für die Domain kuketz-blog.de dargestellt:

unbound DNS-Request

  • [1] Ein Client fragt den Pi-hole nach der Domain kuketz-blog.de
    • [2] Pi-hole überprüft seinen Cache und antwortet, wenn die zugehörige IP-Adresse bereits bekannt ist
    • [3] Pi-hole überprüft seine Filterliste und antwortet, wenn die Domain gesperrt ist
  • [4] Da keines der beiden Szenarien zutrifft, sendet Pi-hole die Anfrage an den (lokalen) rekursiven DNS-Server – also an unbound
  • [5] unbound sendet die Anfrage nun an einen Root-Nameserver und fragt, wer für die Top-Level-Domain (TLD) .de zuständig ist
  • [6] Der Root-Nameserver antwortet mit einem Verweis auf einen TLD-Server für .de
  • [7] An den TLD-Server sendet unbound anschließend eine Anfrage, wer die Domain kuketz-blog.de verwaltet
  • [8] Der TLD-Server wiederum antwortet mit einem Verweis auf den autoritativen Nameserver für kuketz-blog.de
  • [9] Im letzten Schritt fragt unbound nun den autoritativen Nameserver nach der IP-Adresse für kuketz-blog.de
  • [10] Der autoritative Nameserver übermittelt die IP-Adresse der Domain kuketz-blog.de an unbound
  • [11] unbound gibt die IP-Adresse an Pi-hole weiter, der wiederum dem Client die Antwort auf seine Anfrage mitteilt
  • [12] Der Client bzw. Browser kann nun über die IP-Adresse die Website kuketz-blog.de laden/darstellen

In diesem Ablauf werden drei verschiedene Arten von DNS-Servern benannt: Root-Nameserver, TLD-Nameserver und autoritative Nameserver. Um die Unterschiede zwischen diesen drei Typen besser zu verstehen, lest bitte den Artikel »Welche verschiedenen Typen von DNS-Servern gibt es?«.

Hinweis

Der Ablauf beinhaltet die QNAME Minimisation.

2.3 Verwendete Software/Version

Nachfolgend möchte ich die verwendete Software kurz vorstellen. Insbesondere die Versionsnummern sind von Interesse, da sich die hier beschriebene Installation durch Updates ändern kann.

3. unbound

Wenn die im ersten Teil beschriebene Einrichtung abgeschlossen ist, kann nahtlos mit den folgenden Schritten fortgefahren werden. Die Inbetriebnahme von unbound ist schnell erledigt und besteht aus den folgenden Schritten: Installation, Erstellen einer Konfigurationsdatei, Anpassen der Pi-hole-Konfiguration und Testen des Setups. Die Installationsanleitung für unbound in der Pi-hole Dokumentation ist eine gute Vorlage. Ich habe mich im Folgenden daran orientiert und nur kleine Anpassungen vorgenommen.

3.1 Installation

Zunächst wird unbound mit einem Terminalbefehl installiert:

sudo apt install unbound

Da wir unbound über den Debian-Paketmanager installieren, wird die root.hints automatisch als Abhängigkeit des Pakets dns-root-data installiert. Die root.hints wird dann automatisch vom Paketmanager aktualisiert. Die root.hints wird benötigt, wenn eine Adresse/Domain nicht im Cache gespeichert ist. In diesem Fall muss unbound »ganz oben« am Ursprung beginnen und die Root-Nameserver befragen, um zu wissen, wo die Top-Level-Domain für die entsprechende Adresse/Domain zu finden ist. Wenn das Paket regelmäßig aktualisiert wird, ist kein manuelles Eingreifen erforderlich.

3.2 Konfiguration

Als Vorlage für die unbound-Konfiguration wird die Konfiguration des Pi-hole-Projekts verwendet. Diese zeichnet sich durch folgende Eigenschaften aus:

  • Es werden nur DNS-Anfragen von der lokalen Pi-Hole-Installation beantwortet (auf Port 5335)
  • Beantwortung von UDP- und TCP-DNS-Anfragen
  • Überprüfung der DNSSEC-Signaturen und verwerfen von BOGUS-Domains
  • Sicherheits- und Datenschutzoptimierungen
  • Kompatibel mit IPv4- und IPv6-Netzwerk

Mit folgendem Befehl legen wir eine neue Konfigurationsdatei an:

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

Kopiert den Inhalt und fügt ihn direkt in die eben angelegte Konfigurationsdatei ein:

server:
    # If no logfile is specified, syslog is used
    # logfile: "/var/log/unbound/unbound.log"
    verbosity: 0

    interface: 127.0.0.1
    port: 5335
    do-ip4: yes
    do-udp: yes
    do-tcp: yes

    # May be set to yes if you have IPv6 connectivity
    do-ip6: no

    # You want to leave this to no unless you have *native* IPv6. With 6to4 and
    # Terredo tunnels your web browser should favor IPv4 for the same reasons
    prefer-ip6: no

    # Use this only when you downloaded the list of primary root servers!
    # If you use the default dns-root-data package, unbound will find it automatically
    # root-hints: "/var/lib/unbound/root.hints"

    # Trust glue only if it is within the server's authority
    harden-glue: yes

    # Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
    harden-dnssec-stripped: yes

    # Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes
    # see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
    use-caps-for-id: no

    # Reduce EDNS reassembly buffer size.
    # IP fragmentation is unreliable on the Internet today, and can cause
    # transmission failures when large DNS messages are sent via UDP. Even
    # when fragmentation does work, it may not be secure; it is theoretically
    # possible to spoof parts of a fragmented DNS message, without easy
    # detection at the receiving end. Recently, there was an excellent study
    # >>> Defragmenting DNS - Determining the optimal maximum UDP response size for DNS <<<
    # by Axel Koolhaas, and Tjeerd Slokker (https://indico.dns-oarc.net/event/36/contributions/776/)
    # in collaboration with NLnet Labs explored DNS using real world data from the
    # the RIPE Atlas probes and the researchers suggested different values for
    # IPv4 and IPv6 and in different scenarios. They advise that servers should
    # be configured to limit DNS messages sent over UDP to a size that will not
    # trigger fragmentation on typical network links. DNS servers can switch
    # from UDP to TCP when a DNS response is too big to fit in this limited
    # buffer size. This value has also been suggested in DNS Flag Day 2020.
    edns-buffer-size: 1232

    # Perform prefetching of close to expired message cache entries
    # This only applies to domains that have been frequently queried
    prefetch: yes

    # One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1.
    num-threads: 1

    # Ensure kernel buffer is large enough to not lose messages in traffic spikes
    so-rcvbuf: 1m

    # Ensure privacy of local IP ranges
    private-address: 192.168.0.0/16
    private-address: 169.254.0.0/16
    private-address: 172.16.0.0/12
    private-address: 10.0.0.0/8
    private-address: fd00::/8
    private-address: fe80::/10

Hinweis

Alle unbound-Befehle (mit den Default-Werten) sind beim Debian-Projekt näher erläutert. Da auf dem Pi-hole (Version 5.17.1) in Kombination mit dem offiziellen Raspberry Pi OS Lite (64 Bit) immer noch ein Debian Bullseye läuft, müssen wir uns an der dazugehörigen unbound.conf (unbound Version 1.13.1) für Bullseye orientieren.

Damit Pi-hole das Limit (1232) des EDNS Reassembly Buffers berücksichtigt, wird eine weitere Konfigurationsdatei erstellt:

sudo nano /etc/dnsmasq.d/99-edns.conf

Der Inhalt ist wie folgt:

edns-packet-max=1232

Danach ist die Konfiguration abgeschlossen und unbound kann gestartet werden. Wir werden dies jedoch auf einen späteren Zeitpunkt verschieben und noch weitere Konfigurationseinstellungen vornehmen. Ab hier weiche ich von der unbound Installationsanleitung des Pi-hole-Projekts ab.

3.3 IPv6: do-ip6

In der Konfiguration des Pi-hole-Projekts ist IPv6 standardmäßig deaktiviert. Das bedeutet aber nicht, dass eure IPv6 fähigen Clients keine IPv6 Domains mehr auflösen bzw. aufrufen können. Das funktioniert wunderbar. Der Parameter do-ip6 steuert lediglich das Verhalten von unbound in Bezug auf IPv6:

Enable or disable whether ip6 queries are answered or issued. Default is yes. If disabled, queries are not answered on IPv6, and queries are not sent on IPv6 to the internet nameservers. With this option you can disable the ipv6 transport for sending DNS traffic, it does not impact the contents of the DNS traffic, which may have ip4 and ip6 addresses in it.

Wenn man also möchte, dass unbound DNS-Anfragen über IPv6 an die Nameserver sendet, kann man diese Option aktivieren. Wenn zusätzlich die Option prefer-ip6 aktiviert ist, wird IPv6 gegenüber IPv4 beim Senden von DNS-Anfragen bevorzugt.

Ich persönlich habe beide Parameter der Standardkonfiguration unverändert gelassen, also IPv6 ausgeschaltet. Da diese beiden Parameter immer wieder für Verwirrung sorgen, wollte ich nur kurz darauf eingehen.

3.4 Erweiterung der Konfiguration

Die unbound-Konfiguration des Pi-hole-Projektes für den Pi-hole ist eher konservativ ausgelegt. Die Priorität liegt auf einer funktionierenden Konfiguration. Dies ist verständlich, da zusätzliche Befehle oder Änderungen das Verhalten von unbound negativ beeinflussen können. Die Folge: DNS-Auflösungen funktionieren womöglich nicht mehr sauber und Clients erhalten keine bzw. veraltete IP-Adressen.

Doch bevor ich meine Anpassungen vorstelle, möchte ich zunächst mit einem Irrglauben aufräumen: Viele glauben, dass die erste DNS-Anfrage an eine aufgerufene Domain etwas länger dauern kann, weil unbound die DNS-Anfrage über einen Root-Nameserver startet und sich bis zum zuständigen autoritativen Nameserver »durchfragen« muss, bevor der Domainname in die zugehörige IP-Adresse übersetzt wird. Dies ist zwar grundsätzlich richtig, aber die Annahme, dass eine Domain nach einmaliger Auflösung (Caching) zukünftig immer sofort verfügbar ist, ist falsch.

Jeder Resource Record (RR) einer Domain enthält eine Information, die als Time to live (TTL) bezeichnet wird. Für eine Domain gibt die TTL jedes Resource Records an, wie lange (in Sekunden) eine soeben erfolgte Namensauflösung voraussichtlich noch mindestens gültig bleibt. Während dieses Zeitraums kann das DNS-Caching verwendet werden. Nach Ablauf der TTL sollte der Client die entsprechende Namensauflösung verwerfen und bei Bedarf wiederholen. Das bedeutet: Sobald der TTL-Wert für eine Domain abgelaufen ist, wird unbound sich erneut bis zum autoritativen Nameserver »durchfragen«, um einen Domainnamen in die zugehörige IP-Adresse zu übersetzen. Die Annahme, dass also lediglich die »erste« DNS-Anfrage bei Aufruf einer Domain länger dauern kann, ist falsch. Nachfolgend ein Beispiel.

Mit dig können wir uns den TTL-Wert für eine Domain ausgeben lassen. Das funktioniert, wenn wir den autoritativen Nameserver einer Domain kennen:

dig +nocmd +noall +answer @root-dns.netcup.net www.kuketz-blog.de

Die Ausgabe ist wie folgt:

www.kuketz-blog.de.   86400   IN    CNAME    kuketz-blog.de.
kuketz-blog.de.       86400   IN    A        46.38.242.112

Der zweite Wert gibt den TTL-Wert der Domain zurück. Im Beispiel 86400. 86400 Sekunden sind 24 Stunden. Nach 24 Stunden wird unbound also den Cache verwerfen und die Domain erneut in die zugehörige IP-Adresse auflösen. Schauen wir uns eine weitere Domain an:

dig +nocmd +noall +answer @pns101.cloudns.net www.spiegel.de

Die Ausgabe ist wie folgt:

www.spiegel.de.       300     IN    CNAME    aacfb9d106f4.link11.de.

Der TTL-Wert der Spiegel-Domain beträgt 300 Sekunden, also 5 Minunten. Bereits nach 5 Minuten wird unbound erneut die IP-Adresse auflösen.

Glücklicherweise bietet unbound einige Parameter, um das Caching-Verhalten zu beeinflussen und den TTL-Wert für Domains zu überschreiben. Persönlich habe ich nachfolgende Befehle hinzugefügt, d.h. die Pi-hole-unbound-Konfiguration erweitert. Die Konfiguration läuft bei mir seit einigen Monaten reibungslos. Ich kann jedoch nicht vollständig ausschließen, dass die Ergänzungen möglicherweise Probleme verursachen werden. Daher möchte ich erneut darauf hinweisen, dass dieser Beitrag sich an fortgeschrittene Anwender richtet, die mit möglichen Problemen umgehen können.

Mit dem folgenden Befehl rufen wir die bereits erstellte Konfigurationsdatei auf:

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

Anschließend werden die folgenden Parameter ergänzt:

## Performance
# More cache memory, rrset=msg*2 | Default: 4m, 4m
msg-cache-size: 32m
rrset-cache-size: 64m
# Time  to  live [minimum|maximum] for RRsets and messages in the cache | Default: 0, 86400
cache-min-ttl: 3600
cache-max-ttl: 86400
# Serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish | Default: no, 0
serve-expired: yes
serve-expired-ttl: 86400
# Fetch DNSKEYs earlier (DNSSEC): More cpu usage, less latency | Default: no
prefetch-key: yes
# Helps to reduce the query rate towards targets that get a very high nonexistent name lookup rate | Default: no
aggressive-nsec: yes

## Privacy | Default: no, no
hide-identity: yes
hide-version: yes

Auf einige Parameter möchte ich nachfolgend kurz eingehen, damit wir verstehen, was sie bewirken und wie dadurch die Domainauflösung für Clients beschleunigt werden kann:

  • prefetch [yes]: Unbound versucht mit prefetch, einen Eintrag im Cache zu aktualisieren, nachdem die erste Antwort an den Client gesendet wurde. Wenn ein Client kurz vor dem Ende des TTL eine Anfrage für eine Domain stellt und ein zwischengespeicherter Eintrag vorhanden ist, wird dieser an den Client zurückgegeben. Gleichzeitig startet unbound die Auflösung der Domain und ermittelt die aktuelle IP-Adresse. Für oft besuchte Websites/Domains versucht unbound sogar, den Cache auf dem neuesten Stand zu halten.
  • serve-expired [yes]: Wenn diese Option aktiviert ist, versucht unbound, (alte) Informationen aus dem Cache auszuliefern, ohne auf den Abschluss der eigentlichen DNS-Auflösung zu warten. Die eigentliche Antwort landet später im Cache – unbound aktualisiert die Information also im Hintergrund. Wie lange unbound Informationen aus dem Cache ausliefert, wird mit dem Parameter serve-expired-reply-ttl beeinflusst.
  • serve-expired-ttl [86400]: Begrenzt die Zustellung von abgelaufenen Antworten auf die konfigurierten Sekunden. Diese Option gilt nur, wenn serve-expired aktiviert ist. Ein empfohlener Wert gemäß RFC 8767 liegt zwischen 86400 (1 Tag) und 259200 (3 Tage).

Zusammengefasst kann man sich das wie folgt vorstellen: Unbound wird (abgelaufene) Antworten aus dem Cache priorisieren, den Cache für häufig besuchte/beliebte Domains auf dem neuesten Stand halten und für den Fall, dass ein abgelaufener Datensatz zugestellt werden muss (bspw. seltene Abfrage, Problem mit vorgelagerter Auflösung), sicherstellen, dass der Datensatz nicht älter als die angegebene Grenze (86400) ist.

Übrigens verwenden wir den Parameter cache-min-ttl (3600), um sicherzustellen, dass eine Domain einen TTL-Wert von mindestens 3600 Sekunden (60 Minuten) hat. Wenn das Minimum greift, werden die Daten länger als vom Domaininhaber beabsichtigt zwischengespeichert, sodass weniger Abfragen zum Nachschlagen der Daten erfolgen.

4. Anpassung Pi-hole

Nach der unbound-Konfiguration ist eine Anpassung über das Webinterface des Pi-hole erforderlich. Wir geben folgende Adresse in den Browser ein und melden uns an:

192.168.50.5/admin

Unter Settings -> DNS nehmen wir folgende Einstellungen vor:

  • Alle Häkchen (falls vorhanden) bei den DNS-Servern in der linken Ansicht entfernen
  • Custom 1 (IPv4): 127.0.0.1#5335
  • Custom 3 (IPv6): entfernen

Pi-hole Upstream-DNS-Server: unbound

Anschließend wird unten auf der Seite Use DNSSEC angekreuzt.

Nach einem Klick auf Save ist euer Pi-hole in Kombination mit unbound fast einsatzbereit. Wir müssen nur noch eine Debian-Bullseye-Eigenheit anpassen.

5. Debian-Fix

Debian Bullseye+ Releases installieren automatisch ein Paket namens openresolv mit einer Konfiguration, die zu unerwartetem Verhalten in Kombination mit dem Pi-hole und unbound führt. Der unbound-resolvconf-Service weist resolvconf an, unbound als Nameserver in die Datei /etc/resolv.conf einzutragen – allerdings nur mit 127.0.0.1 ohne Angabe des benötigten Ports 5335. Lokale Dienste und Prozesse verwenden die Konfigurationsdatei, um den DNS-Server zu ermitteln. Der fehlende Port führt dazu, dass die DNS-Anfragen unbeantwortet bleiben. Dieser Konfigurationsfehler kann folgendermaßen behoben werden.

Der unbound-resolvconf-Service wird deaktiviert:

sudo systemctl disable --now unbound-resolvconf.service

Verhindert die Erstellung einer resolvconf_resolvers.conf für unbound, wenn resolvconf vom System/einem Prozess aufgerufen wird:

sudo sed -Ei 's/^unbound_conf=/#unbound_conf=/' /etc/resolvconf.conf 
sudo rm /etc/unbound/unbound.conf.d/resolvconf_resolvers.conf

Danach haben wir es geschafft. Nach einem Neustart von unbound ist Pi-hole mit unbound einsatzbereit:

sudo service unbound restart

6. Funktionsprüfung

Wenn alle Arbeiten abgeschlossen sind, kann die Überprüfung erfolgen, ob die Kombination aus Pi-hole und unbound einwandfrei funktioniert. Zunächst wird geprüft, ob die DNSSEC-Valdierung funktioniert:

dig fail01.dnssec.works @127.0.0.1 -p 5335

Ausgabe:

; <<>> DiG 9.16.44-Debian <<>> fail01.dnssec.works @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 14820
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;fail01.dnssec.works.		IN	A

;; Query time: 0 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Tue Oct 10 12:40:46 CEST 2023
;; MSG SIZE  rcvd: 48

Als Status wird ein SERVFAIL zurückgegeben und die IP-Adresse fehlt ebenfalls. Jetzt nochmal mit einer Domain, bei der DNSSEC korrekt validiert werden kann:

dig dnssec.works @127.0.0.1 -p 5335

Ausgabe:

; <<>> DiG 9.16.44-Debian <<>> dnssec.works @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6033
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
dnssec.works.		21418	IN	A	5.45.107.88

;; Query time: 0 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Tue Oct 10 12:43:44 CEST 2023
;; MSG SIZE  rcvd: 57

Als Status wird NOERROR und ebenso eine IP-Adresse (5.45.107.88) zurückgegeben. Das ad-Flag signalisiert, dass unbound die Antwort für authentisch hält bzw. die Validierung via DNSSEC funktioniert. Um zu verstehen, wie die DNSSEC-Validierung auf dem Pi-hole funktioniert und wie die Log-Einträge zustande kommen, empfiehlt sich ein Blick in den Artikel »Understanding DNSSEC validation using Pi-hole’s Query Log«.

Unbound beherrscht ebenfalls QNAME Minimisation (qname-minimisation [yes]) – das kann wie folgt geprüft werden:

dig txt qnamemintest.internet.nl +short @127.0.0.1 -p 5335

Ausgabe:

a.b.qnamemin-test.internet.nl.
"HOORAY - QNAME minimisation is enabled on your resolver :)!"

Von einem Linux-Client aus könnt ihr noch folgende Befehle für einen Test absetzen. Ihr müsst die IP-Adresse 192.168.50.5/fd00::a41a:eae7:9fd6:2f8c mit der eures Pi-holes ersetzen:

  • IPv4 + UDP-Request: dig @192.168.50.5 example.com +udp
  • IPv4 + TCP-Request: dig @192.168.50.5 example.com +tcp
  • IPv4 + UDP-Request + IPv6-Domain: dig @192.168.50.5 -t AAAA example.com
  • IPv6 + UDP-Request + IPv6-Domain: dig -6 @fd00::a41a:eae7:9fd6:2f8c -t AAAA example.com

Ausgabe von dig -6 @fd00::a41a:eae7:9fd6:2f8c -t AAAA example.com:

; <<>> DiG 9.18.19-1~deb12u1-Debian <<>> -6 @fd00::a41a:eae7:9fd6:2f8c -t AAAA example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35276
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
example.com.		86400	IN	AAAA	2606:2800:220:1:248:1893:25c8:1946

;; Query time: 232 msec
;; SERVER: fd00::a41a:eae7:9fd6:2f8c#53(fd00::a41a:eae7:9fd6:2f8c) (UDP)
;; WHEN: Tue Oct 10 13:09:44 CEST 2023
;; MSG SIZE  rcvd: 68

7. Logging

Standardmäßig protokolliert unbound Fehlermeldungen in der Protokolldatei /var/log/syslog. Insgesamt kennt unbound sechs verschiedene Logging-Stufen:

  • Stufe 0 bedeutet keine Details, nur Fehler
  • Stufe 1 liefert Betriebsinformationen
  • Stufe 2 liefert detaillierte Informationen zum laufenden Betrieb
  • Ebene 3 liefert Informationen auf Abfrage-Ebene
  • Ebene 4 liefert Informationen auf Algorithmenebene
  • Ebene 5 protokolliert Clients bei Cache-Fehlern

Sollte es aufgrund von Fehlern oder aus anderen Gründen notwendig sein, den Logging-Level zu erhöhen, so orientiert euch einfach an der Pi-hole-unbound-Konfiguration, das dort gut beschrieben ist.

8. Fazit

In diesem Artikel wurde gezeigt, wie man ein Pi-hole mit unbound konfiguriert. Damit wird einerseits die Abhängigkeit von öffentlichen DNS-Servern aufgehoben und andererseits werden DNS-Anfragen für Clients durch die Anpassung einiger unbound-Parameter (deutlich) schneller beantwortet. Diese Unabhängigkeit geht derzeit leider noch mit unverschlüsselten DNS-Anfragen (via UDP/TCP) einher, da die Root-Nameserver selbst Protokolle wie DNS over TLS (DoT) und auch DNS over HTTPS (noch) nicht unterstützen.

Im nächsten Teil der Artikelserie wird AdGuard Home auf einem Raspberry Pi eingerichtet. Die Funktionsweise von Pi-hole und AdGuard Home ist ähnlich, es gibt jedoch kleine Unterschiede, die je nach persönlichen Vorlieben die eine oder andere Lösung bevorzugen lassen.

Über den Autor | Kuketz

Mike Kuketz

In meiner freiberuflichen Tätigkeit als Pentester / Sicherheitsforscher (Kuketz IT-Security) schlüpfe ich in die Rolle eines »Hackers« und suche nach Schwachstellen in IT-Systemen, Webanwendungen und Apps (Android, iOS). Des Weiteren bin ich Lehrbeauftragter für IT-Sicherheit an der Dualen Hochschule Karlsruhe, sensibilisiere Menschen in Workshops und Schulungen für Sicherheit und Datenschutz und bin unter anderem auch als Autor für die Computerzeitschrift c’t tätig.

Der Kuketz-Blog bzw. meine Person ist regelmäßig in den Medien (heise online, Spiegel Online, Süddeutsche Zeitung etc.) präsent.

Mehr Erfahren ➡

SpendeUnterstützen

Die Arbeit von kuketz-blog.de wird zu 100% durch Spenden unserer Leserinnen und Leser finanziert. Werde Teil dieser Community und unterstütze auch du unsere Arbeit mit deiner Spende.

Folge dem Blog

Wenn du über aktuelle Beiträge informiert werden möchtest, hast du verschiedene Möglichkeiten, dem Blog zu folgen:

Bleib aktuell ➡


Diskussion

Ich freue mich auf Deine Beteiligung zum Artikel

HilfeWenn du Ergänzungen oder konkrete Fragen zum Beitrag hast, besuche das offizielle Forum. Dort kann der Beitrag diskutiert werden. Oder besuche den Chat, um dein Anliegen zu besprechen. zur Diskussion ➡

Abschließender Hinweis

Blog-Beiträge erheben nicht den Anspruch auf ständige Aktualität und Richtigkeit wie Lexikoneinträge (z.B. Wikipedia), sondern beziehen sich wie Zeitungsartikel auf den Informationsstand zum Zeitpunkt des Redaktionsschlusses.

Kritik, Anregungen oder Korrekturvorschläge zu den Beiträgen nehme ich gerne per E-Mail entgegen.