MDXDave.de

IT-Freelancer // Android + Coding

Laden...

PowerDNS Nameserver mit MariaDB und DNSSEC/TLSA

veröffentlicht vor 9 Jahren, am 11. April 2015  |  aktualisiert vor 1 Jahr  |  0 Kommentare

PowerDNS ist eine Nameserver-Software für Linux, Windows, Mac OS X, FreeBSD uva. In dieser Anleitung will ich zeigen wie einfach die Einrichtung des Nameservers funktioniert und wie einzelne oder alle Zonen via DNSSEC und TLSA gesichert werden können.

Ein Nameserver wird zur Auflösung eines Namens (einer Domain), wie beispielsweise mdxdave.de zur dazugehörigen IP-Adresse benötigt (in diesem Fall IPv4: 144.76.194.92 oder IPv6: 2a01:4f8:200:7056::4).

DNSSEC ist ein Sicherheitsmechanismus der durch eine digitale Signierung den Nutzern garantiert, dass die Daten von der vorhergesehenen Quelle stammen und nicht auf dem Übertragungsweg modifiziert werden. Weitere Informationen zu DNSSEC gibt es sehr verständlich erklärt von Verisign. Die meisten Top-Level-Domains unterstützen aktuell DNSSEC.

TLSA, bzw. DANE sind ein weiteres Sicherheitsfeature, dass bei dem Aufruf einer Adresse wie "https://mdxdave.de" garantiert, dass das Zertifikat vertrauenswürdig ist. Mehr Informationen dazu bei Wikipedia.

Im nachfolgenden werden wir also zunächst einen Nameserver mit PowerDNS einrichten und Zonen anlegen. Anschließend werden wir diese via DNSSEC und TLSA/DANE sichern.

Als Betriebssystem kommt Debian Wheezy 11 ("Bullseye") 64-Bit zum Einsatz, statt MySQL nutzen wir den MariaDB-Datenbankserver (mit MySQL sollte die Einrichtung jedoch identisch funktionieren).

Schritt 1: Installation und Konfiguration von PowerDNS

Da das PowerDNS-Paket im Debian Repository veraltet ist, empfiehlt sich die Installation über das Repository von PowerDNS. Folgt hierzu der Anleitung unter nachfolgendem Link:

doc.powerdns.com

Schritt 2: Einrichtung Datenbank

Der folgende Abschnitt ist evtl. veraltet.

Als erstes erstellen wir eine neue Datenbank, wofür wir uns zunächst an den MySQL-/MariaDB-Server anmelden:

mysql -u root -p

Dann erstellen wir eine neue Datenbank nameserver, einen neuen Nutzer nameserver und erteilen diesem das Recht auf den Zugriff auf die eben angelegte Datenbank:

MariaDB> CREATE DATABASE nameserver
MariaDB> CREATE USER 'nameserver@localhost' IDENTIFIED BY 'abcdefg';
MariaDB> GRANT ALL PRIVILEGES ON nameserver.* TO 'nameserver'@'localhost';

Im Code ersetzt ihr natürlich abdefg durch ein vernünftiges und sicheres Passwort, den Namen der Datenabnk & des Nutzers könnt ihr auch anpassen.

Danach öffnen wir die Datei /etc/powerdns/pdns.conf

nano /etc/powerdns/pdns.conf

und fügen folgendes an das Ende der Datei:

launch=gmysql
gmysql-host=localhost gmysql-user=nameserver
gmysql-dbname=nameserver
gmysql-password=abcdefg
gmysql-dnssec=yes

Die Zeile launch=gmysql weißt PowerDNS daraufhin, dass wir das MySQL-Backend nutzen möchten, die weiteren Zeilen geben die Datenbank-Zugangsdaten sowie die Datenbank an und aktivieren die Nutzung von DNSSEC über MySQL.

Anschließend starten wir PowerDNS im Monitor-Modus um die Funktionsfähigkeit zu prüfen:

service pdns monitor

Sofern alles funktioniert hat, können wir nun die Datenbankstruktur anlegen:

wget "https://gist.githubusercontent.com/MDXDave/2041a94e87b0239698e7/raw/2f69938946241da06f58a996332c081544076e0e/gistfile1.sql" -O /root/install/db.sql
mysql -u nameserver -p
MariaDB> USE nameserver;
MariaDB> SOURCE /root/install/db.sql

Im Anschluss starten wir PowerDNS:

sudo systemctl start pdns.service

Schritt 3: Zonen in PowerDNS anlegen

Wir öffnen erneut die MySQL-/MariaDB-Konsole und fügen unsere erste Zone hinzu:

MariaDB> INSERT INTO domains (name, type) VALUES ('example.com', 'native');

Anschließend fügen wir einige Records für die eben angelegte Zone hinzu, zunächst den SOA-Record, dann einen A-Record und AAAA-Record und dann zwei NS-Records, los gehts:

MariaDB> INSERT INTO records (domain_id, name, type, content, ttl, auth) VALUES (1, 'example.com', 'SOA', 'primaryns.example.com nameserveradmin.example.com 2015041101 28800 7200 604800 864000', 7200, 1);
MariaDB> INSERT INTO records (domain_id, name, type, content, ttl, auth) VALUES (1, 'example.com', 'A', '1.2.3.4', 3600, 1);
MariaDB> INSERT INTO records (domain_id, name, type, content, ttl, auth) VALUES (1, 'example.com', 'AAAA', '2a01:1234:1234:1234:ffff:1', 3600, 1);
MariaDB> INSERT INTO records (domain_id, name, type, content, ttl, auth) VALUES (1, 'mdxdave.de', 'NS', 'primarynameserver.example.com', 7200, 1);
MariaDB> INSERT INTO records (domain_id, name, type, content, ttl, auth) VALUES (1, 'mdxdave.de', 'NS', 'secondarynameserver.example.com', 7200, 1);

Nun können wir eine Anfrage an den Nameserver stellen, um die Eintragung unserer Zone und den Records zu prüfen:

dig example.com @127.0.0.1 any

das Ergbniss sollte so ähnlich lauten

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> example.com @127.0.0.1 any
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5734
;; flags: qr aa rd; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;example.com. IN ANY
;; ANSWER SECTION:
example.com. 3600 IN AAAA 2a01:1234:1234:1234:ffff:1
example.com. 7200 IN SOA primarynameserver.example.com. nameserveradmin.example.com. 2015041001 28800 7200 604800 864000
example.com. 7200 IN NS secondarynameserver.example.com.
example.com. 3600 IN A 1.2.3.4
example.com. 7200 IN NS secondarynameserver.example.com.

Falls euch das manuelle Eintragen von Domains und Records zu umständlich ist, könnt ihr auch eins von zahlreichen Webinterfaces nutzen.

Schritt 4: DNSSEC

Nachdem die normale Abfrage unserer Domain nun funktioniert und die korrekten Einträge zurückliefert, können wir DNSSEC für unsere Domain einrichten.

Hierzu geben wir folgenden Befehl ein:

pdnsutil secure-zone example.com

Danach prüfen wir die Erzeugung des DNSSEC-Eintrags mittels

dig example.com @127.0.0.1 DNSKEY +dnssec

Als nächstest suchen wir die notwendigen Informationen heraus, die der Provider der Domain der Root-Zone übergeben muss, dafür geben wir ein

pdnsutil show-zone example.com

anschließend erhalten wir soetwas

keys:
ID = 1 (KSK), tag = 28526, algo = 8, bits = 2048 Active: 1 ( RSASHA256 )
KSK DNSKEY = example.com IN DNSKEY 257 3 8 AwEAAcWGQHigJLuQqq6yf/nNNoCQuxNgbufxG5jJU6329cNvaCOExV+B+eAs7VWCm9iCLA614owGXDgTUOEeOIDiVZIZcvIm7HL8wckHBmrX9um+Vtnc0EtRjEcfL5qxSudeh3s4Gr+HZU1ruACwzzdnbV0EBc3AVC+uxsrmOdWzYtuvxtTOpKLAzBMgOXg5nbozlHR2+ZAEzKhkudl7Dg/aWg6nXg/QhHVDApudfK1Fc8Lyi745cjdPhb8f9ivSrwU9UXnQ/Cp0ebQ90upOmlu4QBxUSy6AEvAzjvEI7G+MTR+FDFAdqQrKSmNcEV2yDWcTLVgpNGF8w1HM+Ri/nmX3mQ8= ; ( RSASHA256 )
DS = example.com IN DS 28526 8 1 a3ba957f75613d2e70d26037dbbf858e9fa91632 ; ( SHA1 digest )
DS = example.com IN DS 28526 8 2 f0f4bb7cef3b3a3f772bf0d17343b42673177a8fb5d32d3ac29a168d09584114 ; ( SHA256 digest )
DS = example.com IN DS 28526 8 3 661410ce29b453132f147f5aa098c5fbb636fef0cb76bd1d861cf8aaa20d476b ; ( GOST R 34.11-94 digest )
DS = example.com IN DS 28526 8 4 dc5688308e1a23a6bc5f6194f687cb893b42c10b74e462542af09202dbb97b4d8a0224458ed08bc68605c6c6e91bede6 ; ( SHA-384 digest )
ID = 2 (ZSK), tag = 26968, algo = 8, bits = 1024 Active: 1 ( RSASHA256 )

Wir kopieren nun den String bei DNSKEY 257 3 8, beginnend mit AwEAA... bis zum =-Zeichen.

Diesen Schlüssel müssen wir nun der Root-Zone unserer TLD mitteilen, also beispielsweise der .com-Zone. Dafür muss der Aschlüssel an den Provider übermittelt werden, dies kann sowohl automatisch als auch manuell geschehen.

Am Beispiel von OVH:

Bei öffentlicher Schlüssel kommt der lange String rein, den wir eben kopiert haben, bei Algorithmus und Flags wählen wir die Zahl nach DNSKEY für Flags (in diesem Fall 257) und die Zahl bei algo = 8 für den Algorithmus (in diesem Fall 8) aus. Als "Kennung" geben wir die Zahl ein, die bei tag = steht (hier: 28526).

Anschließend speichern wir die Daten. Nach max. 24 Stunden sollte die Zone nun komplett durch DNSSEC gesichert sein.

Schritt 5: DANE/TLSA-Eintrag

Da wir hier die SSL-Verschlüsselung, bzw. das genutzte Zertifikat sichern, macht das natürlich nur Sinn, wenn die Domain auch via HTTPS aufgerufen werden kann.

Nach RFC 6698 gibt es mehrere Optionen, wir nutzen DANE-EE (3), mit dem vollen Zertifikat (0) und mit SHA-256 HASH (1)- Zunächst erzeugen wir den SHA-256-Hash unseres Zertifikats, dafür wechseln wir in den Ordner mit dem Zertifikat example.com.crt und führend folgendes aus:

openssl x509 -in example.com.crt -outform DER | openssl sha256

Den Hash hinter (stdin)= kopieren wir (ohne Leerzeichen) und erstellen folgenden RR-Eintrag für unsere Zone example.com:

_443._tcp.example.com IN TLSA 3 0 1 bbab50f183682019691f4dc352f86fd5fe2a8ad0e2d00f265400de382eaf86f6

Zur Erläuterung: _443 steht für den Port, über welchen der Zugriff erfolgt, SSL/TLS, bzw. HTTPS laufen über Port 443 (bei IMAP-SSL beispielsweise _143 für Port 143 oder _993 für Port 993), _tcp stellt das Netzwerkprotokoll TCP dar, TLSA ist der Record-Type und die drei Zahlen 3 0 1 stellen die oben aufgelisteten Optionen dar.

Unser Eintrag in der Datenbank müsste wie folgt eingetragen werden:

MariaDB> INSERT INTO records (domain_id, name, type, content, ttl, auth) VALUES (1, '_443._tcp.example.com', 'TLSA', '3 0 1 bbab50f183682019691f4dc352f86fd5fe2a8ad0e2d00f265400de382eaf86f6', 7200, 1);

Wichtiger Hinweis: Sofern eure Domain unter example.com und unter www.example.com erreichbar ist, benötigt ihr zwei TLSA-Einträge, einen für _443._tcp.example.com und einen für _443._tcp.www.example.com

Schritt 6: Prüfen aller Einträge, DNSSEC und DANE

Nachdem wir nun unsere Einträge eingetragen haben, die Zone durch DNSSEC gesichert und unser SSL-Zertifikat mittels DANE geprüft werden kann, sollten wir nun testen ob auch alles funktioniert. Dazu gibt es diverse Test-Tools im Internet.

Ein DNS-Check, der auch die Existenz und Konsistenz eines DNSSEC-Eintrags prüft findet ihr auf dnscheck.iis.se. Eine Möglichkeit die Gültigkeit des TLSA-Eintrages zu testen, findet ihr unter hde.ssl-tools.net/webservers.