IT-Freelancer // Android + Coding
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).
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:
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
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.
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.
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
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.