Alpine Linux basierter DNSSEC validierender rekursiver Unbound DNS-Resolver

Hallo liebe Kuketz-Gemeinde,

ich nenne mich madnuttah, verdiene mein Brot als Linux-/Windows Sysadmin, programmiere gelegentlich dies und das und bin ein vehementer Verfechter von Datenschutz und Privatsphäre. Hier sind wir auch schon beim Thema meines Beitrages unter freundlicher Abstimmung mit Mike.

DNS ist ein äußerst systemkritischer Dienst im Netz. Nun, es gibt eigentlich keinen Dienst oder kein OS welches nicht ständig gepflegt, den aktuellen Gegebenheiten angepasst und auf dem neuesten Stand gehalten werden muss, um die bestmögliche Sicherheit einer Infrastruktur aufrechtzuerhalten. „Never touch a running system…“ ist eine Weisheit aus besseren Tagen, einer Zeit in der Komfort der Sicherheit überwog; als man sich noch nicht bewusst war, wie eine sich gerade etablierende und zu diesem Zeitpunkt relativ harmlose und nützliche Technologie in wenigen Jahren zur Waffe, die sich auch gegen einen selbst richten könnte, werden kann.

Ich fing irgendwann an mich für Pi-hole zu interessieren und fuchste mich in das Docker cli rein. Soweit lief alles super, allerdings machten die DNS Server meines Internetproviders fast wöchentlich Schwierigkeiten. Anfangs dachte ich es die Schuld läge bei Pi-hole und fand dann heraus, das teilweise die mir zugewiesenen Namensserver öfter einfach unerreichbar waren. Auf meiner Suche nach DNS Resolver Docker Images bin ich auf Unbound gestoßen und hatte mich dann für ein besonders populäres Image entschieden. Weil Sternchen auf Docker Hub und GitHub…

Ich passte meine Config auf „rekursiv“ an (hatte seinerzeit bei Mike eine Anleitung gefunden, Stichwort ‚hyperlokal‘) und nutzte seither meinen eigenen rekursiven DNS Resolver.

Es ist nun etwas mehr als 2 Jahre her als ich mich über die schlechte Pflege und die Größe des von mir verwendeten Unbound-Docker-Images zugegebenermaßen recht geärgert habe. Es gab Buildbases mit Alpine, warum benötigt man heutzutage Images mit zum Teil weit mehr als 100MB Zeugs was angegriffen und kompromittiert werden kann? Warum nutze ich ein Image von irgendjemanden den ich nicht mal kannte, geschweige mein Vertrauen schenken würde?

Warum zum Geier kannte ich mich nicht mit dem Bauen von Abbildern unter Docker aus?

Ich studierte etliche Websites und schaute mir verschiedene Images an und stellte fest, das dies absolut keine Kobayashi-Maru-Mission war, insbesondere das Bauen des Images mittels Workflow was bedeutete, die Images konnten online direkt von einer Action auf GitHub und nicht bei mir zuhause im stillen Kämmerlein gebaut werden! Ich wollte das auch den Menschen bereitstellen. Ich begann via Pipelined Workflow Images für 386, arm, arm64, amd64 bereitzustellen und gewann etwas Aufmerksamkeit weil mich nette Menschen wie Mike mein im Sinne des Idealismus gefertigten Images, ganz ohne monetäre Interessen auf ihren Portalen so freundlich eingeladen bewerben lassen. :heart:

Es erforderte etwas Trial & Error bis es zu meiner Zufriedenheit lief.

Neben den üblichen Updates und Pflege des Images dümpelte es bis kurz vorm Release von Unbound 1.19.1 so vor sich hin. Genau bis bis zu dem Zeitpunk, an dem mich ein aufmerksamer GitHub User darauf hinwies, dass das Image keine sichere Chroot-Umgebung bereitstellen konnte, was ich ausdrücklich als besonders sicheres Feature in der Beschreibung meines Images hervorgehoben hatte. Mein Wort zählt! Das fühlte sich wie ein Schlag in die Magengrube an. Ich konnte das natürlich nicht so lassen und prüfte meine Optionen:

a: Image so wie es ist umbauen
b: Image komplett auf „Distroless“ umstellen
c: Aufgeben

c: gibt’s nicht, hat’s noch nie gegeben. Es hatten ja schon viele das Image installiert und nutzten es. Mir fiel auf, dass ich beim Buildvorgang den Ordner /unbound/etc löschte. Naja, da konnte halt auch kein Chroot greifen. Doof. Soweit lief es nach weiteren Anpassungen wieder in meiner Umgebung aber ich schielte schon seit langem in richtung Distroless Image unter Alpine (das widerspricht sich irgendwie, ich weiß) mit meinen gewohnten und angepassten Dockerfiles. Das war die Gelegenheit, alles komplett neu anzugehen und auch die Anregungen des aufmerksamen Users umzusetzen. Distroless mit einer niedrigst möglichen Angriffsfläche! Ja, es gab viel zu tun, denn auch der Healthcheck hatte so seine Probleme…

Was ich euch heute hier vorstellen möchte, ist wohl aktuell das innovativste und fortschrittlichste Unbound-Docker Image was zur Verfügung steht - mit viel Liebe zum Detail nach den Prinzipien der „Best Practice“ modelliert. Bei gerade einmal 10MB komprimierten Download, aktuell in der Version 1.19.1-6.

Features:

  • Distroless
  • Unprivilegierter Benutzer
  • Unprivilegierter Port
  • Frei konfigurierbare UID/GID (!)
  • Libevent
  • DNSSEC
  • DNSCrypt
  • DNSTap
  • DNS64
  • DNS over HTTPS
  • DNS over TLS
  • Vorbereitet für DoQ
  • Redis (!)
  • Optionaler, aussagekräftiger Healthcheck (!)
  • Optionale Statistiken mit Zabbix und Grafana (!)

Falls ihr Unbound einsetzt, nutzt unbedingt Redis. Und dann am besten auch noch via Unix Socket. Mopsgeschwindigkeit!

Pi-hole habt ihr sicher schon und ich muss auch nicht noch davon schwärmen, oder?

Falls ihr Statistiken mögt, schaut euch mein Begleitprojekt Unbound Statistics an, welches mit Bordmitteln Unbound-Statistiken via Zabbix Active Agent an Zabbix überträgt und anschließend stressfrei in Grafana dargestellt werden können:

In den letzten Tagen habe ich die Pipeline umgestellt, sodass sie via meines Bots ‚madnuttah-bot‘ bei einem Update von Unbound automatisch geupdated, auf Docker Hub gepusht und das GitHub-Repo meinen strengen Sicherheitsrichtlinien entsprechend komplett automatisiert aktualisiert und signiert wird.

Ich freue mich auf eure Meinung und auch auf eure konstruktive Kritik. Wir als Entwickler sind um solche aufmerksamen Benutzer dankbar, nur so sind Verbesserungen und Veränderungen möglich. Damit Dinge entstehen können, die weitaus besser werden als man es selbst für machbar gehalten hätte.

https://github.com/madnuttah/unbound-docker

Danke Mike, dein Blog ist schon seit etlichen Jahren eine wichtige Anlaufstelle für mich.

Liebe Grüße und sorry für die Textwand. Wie man liest, bin ich es gewohnt ausführliche Dokumentationen zu schreiben.

Edit: Rechtschreibung

8 „Gefällt mir“

Vielen Dank für das Projekt und die darin enthaltenen tollen Inspirationen. Ich nutze kein Docker, sondern Proxmox mit u.a. Pihole und unbound.
Bitte entschuldige meine Frage aus Unwissenheit, aber in einem Sicherheitsforum sollte sie angebracht sein. Du schreibst:

DNS ist ein äußerst systemkritischer Dienst im Netz

Da stimme ich Dir zu. Wodurch unterscheidet sich aber deine vorgefertigte Lösung, so dass man dieser - einschl. der vollautomatischen Aktualisierung und Signierung - quasi blind vertrauen kann?

1 „Gefällt mir“

Hi Hans,

ich freue mich sehr über deine Frage.

  • Mein Image ist eines der wenigen (glaube es gibt aktuell 2), die ein Distroless-Scratch-Image als Basis nutzen. Der Vorteil ist, dass im Image nur Programme enthalten sind, welche die Software und das Betriebssystem für den reibungslosen Betrieb unbedingt benötigen.

  • Ich hämmere nicht blind an irgendwelche Domains beim Healthcheck, alles frei konfigurierbar. Ich kann nicht entscheiden, ob du glücklich wärst, wenn ich google.de als Testziel festlegen würde. Daher wird nur der Port in der Standardkonfiguration des Checks mit Netstat und Grep geprüft.

  • Bei allen Netzwerkvorgängen beim Build auf GitHub verwende ich eine Art Firewall für die Runners, angeboten von StepSecurity, um Man-In-The-Middle-Attacken zu vermeiden.

  • Alle heruntergeladenen Dateien, seien es die Source-Tarballs oder die Root-Files von Internic und sofern Signaturen vorhanden sind, werden diese auf Authentizität geprüft.

  • Ich verzichte so gut es irgendwie geht auf unnötige Actions, wenn Actions Verwendung finden, sind es vertrauenswürdige Anbieter.

  • Die meisten Images werden wohl zuhause ohne Workflow gebaut. Wer weiß, was da alles reinmanipuliert werden kann?

  • In fast allen Images ist Netcat enthalten (!). Stell dir nen kompromittierten, zentralen DNS Server mit allen Werkzeugen vor, die sich jemand mit unschönen Absichten nur wünschen könnte.

  • Die config Datei ist bereits etwas ‚gepimpt‘, klar, dass der rekursive Modus schon eingestellt ist aber es sind darüber hinaus auch schon Sicherheitsfeatures aktiviert.

  • Du wirst mit meinem Image keine DNSSEC Probleme wegen einer unkorrekten Zeit haben, das Image hat die Zeitzonen mit auf seinen Weg bekommen. Best practice.

  • Das Signieren von allen Vorgängen in meinem Repo garantiert dir, dass nur diejenigen commits getätigt haben, die sie auch wirklich sind. Also konkret mein Bot.

Das ist wohl ein Aluhut-Image geworden. Hehe.

Edit: Rechtschreibung und MD-Formatierung

3 „Gefällt mir“

Ich weiß was ein Raspi ist, ich kenne Alpine Linux und pihole ist auch ein Begriff,
Docker kenne ich durch Dangerzone.
Jetzt wo es bei mir hackt wie man das nutzen soll.

Für den Rapsi braucht es ein OS, worauf pihole läuft bzw. Docker installiert wird in dem dann pihole für Docker und Dein unbound image in einem Container läuft, soweit korrekt?

Für den Raspi könnte man Alpine Image als OS verwenden (braucht wenige Ressourcen so bleibt viel für den Container, minimales OS. Für Alpine gibt es aber kein Docker und kein pihole, dafür aber Kubernetes, womit sich ein Docker Container einfügen lassen würden, den man zuvor am Rechner mit einem pihole für Docker und Deinem unbound image baut.

Wäre das ein Mögliche Umsetzung? Oder wie soll das Gerüst darum genau aussehen?

Ansonsten, wo geht’s hier bitte zum Gleis 11? Da fährt mein Zug bald ab!

1 „Gefällt mir“

Hi M-u-m-p-i-t-z,

Ja das stimmt so. Ich hab Alpine auf meinen Docker Hosts am laufen. Ist reine Geschmackssache,ich nutze llerdings kein Raspian. Docker läuft bei mir auf alten mini-PCs, je schlanker desto besser in meinem Fall. Dein Raspberry hat ein optimiertes Betriebssystem das läuft unter Debian, du installierst und konfigurierst einfach die Docker-Umgebung nach Anleitung (je nach Modell) laut Internetz.

Anschließend mittels Compose Dateien einen sogenannten Stack bauen und dann loslegen. Ich habe alles hier beschrieben und hier findest du einige Compose Dateien die angepasst werden müssen aber hoffentlich so hilfreich sind. Alles in Englisch aber ich bin hier und mache gerne kleineren Support im Forum. Bei Problemen oder Anregungen bitte auf GitHub ein Issue oder PR öffnen.

Steig ein, ich nehm dich mit.

Edit: @M-u-m-p-i-t-z, hier findest du eine Anleitung für Pi-hole und Unbound auf Raspberry. Die yaml Datei kommt mir etwas veraltert vor aber du hast ja meine frischen. Ist sogar mal zur Abwechslung mein Image was Verwendung findet. :partying_face:

2 „Gefällt mir“

Dieses professionell wirkende Projekt weckt total mein Interesse und gehört eigentlich in die Sektion Anleitungen :smiley:
Wie geschrieben nutze ich aber Proxmox und das verträgt sich nicht optimal mit Docker und müsste zudem in einer VM laufen.
Macht eine Umsetzung auch ohne Docker Sinn und wo könnte ich da anfangen?

1 „Gefällt mir“

@kuketzblog hatte seinerzeit eine Anleitung verfasst, vielleicht hilft sie dir ja weiter.

Es ist eigentlich egal, machst ne Linux VM, packst Docker drauf, yamls anpassen, starten. Ich hab bisher nix Gegenteiliges gehört, Proxmox ist ja auch nur ein Hypervisor. Versuch macht kluch. Ist halt stressfreier, kannst Rollbacks machen, die Daten auf den bind Volumes gehen nicht verloren. Docker ist der Hammer.

Edit: Fang am bestenganz klein an, @Hans_Hauser.

  • Erst mal Docker zum Laufen bekommen. Je nach Komplexität und Sicherheitsniveau deines Netzes kann das schon herausfordern
  • Dann Pi-hole mit nem offiziellen Upstream lauffähig machen
  • Wenn alles gut am Rennen ist, kannst du Unbound als rekursiven Upstream in Betrieb nehmen
  • Danach noch Redis und du wirst strahlen

Je weniger Schichten am Anfang desto weniger Frust.

Edit: Muss mir mal ne Tastaur für’s Tablet gönnen

Ich habe gerade gesehen es gibt für Alpine Linux doch ein Docker Paket und für Kubernetes wäre ein Raspi wohl überfordert.
Ich hatte vor ein paar Wochen das erste mal Alpine auf einem Raspi installiert (sollte ein Jabber Server werden) und war von der Einfachheit und dem RAM OS Prinzip des Alpine Linux begeistert.
Nur leider habe ich das mit den Zertifikaten nicht gerafft und das Project ist dann auch eingeschlafen. Das hier wäre was,wo ich mit was anderem weiter machen könnte.
Obwohl ein pihole eigentlich nichts für meine Ipfire wäre, falls die nicht sogar streiken würde. Aufgrund des DNSSEC Problems (pihole=Zensur) was der Hauptentwickler(Sprecher) aber schon 2019 geäußert hatte.
Ich werde zu gegebener Zeit berichten. Danke für die links, die werden mir helfen.

1 „Gefällt mir“

Hi, dann habe ich das einfach nicht richtig verstanden, Entschuldigung. Klar, Alpine kann Docker. Meine Docker-Hosts laufen alle auf Alpine.

Bin da, falls du Unterstützung brauchen solltest.

Für jemanden, dessen Linux-Kenntnisse ausreichen, um die Systeme einigermaßen zu verwalten, klingt das alles beeindruckend und vorbildlich. Von Docker-Containern habe ich auch schon gehört. Nach Lesen des Beitrages von madnuttah bin ich nun ins Grübeln geraten, ob ich da irgendwas Sicherheitstechnisches übersehe. Bei mir läuft seit Jahren ohne Fehl und Tadel (soweit ich das beurteilen kann) ein Raspberry mit Pihole und unbound, und dank der Anleitungen von Mike und Tschaeggar auch weitgehend wartungsfrei. Das Ganze läuft auf einem schlanken Dietpi-System und außer Pihole und dem rekursiven unbound-Resolver sind noch Baikal und Nextcloud am Werkeln. Die sporadisch abgefragten Log-Dateien melden i.d. Regel „alles im grünen Bereich“. Die Root-Server und adlists werden automatisch upgedatet und einmal pro Woche wird das System auf den neuesten Stand gebracht. Jetzt meine laienhafte Frage: gibt es eine gewichtigen Grund, warum ich mich in dieser Umgebung mit Docker-Containern befassen sollte? Das Dietpi-Repository bietet ja eine solche Installation an.

Docker container haben etliche Vorteile.

  • Optimale Ressourcennutzung durch Virtualisierung
  • Kein Datenverlust dank persistenter (bind) Volumes
  • Wartbarkeit, du kannst einfach ein Rollback bei einem Problem auf das vorherige Image machen
  • Kein Stress mehr bei Updates des Betriebssystems
  • Dein Stack ganz einfach mit weiteren Microservices erweitern wenn was neues dazu soll, z.B. es läuft alles super und jetzt willst du noch redis wegen persistentem Cache
  • Übertragbarkeit, falls mein Host ausfällt, fahre ich einen anderen hoch, mach die fstab fein, initiiere den Stack und es geht weiter. Cold standby überhaupt kein Thema

Das sind eigenlich die wichtigsten Argumente für Docker.

1 „Gefällt mir“

Ja, danke für die Erläuterungen. Wenn ich demnächst mehr Muße habe, werde ich mich mal in die Docker-Materie einlesen.

1 „Gefällt mir“

Danke für den ausführlichen Beitrag. Hattest du dir in dem Zusammenhang auch Wolfi angeschaut? Falls ja wieso hast du Alpine den Vorzug gegeben?

Was ist Wolfi?

Alpine ist ein sehr schlankes und gut gepflegtes Betriebssystem, daher hatte ich diesem den Vorzug gegeben.

Wolfi. Ich wollte mich weiter über distroless informieren und dabei bin ich recht schnell auf Wolfi gestoßen.

What is Wolfi and how does it compare to Alpine?

Wolfi is a Linux undistro designed from the ground up to support newer computing paradigms such as containers. Although Wolfi has a few similar design principles as Alpine (such as using apk), it is a different distribution that is focused on supply chain security. Unlike Alpine, Wolfi does not currently build its own Linux kernel, instead relying on the host environment (e.g. a container runtime) to provide one.

1 „Gefällt mir“

Danke, schau ich mir mal genauer an. SBOM klingt interessant und ist aktuell ein Problem beim Sicherheitsscan. Docker Scout und Trivy haben wohl ihre Schwierigkeiten mit distroless images.

1 „Gefällt mir“

Gibt es auch eine Installationsanleitung für Dummys wie mich ? Für jene die jetzt nicht so viel Ahnung von Docker haben ?

Für die Grundinstallation von Docker gibt es speziell für die Linux-Variante die du betreiben möchtest, Installationsanleitungen. Das würde auch den Rahmen hier sprengen. Ansonsten sollte meine Anleitung auf GitHub schlüssig sein. Was kann ich besser beschreiben, wenn dem nicht so wäre?

Ich frage auch immer gerne: wie weit bist du denn?

Docker läuft bei mir schon auf einem Raspi. Allerdings bis jetzt mit Adguard Home.

Darf ich das auch erfahren? :slight_smile: