Software

oDroid XU4 / Raspberry Pi: PiHole mit DNS-over-TLS in Docker

PiHole Logo

I have translated the article for the official odroidmagazine to english: https://magazine.odroid.com/article/pihole/

Seitdem Docker den Support für den Raspberry Pi und somit sämtliche ARM-Prozessoren aufgenommen hat, ist es ein leichtes Software auf unseren geliebten günstigen Single-Board-Computern zu deployen. So kam es, dass ich vor kurzem auf das DNS-over-TLS (DoT) Docker Image von qdm12 auf GitHub gestoßen bin. Ein DNS-„Proxy“, der DNS Anfragen annimmt und sie verschlüsselt bei Google (8.8.8.8), CloudFlare (1.1.1.1) oder anderen DoT-Servern abfragt. Dies ließ sich auch ratzfratz auf meinem oDroid XU4 und Raspberry Pi 3 einrichten (zwei Geräte, dass falls mal ein Gerät ausfällt, das Internet zuhause problemlos funktioniert). Kurz noch die DNS-Server der Fritzbox auf die beiden IPs der Geräte eingestellt und schon waren die DNS-Abfragen meines Heimnetzes verschlüsselt und gingen nicht mehr im Klartext durch meine Leitung. Während ich mich mit dem Thema DNS beschäftigte, bin ich dann auch noch auf PiHole (Docker Image) gestoßen. Ein DNS-Server, der DNS-Anfragen beantwortet, außer sie gehen an Werbe-Server. Somit kann man praktisch auf unterster Ebene Ad- und Tracking-Blocking bewerkstelligen, z.B. auch für Geräte wo sich keine AdBlocker installieren lassen. Beides kombiniert, PiHole mit DNS-over-TLS, ergibt, durch das Deployment auf zwei Geräten, ein ausfallsicheres, verschlüsseltes, werbefreies und trackingfreies DNS-Setup für die ganze Familie. In diesem Beitrag möchte ich einmal kurz erklären wie man sich dieses aufbaut. Dieses Tutorial richtet sowohl an mein Stammpublikum, Fans vom oDroid XU4, als auch Raspberry Pi Benutzer, da das Setup identisch ist.

 

Docker installieren

Die Installation von Docker und Docker-Compose ist kinderleicht. Öffnet eine SSH-Verbindung und gebt folgende Befehle ein:

Docker-Compose ist für die Orchestrierung von mehreren Docker-Containern zuständig und vereinfacht diese stark.

 

PiHole und DoT-Proxy installieren

Haben wir Docker und Docker-Compose installiert, können wir uns auch schon an’s Eingemachte begeben. Wir werden einen PiHole und zwei DNS-over-TLS Server starten. Ich habe die DoT-Server auf verschiedene DNS-Upstream Server gerichtet, sodass einer bei Cloudflare die Anfragen stellt und der andere beim Google Public DNS. Beide haben eine Verfügbarkeit zwischen 99% und 99,99%. Solange kein DNS-Resolver eine Uptime von 100% gewährleisten kann, würde ich also jedem empfehlen immer zwei Anbieter zu nutzen. Das Docker-Image von qdm12 bietet neben beiden erwähnten auch noch quad9, quadrant und cleanbrowsing an. Ansonsten kann man sich gerne durch die entrypoint.sh wühlen und dort eigene Provider eintragen.

Wir klonen also erstmal das Git-Repository vom DoT-Server und richten diesen ein. Wenn das läuft werden wir PiHole mit in die docker-compose.yml integrieren.

In der docker-compose.yml könnt ihr nun die Einstellungen anpassen. Unter anderem würde ich dazu raten BLOCK_MALICIOUS auf off zu stellen, da der mir nach meinem Geschmack zu viel wegblockt. VERBOSITY habe ich auf 0 gesetzt. Und bei provider habt ihr wie gesagt die Möglichkeit zwischen google, cloudflare, quad9, cleanbrowsing und quadrant zu wählen. Einen genaueren Einblick zu den Einstellmöglichkeiten findet man auf der README Seite des Git Repos. Anschließend kann man mit docker-compose up --build #optional -d um den Prozess in den Hintergrund zu schieben den Compose-Stack builden und starten. Wenn Änderungen an den Konfig-Files vorgenommen worden sind, würde ich immer den Stack mit --build starten. Ansonsten reicht docker-compose up -d zum hochfahren und  docker-compose down  zum herunterfahren. Wie testen wir jetzt, ob der DNS-Server funktioniert? Dazu gibt es das kleine Tool dig:

der Befehl sollte dann sowas zurückgeben:

Ihr habt es soweit geschafft? Sehr gut! Dann machen wir aus einem DoT-Server nun zwei und fügen noch PiHole hinzu. Der Einfachheit halber zeige ich euch erstmal mein docker-compose.yml File und werde anschließend erklären, was ich da genau mache. Mein docker-compose.yml File:

Es sind viele Änderungen, deshalb empfehle ich euch euer docker-compose.yml einfach mit meiner zu überschreiben. Zu aller erst solltet ihr in Zeile 47 die IP eures Gerätes angeben, unter dem PiHole erreicht werden kann. Mit ip route get 1.1.1.1 | awk '{print $NF; exit}' könnt ihr schnell herausfinden, welche dies ist (Quelle: AskUbuntu.com). Anschließend unter Zeile 51 das Passwort für das Web Interface von PiHole festlegen.

Was machen wir da nun genau? Um die beiden DoT-Server für PiHole erreichbar zu machen, erstellen wir ganz unten eine Network-Bridge. Diese sorgt dafür, dass wir den einzelnen Containern feste IP Adressen zuweisen können. Docker handhabt das normalerweise so, dass die Container sich immer untereinander mit den Container-Namen erreichen können. DNS Server wie dnsmasq von PiHole kennen aber Upstream-Server mit Domain-Namen nicht, sondern möchte selbstverständlich IP Adressen. Wie sollte er diese denn die Domains auch auflösen? Also den Container fixe IPs geben, easy. Diese legen wir in Zeile 49 und 50 als Upstream-Server für PiHole fest. In Zeile 34 und 35 legen wir die DNS-Server des Containers selber fest, die z.B. beim hochfahren der Prozesse genutzt werden. An erster Stelle muss immer 127.0.0.1 stehen, an zweiter kann ein beliebiger stehen. Ich habe dort die IP meiner Fritzbox.

In Zeile 53 und 54 mounten wir noch die Konfig-Ordner von PiHole auf unserem Hostsystem, damit diese nicht bei jedem Buildvorgang gelöscht werden und persistent bleiben. Das wäre es auch schon soweit, den Rest solltet ihr kennen oder ist selbstverständlich. Mit docker-compose up --build -d können wir nun alles builden und starten.

 

PiHole Ad-Lists einfügen

Das Web Interface von PiHole erreichen wir nun mit unserem Browser, indem wir einfach die IP des Raspberry Pi/oDroids aufrufen.

Mit dem Link kommt ihr nun zum Interface. Links in der Navigation „Login“ auswählen und das Passwort eingeben, welches ihr soeben in der Konfig festgelegt habt. Voilà! Testet am besten nun nochmal mit dig, ob DNS Abfragen funktionieren. Läuft alles tadellos, können wir nun Listen bei PiHole einpflegen, die zum Blockieren der Werbung zuständig sind. Ich beziehe meine Ad-Lists in der Regel ausschließlich von firebog.net. Einpflegen in PiHole könnt ihr diese dann unter Settings -> Blocklists.

Da in meinem Haushalt mehr Personen als ich das Internet nutzen, sperre ich lieber weniger als zu viele DNS-Adressen. Wenn nämlich irgendwo irgendwas aufgrund des DNS-Blackholes nicht geht, ist’s nervig für alle. Das ist am Ende aber natürlich jedem selbst überlassen. Am Ende auf Save and Update klicken und schon werden die DNS Abfragen, die in den Listen enthalten sind, blockiert. Die Listen werden nachts um 00:00 Uhr automatisch aktualisiert.

 

Schluss

Ihr habt nun einen PiHole Server, der seine DNS-Anfragen verschlüsselt erhält. Wenn ihr sicher seid, dass alles funktioniert, könnt ihr nun euren PiHole-Server als DNS-Server in eurem Router angeben. Wir haben hier eine Fritzbox und die Konfiguration darin sieht so aus:

Tragt dort die interne IP Adresse eures PiHole-Geräts ein und speichert die Einstellungen. Wie ihr seht, habe ich dort zwei IPs eingetragen. An erster Stelle kommt der oDroid XU4, an zweiter mein Backup-Pi3.

Tada! Absofort laufen die DNS-Abfragen des gesamten Netzwerkes gefiltert über PiHole -> DNS-over-TLS -> Cloudflare/Google/Quad9/…

Seid ihr auf Fragen oder Probleme gestoßen? Meldet euch gerne in den Kommentaren!

Ähnliche Beiträge:

Kommentare (16)

  1. Moin Dennis,
    vielen Dank für die sehr coole Anleitung. Ich habe die Installation zwar auf meinem Raspberry Pi 3 B+ durchgeführt , hat aber auch auf Anhieb geklappt.
    Mehr davon !
    Beste Grüße,
    Kolya

    • Mit jnettop (einfach apt install jnettop) kann man, wie ich finde, ziemlich unkompliziert die offenen Verbindungen mit den dazugehörigen Ports sehen. Tcpdump kenne ich nicht, wird aber vermutlich ähnlich wie Wireshark sein nehme ich an? Damit sollte es im Zweifel dann wohl auch gehen 🙂

  2. Hallo,

    danke für Deine Arbeit und ausführliche Anleitung. Leider hakt es bei mir schon am Anfang. Sind die Eingabezeilen heute (20-10-2019) noch aktuell?
    Bereits hier wirft mir das Terminal einen Fehler zurück
    >> pip3 install docker-compose
    >> Command „python setup.py egg_info“ failed with error code 1 in /tmp/pip-build-b6j3aaa3/pynacl/

    und trotz aller Trickserei komme ich leider nicht weiter.
    Hast Du eine Idee?
    Viele Grüße
    Paul

  3. Hi Dennis,

    kann man auch von außerhalb auf die Web Admin Oberfläche von Pi-Hole zugreifen?
    Bei mir klappt das leider nur direkt vom Raspi über die Docker IP 10.5.0.4.

    Danke,

    Wiborgit

    • Moin Wiborgit!

      Das sollte eigentlich per Default möglich sein. Dafür sind nämlich die Ports-Angaben im Docker-Compose File vorgesehen:

      ports:
      – „53:53/tcp“
      – „53:53/udp“
      – „80:80/tcp“
      – „443:443/tcp“

      Damit wird Port 80 und 443 an den Host durchgereicht, wodurch du eigentlich auch innerhalb deines Netzwerkes auf PiHole über die IP des oDroid/Raspi zugreifen können solltest. Gib mir sonst nochmal deine genaue Docker-Compose Konfig durch, dann schaue ich da mal drüber.

      • Hallo Dennis,

        vielen Dank erstmal für die super gute Anleitung. Bzgl. der Portdefinition habe ich allerdings das Composer Build File geändert, weil meine ursprüngliche Idee war, das ich gleichzeitig einen Nextcloud Server über den Raspi integriere. Dementsprechend habe ich die Ports verbogen:
        ports:
        – „53:53/tcp“
        – „53:53/udp“
        – „6080:6080/tcp“
        – „6443:6443/tcp“

        Damit hatte ich die Hoffnung, das ich von extern auf PiHole zugreifen kann über die Adresse:
        https://192.168.2.110:6443 (dabei ist die 192.168.2.110 die feste IP meines Raspi ist).

        Mir ist inzwischen klar, das es genau dran klemmt. Ich müsste also für ein einzelnes Docker Image eine zusätzliche IP erzeugen, welche ich dann korrekt adressieren kann – allerdings habe ich gerade noch keine Idee, wie das in Docker zu machen ist.

        Danke und Gruss,

        Wiborgit

          • 2. Ergänzung….
            Habe jetzt den Prozess, der die Adresse nutzt (war der lighttpd von nextcloud) gestoppt. Dann mit dem orginalen Composer Build File nochmal durchgestartet. Jetzt kann ich über die IP vom Raspi natürlich direkt die PiHole Admin Konsole auch von extern erreichen.
            Sprich meine nächste Aufgabe ist einfach nur…zusätzlich einen docker Nextcloud Service mit eigener IP (die dann auch von extern erreichbar ist) einzurichten…..

  4. Hallo

    Habe noch nicht so viele Erfahrungen mit Compose

    Bei mir gehts leider auch nicht. Ich versuche das via Container Station in der QNAP zu starten.
    Dort kann man ja via YML das Compose File hinzufügen.

    Allerdings darf ich kein Netzwerk erstellen sondern ein vorhandenes verwenden. Kannst mir bitte kurz schreiben wie der Stringaufbau ist bei der Verwendung von einem vorhanden Netzwerk.

    Name = docker0
    GW = 10.0.5.1
    Net = 10.0.5.0/24
    DHCP = 10.0.5.2 ~ 10.0.5.254
    DNS = 10.0.5.1

    Danke für deine HIlfe

      • In deiner Anleitung erstellst du eine Netzwerkbridge

        Das lässt er nicht zu. Gibts eine Möglichkeit Files hochzuladen dann könnte ich die Screenshots posten.

        Auf der QNAP heißt es
        Netzwerkeinstellungen (lxcbr0)
        Bridge-Name docker0

        Netzwerkeinstellungen (docker0)
        Bridge-Name docker0

        ———————— YML BEGINN ——————
        version: ‚2‘
        services:
        cloudflare-dns-tls:
        build: .
        restart: always
        image: qmcgaw/cloudflare-dns-server
        container_name: cloudflare-dns-tls
        environment:
        – VERBOSITY=0
        – VERBOSITY_DETAILS=0
        – BLOCK_MALICIOUS=off
        – LISTENINGPORT=53
        – PROVIDER=cloudflare
        networks:
        dnsbridge:
        ipv4_address: 10.5.0.2
        google-dns-tls:
        build: .
        restart: always
        image: qmcgaw/cloudflare-dns-server
        container_name: google-dns-tls
        environment:
        – VERBOSITY=0
        – VERBOSITY_DETAILS=0
        – BLOCK_MALICIOUS=off
        – LISTENINGPORT=53
        – PROVIDER=google
        networks:
        dnsbridge:
        ipv4_address: 10.5.0.3
        pihole:
        image: pihole/pihole:4.2.1
        dns:
        – 127.0.0.1
        – 172.22.222.1
        ports:
        – „53:53/tcp“
        – „53:53/udp“
        – „80:80/tcp“
        – „443:443/tcp“
        cap_add:
        – NET_ADMIN
        networks:
        dnsbridge:
        ipv4_address: 10.5.0.4
        environment:
        ServerIP: 172.22.222.227
        TZ: Europe/Berlin
        DNS1: 10.5.0.2
        DNS2: 10.5.0.3
        WEBPASSWORD: PIHOLE_PASSWORD
        volumes:
        – ‚/etc/pihole/:/etc/pihole/‘
        – ‚/etc/dnsmasq.d/:/etc/dnsmasq.d/‘
        restart: always
        networks:
        dnsbridge:
        driver: bridge
        ipam:
        config:
        – subnet: 10.5.0.0/16
        gateway: 10.5.0.1

        ————– YML ENDE ————-
        Fehlermeldung von QNAP
        Fehler 2020/09/11 12:23:10 Container admin Failed to do background task (application_custom, stonepi)
        Fehler 2020/09/11 12:23:10 Container admin Background task error for application_custom stonepi: Failed to build service image. Please check your YAML.
        ———-

        Danke für die HIlfe

  5. Hello,
    I’m using the latest ubuntu on odroid XU4 and having probkem to pass the docker-compose installation. After many problems with cffi, bcrypt and python, it now fails with:
    adding license file ‚LICENSE‘
    writing manifest file ’src/bcrypt.egg-info/SOURCES.txt‘
    copying src/bcrypt/_bcrypt.pyi -> build/lib.linux-armv7l-cpython-310/bcrypt
    copying src/bcrypt/py.typed -> build/lib.linux-armv7l-cpython-310/bcrypt
    running build_ext
    running build_rust

    =============================DEBUG ASSISTANCE=============================
    If you are seeing a compilation error please try the following steps to
    successfully install bcrypt:
    1) Upgrade to the latest pip and try again. This will fix errors for most
    users. See: https://pip.pypa.io/en/stable/installing/#upgrading-pip
    2) Ensure you have a recent Rust toolchain installed. bcrypt requires
    rustc >= 1.56.0.

    Python: 3.10.6
    platform: Linux-5.4.211-407-armv7l-with-glibc2.35
    pip: 22.0.2
    setuptools: 65.4.0
    setuptools_rust: 1.5.2
    rustc: n/a
    =============================DEBUG ASSISTANCE=============================

    error: can’t find Rust compiler

    I’ve tried to update the setuptools, but they seem to be the latest. Anything else I can do please?

Schreibe einen Kommentar