Das Einrichten von DNSSEC soll hier in BIND9 auf einem Debian Linux-System demonstriert werden. Vorausgesetzt es existiert bereits ein funktionierender DNS-BIND-Server wie hier beschrieben.
Alle Konfigurationsdateien für Bind9 liegen in "/etc/bind/", auf RedHat-, Centos- und Fedora-Linux-Systemen ist die Ablagestruktur etwas verschieden zu Debian. Und die Zonendateien liegen generell unterhalb von "/var/cache/bind/" strukturiert nach den TLD in eigenen Verzeichnissen wie "de", "com" etc.
Zone Walking (DNSSEC Walking bzw. Zone Enumeration) ist als ein Verfahren bekannt, bei die Angreifer den vollständigen Inhalt von DNSSEC signierten DNS-Zonen auslesen können. So können vertrauliche Daten (wie Kundenlisten) und sicherheitsrelevante Informationen (Server-IP-Adressen) abgegriffen werden.
DNSSEC verkettet automatisch beim Signieren einer Zone mittels NSEC Resource Records alle Labels ringförmig in alphabetischer Reihenfolge. Am Beispiel der Zone example.tld sieht das so aus
example.tld. NSEC name1
name1 NSEC name2
name2 NSEC name5
name5 NSEC example.tld.
Auf der linken Seite steht jeweils das Label (kanonischer Name) und rechts davon ein Verweis auf das lexigrafisch nächste Label. Auf diese Weise kann die Nichtexistenz von Namen bewiesen werden. Fragt also ein Client den nichtexistierenden Namen name3 an, dan antwortet der DNS-Server mit dem NSEC-Eintrag name2 NSEC name5 und siganlisiert somit, dass zwischen name2 und name5 kein weiterer Eintrag existiert. Der Angreifer macht sich diese Verkettung zunutze, indem er mit dem ersten Namen einer Zone beginnend (das ist immer der Name der Zone selbst) die Kette durch sukzessive Abfragen durchläuft. Durch dieses technisch recht einfache Verfahren kann er innerhalb weniger Sekunden den gesamten Zoneninhalt auslesen.
Das Zone Walking lässt mit der Alternative zu NSEC, nämlich NSEC3, deutlich erschweren. NSEC3 stellt die Namen nicht mehr im Klartext dar, sondern als einen kryptographischen Hashwert. NSEC3 erschwert zwar somit das Zone Walking, aber es kann Angriffe auf die Hash-Funktion das Zone Walking nicht komplett vermeiden. Deshalb soll die nachfolgende Konfiguration mit NSEC3 erfolgen.
Vorab hier noch die Erklärungen zu DNSSEC, KSK, ZKS und RRSIG.
So wird für jede Zone, die abgesichert werden soll, ein eigener Zonenschlüssel (Zone Signing Key) bestehend aus einem öffentlichen und einem privaten Schlüssel erzeugt. Der öffentliche Teil des ZSK existiert dann in der jeweiligen Zonendatei als DNSKEY Resource Record. Mit dem privaten Schlüssel jedoch, wird dann jeder einzelne RR in der Zone digital unterschrieben.
Zusätzlich wird zum Schlüssel für die Signatur der Zone (ZSK) ein syntaktisch identischer Schlüsselunterzeichnungs-Schlüssel KSK (Key Signing Key) generiert. Der Hintergrund dazu ist die Tatsache, dass sich die Zonenkeys (DNSKEY) öftere ändern können und bei einer Chain of Trust, die Parent-Zone der Child-Zone nicht mehr vertrauen würde. Nachdem aber für diesen Fall der KSK für einen langen Zeitraum der gleiche bleibt, bleiben somit bei Änderungen auch die Chain of Trust zwischen Parent- und Child-Zone erhalten. Andernfalls müsste die Child-Zone der Parent-Zone kontinuierlich neue Schlüssel mitteilen, was sich durchaus als sehr ineffizient und fehleranfällig gestalten kann.
Letztlich wird die Zone mittels der DNSKEYs signiert, während die Resource Records über die RRSIGs signiert werden.
Zunächst legen wir der besseren Strukturierung halber ein neues Verzeichnis innerhalb des Bind9-Konfigurationsverzeichnisses an.
mkdir -p /etc/bind/keys/
chown -R bind:bind /etc/bind/keys/
Innerhalb dieses neuen Verzeichnisses wird der KSK mit folgenden Befehl erzeugt:
dnssec-keygen -3 -a RSASHA512 -b 4096 -n ZONE -r /dev/urandom -f KSK example.tld
In dem Verzeichnis liegen jetzt zwei Dateien:
Kexample.tld.+010+64413.key (DNSKEY Record),
der dem Verifizieren der ZSKs dient und von höheren Zonen signiert wird.
Kexample.tld.+010+64413.private,
dem privaten Schlüssel zur Signatur des öffentlichen ZSK.
Der DNSKEY Record im öffentlichen Schlüssel sieht etwa so aus:
cat Kexample.tld.+010+64413.key
; This is a key-signing key, keyid 64413, for example.tld.
; Created: 20200313175118 (Fri Mar 13 18:51:18 2020)
; Publish: 20200313175118 (Fri Mar 13 18:51:18 2020)
; Activate: 20200313175118 (Fri Mar 13 18:51:18 2020)
example.tld. IN DNSKEY 257 3 10 AwEAAaoJiFk+Xj+9v[...]KTMN4QNqRm8l1RgnDq/2GvrxmSPXfGKyWm fjvSJot4EX2i97ER
Den Zone Signing Key erzeugt man im Anschluß daran wie folgt, gefolgt von einer Neuzuordnung der Dateiattribute.
dnssec-keygen -3 -a NSEC3RSASHA1 -b 2048 -n ZONE -r /dev/urandom example.tld
chown -R bind:bind /etc/bind/keys/
Jetzt liegen zwei weitere Dateien in dem Verzeichnis:
Der Inhalt dieses ZSK stellt sich in etwa so dar.
cat Kexample.tld.+007+40385.key
; This is a zone-signing key, keyid 40385, for example.tld.
; Created: 20200313175211 (Fri Mar 13 18:52:11 2020)
; Publish: 20200313175211 (Fri Mar 13 18:52:11 2020)
; Activate: 20200313175211 (Fri Mar 13 18:52:11 2020)
example.tld. IN DNSKEY 256 3 7 AwEAAauXGNQMitXTRPKAkme9[...]Mqi3ZvO 0yn19+nxfb8=
Jetzt kann die Zone in der jeweiligen Zonendatei durch das Hinzufügen der öffentlichen Schlüssel mittels der $INCLUDE-Direktive für die Signatur vorbereitet werden. Das lässt zum Einen einfach über eine Schleife erledigen
for key in `ls Kexample.tld.*.key`
do
echo "\$INCLUDE /etc/bind/keys/$key">> /var/cache/bind/tld/db.example.tld
done
oder einzeln pro Zonendatei mit einer vi-Funktion:
:r! ls /etc/bind/keys/Kexample.tld.*.key
Durch das Signieren wird gleichzeitig eine neue Zonendatei mit dem Suffix ".signed" erzeugt.
dnssec-signzone -3 `head -c 512 /dev/urandom | sha1sum | cut -b 1-16` -z -H 330 -K /etc/bind/keys -t -o example.tld /var/cache/bind/tld/db.example.tld
Verifying the zone using the following algorithms: NSEC3RSASHA1 RSASHA512.
Zone fully signed:
Algorithm: NSEC3RSASHA1: KSKs: 0 active, 0 stand-by, 0 revoked
ZSKs: 1 active, 0 stand-by, 0 revoked
Algorithm: RSASHA512: KSKs: 1 active, 0 stand-by, 0 revoked
ZSKs: 0 active, 0 stand-by, 0 revoked
/var/cache/bind/tld/db.example.tld.signed
Signatures generated: 26
Signatures retained: 0
Signatures dropped: 0
Signatures successfully verified: 0
Signatures unsuccessfully verified: 0
Signing time in seconds: 0.315
Signatures per second: 82.418
Runtime in seconds: 0.358
chown -R bind:bind /var/cache/bind/
Allerdings ist jetzt zu beachten, dass nach jeder Änderung in der Zonendatei, diese auch neu signiert werden muss.
Zusätzlich sind die signierten Zonen per Default nur 30 Tage lang gültig. Ein eigenes Enddatum für die Gültigkeit der signierten Zonendatei kann man dnssec-signzone mit "-e YYYYMMDDHHMMSS" mitgeben.
In den globalen Options von BIND9 aktiviert man DNSSEC mit folgenden Einträgen in /etc/bind/named.conf.options
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;
key-directory "/etc/bind/keys/";
In der Datei /etc/bind/named.conf.local ändert man nur in den Zonendeklarationen das file von
zone "example.tld" {
type master;
file "tld/db.example.tld";
allow-transfer {
"slaves";
};
notify yes;
};
nach
zone "example.tld" {
type master;
file "tld/db.example.tld.signed";
allow-transfer {
"slaves";
};
notify yes;
};
und startet den BIND9 neu
systemctl restart bind9.service
Abschliessend ist das DNSSEC bei dem eigenen Registrar zu aktivieren. Das geschieht meistens auf deren Webportalen, indem man den DNSKEY RR passend zur Zone eingeben muss und zusätzlich DS Record. Dazu wartet man bis das AXFR der Nameserver des Registrars erfolgt sind und eine Abfrage
dig DNSKEY example.tld
positiv den DNSKEY liefert. Dann nämlich weiß man, dass sich die Zonen synchronisiert haben. Man bekommt den DNSSEC sowohl für den Zonenschlüssel (256) als auch den Schlüsselunterzeichnungs-Schlüssel (257) angezeigt. Beim Registrar einzutragen ist Letzterer mit dem Flag 257. Zusätzlich wird der Delegation Signer Record (DS-RR) - dieser enthält den Digest des KSK Public Keys - einzutragen sein. Letzerer befindet sich in einer zusätzlichen Datei "dsset-example.tld." in dem Verzeichnis, von dem man "dnssec-signzone" gestartet hat, deren Inhalte man dazu übernehmen kann:
cat dsset-example.tld.
example.tld. IN DS 40385 7 1 CDD805F6E544091910FF821AEB6D83756F02A23E
example.tld. IN DS 40385 7 2 75D763812727198BD0B5FD4F5FCA59B96262D0EF390A435829FC66E8 9492D462
example.tld. IN DS 64413 10 1 43DF817F6558611A58617C8017338F76E6015AE5
example.tld. IN DS 64413 10 2 096EEEFF5E66BA5DC03930D3A567BE57247FEDDFBAFB5142508B24CB B2B153F8
Wenn man jetzt den DNS-Server abfragt oder andere Nameserver, sofern man das DNSSEC bei seinem Registrar bereits aktiviert hat, so erhält man diese Informationen.
dig example.tld dnskey +noall +answer +multiline
; <<>> DiG 9.11.5-P4-5.1-Debian <<>> example.tld dnskey +noall +answer +multiline
;; global options: +cmd
example.tld. 86400 IN DNSKEY 257 3 10 (
AwEAAaoJiFk+Xj+9vRrKq2pdaFkwCKaGy1QNMbn/aQYT
G5czj9aO/o400mS8YfEMGC3U+AY0INliajs7sfeVuuFv
JYbmkLpJGIbF1/3Tr/8jzENJSEqxCh6y5iFz7HdgMat8
+TekfyaDf30reM61l8G1BN3fcaFHf2DRv0+AkD/eY/kd
Id+ngvQ1ifzk3tZNxIjeClEdQ7D2OTAazagcDl+vSKWh
zo3iSwyjMnboAo0RdHMKSuxgSDkMOch9DIih5SVKRZy5
zq9kJfuCPpgVAnjjB2oZ0K2rpKu2FPHhV5zV9T2m2cBw
YpldTobuAN8Ouj8m72y4RdrI5ik1GOA4HzlUg0zKnaLh
L1Y+Mxo2Qz9hJMJ+rKifpcY72e5/FX9addolaqOjBX44
FvHJWaxcAjVVqFfPfgkMLMtcJY0YVMr694rNecfAFfVh
n8UwQk9epq1xDI3D1pH8/HzmEdM7lK9FLIx++fDtkpXq
V7f5dorwm92kGZpdtZ/LeCnFGpfLNeu4heQJ587pnwap
j/wbNUF4IPuTkuEpKJReQzWQ0gWp0yU3kDn7vcXD7Eee
+3Atoobq6wwOsrkUXl1FVaF3rOm6L82S3dvtB/SSuHCF
jcdy33tlv1nE5cjaBZHRChKTMN4QNqRm8l1RgnDq/2Gv
rxmSPXfGKyWmfjvSJot4EX2i97ER
) ; KSK; alg = RSASHA512 ; key id = 64413
example.tld. 86400 IN DNSKEY 256 3 7 (
AwEAAauXGNQMitXTRPKAkme9Gs7MvrHgNeNJddafYO7F
5i/TsLre8zitWD/+bJZXx0Vu89QTjKX9zQwhSRegwFvH
4gfe4Hvo0SHt9YsMGwA1LDW9RfFXDCGWEemDnAxX0NV9
330BSYyQ2fVrPpJoyB+et/BrLi/IzBrrFXB+O24jkBYW
TK0khA9c1lAk//nWEVstarXZgmz2WlF4//aPUpGqOnDL
jbv1gXo3vUfcSBN2EcAaXAyTSGTaJUA6I6BEFbN1id2g
bFI/RsVa0dYo3imvn46IgroVmDhx+LbKlMq71GhePyaW
zaZX8Bmi8Y9IxlJV5+UizMqi3ZvO0yn19+nxfb8=
) ; ZSK; alg = NSEC3RSASHA1 ; key id = 40385
Wenn man in dig die Option +dnssec mit nutzt, dann werden auch die RRSIG Records angezeigt:
dig A www.example.tld +dnssec
; <<>> DiG 9.11.5-P4-5.1-Debian <<>> A www.example.tld +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45983
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 7, ADDITIONAL: 2
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; COOKIE: e6717cb28dcc8637149ebe435e6f790ddf6237e8cfc03713 (good)
;; QUESTION SECTION:
;www.example.tld. IN A
;; ANSWER SECTION:
www.example.tld. 86400 IN A 79.143.191.49
www.example.tld. 86400 IN RRSIG A 7 3 86400 20200415110953 20200316110953 40385 example.tld. DYnaFMQaVpOO3VA8ZYg7K3YKHMgl4+UFLXjgUt35GLYLrUwO5XKQwr+T LKlBukkIgC2zUVVZSuIGoDv8rDGCeBED2d0KrnVjdQjqS00ZUOCGUU27 vagd/u6DuHUF0VVWgHU8fjWG1+S4rqRov3pSQ0gCq5JaYFOZZXeKCcq4 cmcL/9dQbdL5h1JArqxJoNtQOnlKw7JtifWAHRtWPX7eQ4tbq6TA9fR3 SQ/nde4ZP6dRDyv2OcO3lpfhc/JDbeyksu11nfp8WLjjDTsY5D2mC4bA a0kL9H357OiKtLiwLSCOM/zYa/gq+2wUDOSnG/zX7jfKvDr+rQWKcAvV l1/apg==
www.example.tld. 86400 IN RRSIG A 10 3 86400 20200415110953 20200316110953 64413 example.tld. kCA+W2mn/Hvgx50L51DJzMqRluiYp/m2Gb8DLHqNmu7kSNmFYmpq+jvk caEcBroZaoyalsGAFJas+NlYHQGZFyzJKav1dujb0I8nUDsG7TGnmH70 lVpP6qqvo2pveZYeq50q7BKt49mIoEiYMbFyGW4i6oR0w+ueshb/BgqN FlMzDOk99aKRBwV+JmxImcVKZIfYtQ/Q7z20z7rZVBUcL9yUsCSo7J4N OmABeSxwH2Y63eChTDCuFfy5ngnCD+Iqr2HT9X+Y2oz7g3hsuUPP9PHD s4ingQo+aQ2PPzO6endmwsq27XBJ8M0jurEA2oSmoj4d5qZvcknlJ/Us YIZmF8Q/uKSqg9Z4wF+okYo/meC3wRtdsDWoW7irO47Ion0whVvj16X8 fiVn9eHBa1SNf+D+EpRRog8dlEuaK2ScFJDVdzx4JX3ps9b1hVPqlpPa b1uMYRQJpKfc2IZjwkiAcwcTW95tasuvpg8t1ZUOHgumf2f7eS5VwLsv cR2GRn+NGO9o9TrjYRddArSkodDecOY0Ac4OEgq2allTTw7IPMYabyXz 5UzVKQVJ2NXfvZyfR000yf1etx2jXcdB7yBXcTyfyE+C+sUIB72d5TKg z+/bcO/7Zgryp9ixvwM/qFexFqYHD5WuEuAbOGf1sq7gZF2HxnCK+DuI Swpt61A34V0=
Online lassen die DNSSEC Konfigurationen ebenfalls prüfen. So zum Beispiel der DNSSEC-Debugger von Verisign Labs.