Nameserver fürs Homelab

  • Moin,

    ich habe aktuell einige Domains bei Netcup als Registrar und bei desec.io als Nameserver Provider liegen. Meine DNS Settings habe ich in einem Repository in meinem GitLab liegen und deploye diese bei Änderungen via DNSControl zu desec.io. Soweit so gut.


    In meinem Homelab möchte ich gerne eine Autarkie bei Internetausfall herstellen. Das ist insoweit auch bisher alles ganz gut gelöst, aber ich habe aktuell beim DNS noch einen Single Point of Failure, den ich gerne auf der Welt räumen möchte.


    Ich brauche nun also einen dritten Nameserver, der hier bei mir im Homelab steht und meine DNS Zonen kennt. Allerdings sollte der auch nur aus meinem Heimnetz erreichbar sein. DNSControl kann auf PowerDNS oder als Bind Zonefiles deployen. Ich habe noch nie damit gearbeitet - was davon will ich haben?


    Und: Ich habe einen Mikrotik Router mit RouterOS 7. Der hat eine Art eigenen DNS Server, den ich auch nutze. Wie richte ich das dort dann korrekt ein, dass auch mein eigener Nameserver genutzt wird?



    Oder erzähle ich hier gerade ganz großen Bullshit und das Problem meiner Lösung sieht ganz anders aus?


    Vielleicht kann mir ja das Schwarmwissen hier etwas weiter helfen. :saint:

    "Denn der radikalste Zweifel ist der Vater der Erkenntnis."

    -Max Weber

  • Hui. Wow. mhm. ähm.


    Also du hast aktuell deine Domains bei Netcup liegen mit "externen" DNS Server der von desec.io bereitgestellt werden, korrekt?


    Den Teil mit du willst deinen SPoF weg haben, irgendwie noch verstanden, aber dein Implementationsdesign ist bisschen wirr.


    PowerDNS finde ich persönlich eine schönere Wahl, weil:

    • mächtig
    • schlank
    • api

    Im Grunde kann ich die Frage mit deinen Router nur semi beantworten, weil dein Design noch nicht ganz klar ist, aber. Du würdest im Endeffekt einfach nur einen DNS Server bei dir Zuhause betreiben und deinem Router sagen das dieser benutzt werden soll. Der Rest muss dann von deinem DNS Server beantwortet werden.


    Im Endeffekt habe ich es bei mir so. Meine Domains liegen bei einem Domain Anbieter in Deutschland und ich verwende seine DNS-Server für die öffentliche Seite. Für die Interne Seite habe ich aktuell zwei Pi-Hole Instanzen laufen die per DHCP verteilt werden, oder per Hand statisch eingetragen sind. Zu dem betreibe ich das ganze als Split-DNS. Bedeutet das du intern anderst aufgelöst wirst, als extern. Entsprechend nimmt man bei mir auch unterschiedliche Wege zu seinem Ziel.


    Mein Setup werde ich aber noch umbauen, weil Pi-Hole ehr ein rudimentärer DNS Server ist wenns um eigene DNS Records geht. Da werde ich auf PowerDNS schwenken. Der Auth Server wird dann meine Internen Zonen halten. Vor dem steht dann der Recursor der bei internen Anfragen auf den Auth geht und bei Externen Anfragen das Pi-Hole frägt. Vielleicht mache ich aus jux noch einen dnsdist davor aber das wäre dann schon bisschen übertrieben.

  • Also du hast aktuell deine Domains bei Netcup liegen mit "externen" DNS Server der von desec.io bereitgestellt werden, korrekt?

    Soweit so richtig, ja. Also meine NS Records sind afaik "ns1.desec.io." und "ns2.desec.org.".


    aber dein Implementationsdesign ist bisschen wirr.

    Genau das ist mein Problem. Ich weiß nicht, was ich so genau will. ^^ Das ist aber auch eigentlich der Grund, warum ich frage...



    Generell ist das technisch etwas schwierig. Ich habe halt keinen lokalen Recursor rumstehen, sondern nur den DNS Server im Router, der die Anfragen per DoH an einen externen Recursor weiterleitet. Split Horizon DNS habe bzw. brauche ich dank IPv6 nicht.


    Das Problem, nochmal konkretisiert ist, dass mein Homelab bei Ausfall der Internetleitung theoretisch nach wie vor funktioniert (weil die Ressourcen alle nach wie vor miteinander reden können). Praktisch können sie sich aber doch nicht erreichen, weil sie den DNS Namen ihres Ziels nicht in eine IP Adresse auflösen können.


    Prinzipiell wären alle meine Zonen als statische Einträge im DNS Server des Routers, glaube ich, am elegantesten. Aber das lässt sich halt leider nicht ganz so elegant deployen.



    Aber danke für deinen Input. :)

    "Denn der radikalste Zweifel ist der Vater der Erkenntnis."

    -Max Weber

  • Nutzt du denn lokal auch die FQDNs die nicht .local oder so sind?


    Zumindest bei der Fritz!Box ist es so, dass der DHCP Name auch einen defacto DNS Eintrag erzeugt, unter dem ich das andere Gerät auch erreichen kann. Persönlich habe ich deine Aufgabenstellung über unbound mit lokalen Zonen gelöst und zusätzlich cached er auch die Einträge von Upstream DNS Server.

    Im lokalen Netz würde ich trotzdem immer versuchen mit Einträgen zu arbeiten, die unabhängig von der Erreichbarkeit externer NameServer sind.

  • Nutzt du denn lokal auch die FQDNs die nicht .local oder so sind?

    Ja, definitiv. Das DHCP autogenerierungs Hostname Zeug nutze ich gar nicht.

    Im lokalen Netz würde ich trotzdem immer versuchen mit Einträgen zu arbeiten, die unabhängig von der Erreichbarkeit externer NameServer sind.

    Das ist es halt. Ich könnte auch einfach die TTL höher nehmen. Wenn dann aber Eintrag X wieder im DNS Cache fehlt, gehen die Probleme wieder los.

    "Denn der radikalste Zweifel ist der Vater der Erkenntnis."

    -Max Weber

  • Bei mir hat das alles mal mit einem bind9 als "Hidden Primary" für meine Domains angefangen. Ich verwalte die Zonen meiner Domains auf diesem, von außen angesprochen werden kann dieser aber nicht. Änderungen werden auf die Nameserver meines Domain Providers veröffentlicht, und nur diese stehen via NS record auch in den Zonen drin. Heißt ich hab den Luxus echter nsupdate Requests aber muss mich nicht mit DoS und ähnlichem rumärgern.


    Vor einiger Zeit ist dann noch eine Interne Instanz dazu gekommen. Diese ist einerseits in meinem OPNSense Router für DHCP DynDNS (A & PTR Records) eingetragen, andereseits gibts ne echte Domain für meine Homelab Dienste, sodass ich auch via DNS Challenge Lets Encrypt Zertifikate holen kann.


    Auf dem ns2 nutze ich dafür bind views, die es erlauben unterschiedliche Zonen je nach Quell IP des Anfragenden bereit zu stellen. Heißt, kommt ein DNS Query von 192.168.0.0/16 ist dig brickburg.de A etwas anderes, als wenn das gleiche query von 8.8.8.8 kommen würde.


    ns1 bei mir im Homelab ist dabei der Primary für alles, und ns2 der Secondary. Ich kann also meinen Proxmox warten ODER das Internet kann aufallen, meine internen DNS Zonen sind verfügbar. Fällt beides aus, ists natürlich wieder kaputt.


    Sehr angenehm, wenn gerade Updates laufen und die VMs nacheinander rebooten. Man merkt nichts mehr davon.


    Zusätzlich gibts noch auf beiden Systemen einen pihole, der im Client VLAN als ns1 und ns2 im DHCP eingetragen ist und die Queries an die jeweiligen Nameserver forwarded, sofern es kein Junk Query ist.


    Beide Nameserver haben mindestens 2 interne IPs, sodass bind und pihole jeweils auf Port 53 mit eigener IP laufen können. ns2 bekommt diese IPs durch ein via OpenVPN geroutetes /27 Netz.


    Managed wird das alles via Ansible, ich hab ~250 Zeilen langes Konfigurationsobjekt, wo Zonen, HMAC Keys und Zugriffsregeln definiert sind und das Playbook erzeugt daraus die bind9 config files. Und macht anschließend Logik Checks wie "DNSSEC ist aktiv, gibts auch Keys?" oder "stimmen die NS Records in den Zones?" oder "Sind die SOA Records korrekt?".


    pasted-from-clipboard.png

  • ich würde mit dnscontrol bind-zones schreiben lassen, die zone auf den router kopieren und via dhcp-lease-trigger (dhcp-lease-script) die statics importieren.

    So ähnlich ist jetzt auch mein Plan.


    Leider kann der Router keine Bind Zones (RouterOS halt), daher habe ich den Bind9 auf den Pi geschmissen, wo auch mein PiHole drauf liegt. Da muss ich mir noch eine Magie bauen, die dann aus der Pipeline raus die Bind files per SCP auf den Pi kopiert und den Bind dort neustartet/reloadet.


    Mein Hauptproblem ist eigentlich. Der DNS Server von RouterOS kann mit sog. FWD Records so konfiguriert werden, dass er bestimmte Domains an einen bestimmten, weiteren DNS Server forwardet. Das funktioniert aber nicht, wenn man diesen als Upstream DNS Server DNS-over-HTTPS nutzen lässt. Keine Ahnung, warum man das so programmiert.


    Eine Idee habe ich da noch, die habe ich aber noch nicht getestet. Wenn die Internetleitung wegknackt, sollte das DoH nicht funktionieren und er sollte auf normales DNS zurückfallen. Vielleicht funktionieren dann die FWD Zones. Das würde ja eigentlich schon ausreichen.


    Es gibt noch die Möglichkeit, die eingehenden DNS Anfragen mit DPI in der Firewall mittels NAT an ein anderes Ziel zu leiten. Aber das ist... nun ja. Etwas unsauber.

    "Denn der radikalste Zweifel ist der Vater der Erkenntnis."

    -Max Weber

  • Ich glaube, ich habe jetzt die "beste" Lösung gefunden.


    Was ich gemacht habe - ich habe DoH am Router ausgeschalten, damit die FWD Records wieder funktionieren. Statt öffentlichen DNS Servern, nutze ich nun allerdings den Unbound Recursive Resolver meines VPN Servers. Der VPN Server ist so oder so per Wireguard Tunnel an meinen Router angebunden.


    Um das ganze halbwegs ausfallsicher zu haben, habe ich mir mittels Netwatch einen Failover-Mechanismus gebaut:

    pasted-from-clipboard.png


    Ist die Unbound Instanz auf meinem VPN Server nicht mehr erreichbar, wird auf normale, öffentliche DNS Server umgeschalten. Und anders herum.


    Was jetzt noch fehlt, ist, dass ich einen Bind aufsetze und mir ein Deployment aus DNScontrol heraus bastel. Wo genau der am Ende laufen wird, weiß ich selber noch gar nicht... dort deploye ich dann aber auf jeden Fall meine DNS Records aus der Pipeline heraus hin und lege auf meinem Router die passenden FWD Records an.


    Ich glaube, dass ich das Problem damit einigermaßen elegant gelöst bekomme.

    "Denn der radikalste Zweifel ist der Vater der Erkenntnis."

    -Max Weber

    Einmal editiert, zuletzt von whoami0501 ()

    Gefällt mir 2
  • Ich selbst nutze monit, um Unbound-Instanzen nach Möglichkeit wiederzubeleben (ginge wohl auch mit Systemd-Bordmitteln) und dnsdist, um Last­ver­teilung/Aus­fall­si­cherung und selektive Ausnahmen für Auflösungen (am heimischen Desktop etwa für Homebanking-Domänen und generell für die lokale Auflösung von "vpn-thishost." o. ä.) zu realisieren. Inwiefern man dnsdist in die obige Umgebung bekommt, kann ich allerdings nicht sagen.

    VServer IOPS Comparison Sheet: https://docs.google.com/spreadsheets/d/1w38zM0Bwbd4VdDCQoi1buo2I-zpwg8e0wVzFGSPh3iE/edit?usp=sharing

    Einmal editiert, zuletzt von m_ueberall ()

  • Sieht hart nach Mikrotik aus.


    Magst du ein bisschen auf die eingesetzten Pakete und Scriptingmöglichkeiten eingehen?

    Grenzt ja fast an SDN - finde ich Wunderbar.

    Ist es auch. RouterOS 7 auf meinem CCR2004-16G-2S+.

    Pakete nutze ich keine speziellen - das sind alles Bordmittel, die ROS 7 von Werk aus mitbringt.


    Was das Scripting betrifft. Naja, prinzipiell ist es recht simpel. Mikrotik Geräte kann man ja auch per Kommandozeile (SSH/Serial/WebTerminal/...) steuern. Mit entsprechender Befehlssyntax. Und die kann man auch zum Scripten nutzen.


    In meinem Fall habe ich das Script direkt in der Netwatch Konfiguration drin, was heißt, dass bei einem neuen Status (z.B. "up" auf "down") der Scriptschnipsel ausgeführt wird. Quasi eine Art Hook.


    Im Normalfall kann ich in ROS 7 zwar konfigurieren, dass mehrere DNS Server genutzt werden sollen, allerdings keine Priorität oder Reihenfolge. Dort wird dann immer ein Lastausgleich o.Ä. auf alle eingetragenen Ziele gefahren. Und genau das war mein Problem - ich wollte, solange er verfügbar ist, ausschließlich meinen eigenen Unbound durch besagten Wireguard Tunnel hindurch benutzen.


    Daher habe ich mir wie gesagt diesen Umschaltmechanismus gebaut. Netwatch macht alle 10 Sekunden einen TCP Connect auf Port 53 meines VPN Servers. Schlägt dieser fehl, wechselt der Status auf "down" und das Script bei "On Down" wird ausgeführt. Dieses schaltet dann auf alternative DNS Server um.



    Theoretisch hätte man es noch ein bisschen eleganter bauen können. In meinem Falle wird nicht erkannt, wenn der Unbound zwar läuft, aber z.B. nur noch SERVFAIL liefert. Theoretisch könnte man auch das Script "plain" hinterlegen und als eine Art Cronjob laufen lassen. Dort könnte man dann mit einem /resolve versuchen, den Zielserver eine Domain auflösen zu lassen. Dabei könnte man dann widerum potenzielle Fehler catchen und darauf basierend einen anderen DNS Server setzen.


    Eventuell baue ich das nochmal um. Ich habe das mit dem Fehler catchen beim ROS Scripting noch nie gemacht. Das muss ich mir nochmal anschauen.

    "Denn der radikalste Zweifel ist der Vater der Erkenntnis."

    -Max Weber

    Danke 1
  • Ich habe das ganze Setup nun (endlich) fertiggestellt.


    Nebst dem Failover Script im Router (siehe oben), habe ich nun eine VM mit einem Bind Server laufen. Pushe ich nun in mein GitLab Repository mit meinen DNS Zonen, werden diese von DNSControl einmal zu desec deployed und zusätzlich als Bind Zonefile gerendert. Die Zonefiles werden dann per SSH/rsync auf die VM kopiert und mit einem Deployment-Script in der Bind Konfiguration eingepflegt. Im Router existiert nun ein FWD Record, welcher die Anfragen für die jeweiligen Domains an den Bind weiterleitet.


    Aktuell gibt es da noch das kleine Problem, dass es ab und an mal laggt. Ich selber merke das nicht direkt, aber in meinem Monitoring macht sich das aktuell bemerkbar. Der Monitoringserver steht ebenfalls hier im Homelab und wirft ab und an mal kurzzeitig Fehler ala '"abc.xyz.de" is not a valid hostname' oder 'Zu diesem Hostname gehört keine Adresse' oder ähnliches. Ich vermute mal, dass das ein Bug in RouterOS ist. Evtl. baue ich mir einen Schalter, sodass der FWD Record mit dem Failover Script aktiviert und deaktiviert wird.

    "Denn der radikalste Zweifel ist der Vater der Erkenntnis."

    -Max Weber