Autoritativer DNS-Server mit PowerDNS: interne Namensauflösung

Eine funktionierende und zuverlässige Namensauflösung ist das Rückgrat jedes Netzwerks, besonders in internen Infrastrukturen, in denen Dienste und Ressourcen schnell erreichbar sein müssen. Während Hosts-Dateien einfache Netzwerke abdecken können, sind sie nicht für größere, dynamische Umgebungen geeignet. Hier kommt PowerDNS ins Spiel, ein leistungsfähiger, autoritativer DNS-Server, der in Kombination mit einem SQL-Backend eine skalierbare Lösung bietet. In dieser Anleitung zeige ich dir, wie du PowerDNS mit einer MySQL- oder MariaDB-Datenbank konfigurierst, um interne DNS-Zonen zu verwalten. Zusätzlich fügen wir eine optionale Konfiguration hinzu, die es uns ermöglicht, DNS-Anfragen über die OPNsense-Firewall mittels Unbound Resolver weiterzuleiten, sodass alle internen Geräte – inklusive VPN-Clients – davon profitieren.

Voraussetzungen

Um sicherzustellen, dass der Setup-Prozess reibungslos abläuft, sollten bestimmte Voraussetzungen erfüllt sein. Hier erfährst du, welche notwendig sind, um PowerDNS erfolgreich zu konfigurieren.

  • DNS Grundverständnis
  • Linux Debian Grundkenntnisse
  • Port 53 sollte am besten nur für den Unbound erreichbar sein! (Firewall)

Hinzufügen des PowerDNS Repositorys für den Autoritativen DNS-Server

Zuerst fügen wir das PowerDNS-Repository hinzu, um Zugriff auf die neuesten Versionen und Sicherheitsupdates zu haben. So stellen wir sicher, dass der Server mit den aktuellsten Features ausgestattet ist.

Auf der nachfolgenden Seite findest du die Repositorys. Dort benötigen wir für unsere Distribution die passende des Authorativen Servers. In diesem Fall also im Bereich Debian 12, PowerDNS Authoritative Server - version 4.9.X (stable).

Hier sehen wir nun schon die nötigen Schritte, die ich hier einmal für die Version 4.9.x (stable) etwas vereinfache und zu copy&paste Commands mache.

Einmal die source Liste erstellen:

cat <<EOF > /etc/apt/sources.list.d/pdns.list
deb [signed-by=/etc/apt/keyrings/auth-49-pub.asc] http://repo.powerdns.com/debian bookworm-auth-49 main
EOF

Dann fügen wir noch das Pinning hinzu, damit diese Pakete auch wirklich von dieser Repository gezogen werden und nicht von der Debian Standard Repository:

cat <<EOF > /etc/apt/preferences.d/auth-49
Package: auth*
Pin: origin repo.powerdns.com
Pin-Priority: 600
EOF

Anschließend fügen wir noch den GPG Key hinzu:

install -d /etc/apt/keyrings; curl https://repo.powerdns.com/FD380FBB-pub.asc | sudo tee /etc/apt/keyrings/auth-49-pub.asc

Installation von PowerDNS

Im Anschluss installieren wir PowerDNS und alle notwendigen Abhängigkeiten, um den autoritativen DNS-Server einzurichten und betriebsbereit zu machen.

Wir aktualisieren einmal die Paketquellen, damit die von PowerDNS eingelesen werden:

apt update

und nun können wir PowerDNS installieren:

apt install pdns-server pdns-backend-mysql

Vorbereitung der Datenbank für das SQL-Backend

Das empfohlene Backend ist SQL, da es die meisten Features unterstützt. Natürlich gibt es auch noch weitere Backends, aber in diesem Fall nutzen wir das SQL für MariaDB/MySQL.

Wie man einen MySQL Server einrichtet, eine Datenbank erstellt sowie einen Benutzer der volle Rechte auf die Datenbank hat erstellt, erkläre ich hier jetzt nicht – aber sobald diese Punkte erledigt sind, müssen wir nämlich das Schema noch laden. Das Example findet man am besten in GitHub.

https://github.com/PowerDNS/pdns/blob/rel/auth-4.9.x/modules/gmysqlbackend/schema.mysql.sql

Wie man hier am Link sehen kann, habe ich den Release Branch mit dem Sub-Branch auth-4.9.x gewählt, was zu unserer Version passt. Einfach zum Datenbank-Server per CLI verbinden, kurzes use pdns_db, vorausgesetzt die Datenbank heißt pdns_db und dann einfach die Querys direkt in die Datenbank importieren.

Damit ist dann was die Datenbank angeht alles vorbereitet – eigentlich. Es gibt noch ein kleines extra. Da die Storage Engine der Datenbank-Server meistens InnoDB ist, empfehle ich noch die Anwendung von Foreign Keys. Auch einfach direkt in die Datenbank rein die Querys:

ALTER TABLE records ADD CONSTRAINT `records_domain_id_ibfk` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE comments ADD CONSTRAINT `comments_domain_id_ibfk` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE domainmetadata ADD CONSTRAINT `domainmetadata_domain_id_ibfk` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE cryptokeys ADD CONSTRAINT `cryptokeys_domain_id_ibfk` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

Konfiguration des SQL-Backends in PowerDNS

Nach der Einrichtung der Datenbank und des passenden Benutzers verknüpfen wir PowerDNS mit dem SQL-Backend, sodass der Server Zonen und DNS-Einträge direkt aus der Datenbank lesen und verwalten kann.

Dazu erstellen wir eine neue Konfigurationsdatei:

touch /etc/powerdns/pdns.d/backend-sql.conf

Nun können wir diese Datei füllen mit unserer Konfiguration – beachte die Zugangsdaten und eventuell den Host, falls es sich um einen externen Datenbank-Server handelt, zu ändern:

launch=gmysql
gmysql-host=<ip-des-datenbank-servers>
gmysql-port=<meistens Port 3306>
gmysql-dbname=<pdns-datenbank-name>
gmysql-user=<pdns-datenbank-user>
gmysql-password=<pdns-datenbank-user-pw>

DNSSEC Support und SSL lassen wir für die Einfachheit erstmal raus. Zu SSL werde ich noch einmal einen eigenen Artikel verfassen.

Konfiguration des Primary/Secondary-Setups in PowerDNS

Um Redundanz und Zuverlässigkeit zu gewährleisten, richten wir PowerDNS als Primary- und Secondary-DNS-Server ein. So stellen wir sicher, dass auch bei einem Ausfall des Primary-Servers die Namensauflösung weiterhin funktioniert.

Dazu erstellen wir eine neue Konfigurationsdatei:

touch /etc/powerdns/pdns.d/general.conf

Wir können hier nun unsere Konfiguration einfügen, um aus dem PDNS einen authorativen Primary/Secondary zu machen:

# IP/Port auf dem gelauscht werden soll
local-address=0.0.0.0:53, [::]:53

# API/Webserver aktivieren und Key festlegen (Für Statistiken)
webserver=yes
webserver-address=0.0.0.0
webserver-allow-from=<euer-internes-netz>
api=yes
api-key=<hier-einen-sicheren-API-key-einfügen>

# Primary/Secondary setup
primary=yes
secondary=yes

# Default SOA festlegen
default-soa-content=<fqhn-pdns-server> <email>.<domain> 0 10800 3600 604800 3600

# AXFR deaktivieren
disable-axfr=yes

# In den meisten fällen der interne DNS Resolver wie z.B. Unbound eurer OPNsense
resolver=<ip-eures-internen-resolvers>

Anlegen, Editieren und Löschen von DNS-Zonen

Jetzt, da PowerDNS mit der Datenbank verbunden ist, erstellen wir die erste DNS-Zone. Außerdem zeige ich dir, wie du DNS-Zonen bearbeiten und löschen kannst, um die Einträge jederzeit anpassen zu können.

Wir legen uns erstmal unsere lokale Zone an:

pdnsutil create-zone <deine-domain.lan> <dein-pdns-hostname>

Damit wir deine Zone direkt mit vorkonfigurierten SOA Record sowie NS Record für unseren DNS Server angelegt. Nun brauchen wir aber mindestens noch einen A Record, der die IP unseres Nameservers auflöst:

pdnsutil add-record <deine-domain.lan> <hostname-des-servers> A <ip-des-dns-servers>

Damit haben wir nun einen A Record hinzugefügt, welcher in der Zone deine-domain.lan einen A Record hinzugefügt hat, welcher den Namen <hostname-des-servers>.<deine-domain.lan> trägt und die IP Adresse <ip-des-dns-servers> enthält. Damit kann der DNS Server intern auch aufgelöst werden.

Nun kann man natürlich weitere Records für andere Hosts hinzufügen, die auch auflösbar sein sollen. Man kann natürlich auch die Zone editieren und selber die Einträge rein schreiben:

pdnsutil edit-zone <deine-domain.lan>

Einfach mit dem gewünschten Editor Einträge hinzufügen, ändern oder löschen. Arbeitet man darüber um Einträge hinzuzufügen, zu ändern oder zu löschen wird man anschließend gefragt, ob man den Serial erhöhen möchte – das würde ich immer bestätigen. So weiß der Resolver beim abrufen der Zone, dass er nicht mehr den aktuellen Stand der Zone kennt.

Wenn man über den add-record Befehl gearbeitet hat, muss man anschließend noch den serial selbst erhöhen:

pdnsutil increase-serial <deine-domain.lan>

(Optional) OPNsense Unbound Query Forwarding Konfiguration

Für zusätzliche Flexibilität im Netzwerk richten wir Unbound Query Forwarding auf der OPNsense Firewall ein, um DNS-Anfragen für unsere interne Zone direkt an den PowerDNS-Server weiterzuleiten. Dies ist besonders hilfreich für VPN-Clients oder andere verbundene Netzwerke – so löst unser Unbound Resolver alles auf und wenn es speziell um die deine-domain.lan geht, wird der Resolver sich die Antwort von deinem PowerDNS holen, da die Domain ja öffentlich nicht auflösbar ist.

Dazu gehen wir in OPNsense unter Services -> Unbound DNS und wählen hier den Punkt Query Forwarding aus. Hier tragen wir ein:

  • Domain = <deine-domain.lan>
  • IP = <IP-des-PowerDNS-Servers>
  • Server Port = <Siehe-PDNS-general-conf-Listen-Port>

Sobald das gespeichert und anschließend per Apply bestätigt ist, wird die Auflösung über den Unbound DNS Resolver funktionieren!

Einrichten des Unbound Resolvers auf Clients und Servern

Damit alle Clients und Server im internen Netzwerk unsere DNS-Zone auflösen können, konfigurieren wir den Unbound Resolver als DNS-Server auf den jeweiligen Geräten, sodass die Anfragen korrekt weitergeleitet werden.

Unter Debian empfehle ich dabei in der /etc/network/interfaces einmal die Zeile dns-nameservers <deine-unbound-resolver-ip> <ip-eines-guten-öffentlichen-resolvers> einzupflegen. Weiter ist es hilfreich, die Zeile dns-search <deine-domain.lan> hinzuzufügen.

Wie man auf den unterschiedlichsten Clients die DNS Server konfiguriert, kann hier nicht abgespiegelt werden. Bei Fragen oder Probleme stehe ich natürlich gerne zur Verfügung.

Testen der Namensauflösung

Zu guter Letzt führen wir einen Test durch, um sicherzustellen, dass die Namensauflösung korrekt funktioniert. So prüfen wir, ob alle Einträge ordnungsgemäß aufgelöst werden und die Konfiguration wie geplant greift.

Wir verbinden uns also auf irgendein System welches den dig Befehl hat und selbst den Unbound Resolver benutzt. Nun versuchen wir mittels dig A <hostname-des-dns-servers>.<deine-domain.lan> +short aufzulösen. Du solltest die IP Adresse die wir per Record eingetragen haben zurück bekommen.

Fazit

Mit der PowerDNS-Lösung in Kombination mit einem SQL-Backend hast du eine leistungsfähige und flexible DNS-Infrastruktur geschaffen, die perfekt für interne Netzwerke geeignet ist. Durch die Integration mit OPNsense und Unbound hast du außerdem die Möglichkeit, eine zentrale Namensauflösung für alle Geräte, einschließlich VPN-Clients, zu realisieren. Diese Lösung sorgt nicht nur für Stabilität und Effizienz im Netzwerk, sondern vereinfacht auch die Verwaltung von DNS-Zonen erheblich. Einmal eingerichtet, kannst du die DNS-Konfiguration problemlos an die Bedürfnisse deines Netzwerks anpassen und so für einen reibungslosen Betrieb sorgen.

Schreibe einen Kommentar