dnssec-keymgr (aus BIND 9.11)
Existieren bereits Keys (beispielsweise unter vorheriger manueller Verwaltung), die nach den Regeln der keymgr-Policy bereits abgelaufen sind (also deren Activation-Time vor mehr als roll-period + post-publish liegt), so wird der Schlüssel sofort inaktiviert und aus der Zone gelöscht. Dies führt zu einem unkoordinierten ZSK-Rollover mit Ausfällen durch im Resolver gecachten RRSIGs, zu denen kein DNSKEY mehr gefunden werden kann.
Der Bug ist unter https://gitlab.isc.org/isc-projects/bind9/issues/117 gemeldet.
Workaround könnte sein, bei allen Keys vor der Ausführung von dnssec-keymgr die Activation-Time neu zu setzen. Umgetestet!
for i in *.key; do dnssec-settime -A +0 $i; done
Zum Signieren von Zonen werden gültige DNSKEYs benötigt. Mit BIND <= 9.10 muss man diese per Hand erzeugen, damit BIND Zonen dann regelmäßig neu signiert. Läuft der letzte Schlüssel ab, ohne dass neue erzeugt wurden, sind die Signaturen der Zone ungültig, validierende Nameserver erhalten ein SERVFAIL als autoritative Antwort und die Zone ist nicht erreichbar.
Die Sicherstellung der Erzeugung von neuen Schlüsseln ist damit eine lästige Fehlerquelle.
BIND 9.11 führt den sogenannten dnssec-keymgr ein, mit dem anhand einer Policy, die Richtlinien zur Erzeugung neuer Schlüssel definiert, Schlüssel nicht nur für eine Periode automatisch erzeugt werden können, sondern über regelmäßigen Aufruf des dnssec-keymgrs (z.B. in einem cron-job) für weitere Perioden generiert werden. Dies erlaubt ein Schlüsselmanagement ohne Interaktion durch Systemverantwortliche.
Es ist daher zu empfehlen, einen Umstieg auf BIND 9.11 in Erwägung zu ziehen. BIND 9.11 ist aber unter Umständen noch nicht in den Repositories der Distributionen verfügbar und wird in vielen Fällen nur für neue Distributionsversionen verfügbar sein.
dnssec-keymgr ist allerdings eine Python-Anwendung, die weitestgehend unabhängig von den Quellen der BIND-Version ist. Die Anwendung dnssec-keymgr und die Python-Pakete, die von ihr benutzt werden, können auf Systeme mit älteren BIND-Versionen kopiert werden und dort der dnssec-keymgr aufgerufen werden.
Die Erzeugung von gültigen Schlüsseln hängt nur von einer gültigen policy-Datei ab, und die so erzeugten DNSKEYs werden dann klaglos von BIND 9.9.5, mit dem wir am LRZ den Test durchgeführt haben, verwendet.
Schritt-für-Schritt-Anleitung
Um den dnssec-keymgr auf einem BIND 9.9.x zu installieren geht man am besten wie folgt vor.
- BIND 9.11-Quellen entpacken und
./configure
laufen lassen - Im Verzeichnis ./bin/python/ make ausführen
- Python isc-Package-Dateien kopieren
- dnssec-keymgr kopieren
- Policy-Datei anlegen
- Schlüssel-Verwaltung mit dnssec-keymgr
- BIND 9.9.x für automatisches dnssec konfigurieren
BIND 9.11-Installation
Im Netz finden sich dazu auch Tutorials, wenn man sich über die Vorgehensweise unsicher ist, z.B.
http://www.linuxfromscratch.org/blfs/view/cvs/server/bind.htmlDownloaden der Quellen
wget https://www.isc.org/downloads/file/bind-9-11-0-p1/ -O bind-9.11.0-P1.tar.gz
Upacken in ein temporäres Verzeichnistar xzf bind-9.11.0-P1.tar.gz
Die folgenden Abhängigkeiten existieren und sollten am besten mit dem Paketmanager nach-installiert werdenapt-get install g++ libssl-dev python-ply
Im configure-Schritt muss angegeben werden, dass BIND mit Python-Unterstützung gebaut werden soll./configure --with-python=`which python`
BIND muss nicht mehr kompiliert werden, da die notwendigen Ersetzungen bereits beim ./configure-Schritt durchgeführt wurden. Eine Installation ist ebenfalls nicht nötig, d.h. dieser Vorgang kann auch durch einen nicht privilegierten Benutzer ausgeführt werden.
Auch einige der Python-Module für den Keymgr werden erst aus anderen zusammen gebaut. Daher ist ein Make-Schritt nötig. Dieser muss aber nur in <PATHTOSOURCES>/bin/python ausgeführt werden:
makeUns interessieren der dnssec-keymgr, der sich, zusammen mit den anderen dnssec-Programmen in
./bin/python/
befindet.Auch einige der Python-Module für den Keymgr werden erst aus anderen zusammen gebaut. Daher ist ein Make-Schritt nötig. Dieser muss aber nur in <PATHTOSOURCES>/bin/python ausgeführt werden:
cd <PATHTOSOURCES>/bin/pythonmake
- Python isc-Package-Dateien kopieren
In ./bin/python/ befindet sich ein Unterverzeichnis "isc", das die BIND-9.11-Pythonmodule beinhaltet. - dnssec-keymgr kopieren
dnssec-keymgr ist selbst zwar nur ein wrapper, beinhaltet aber die Python __main__-Funktion und wird zum Schlüsselmanagement aufgerufen.import os
import sys
sys.path.insert(0, os.path.dirname(sys.argv[0]))
if os.name != 'nt':
sys.path.insert(1, os.path.join('/usr/local', 'lib'))
import isc.keymgr
if __name__ == "__main__":
isc.keymgr.main()
Es muss sicher gestellt werden, dass die "isc,keymgr"-Pythonmodule gefunden werden. Als privilegierter Benutzer können diese nach /usr/lib/python2.7/site-packages kopiert werden. Es ist aber auch möglich die Umgebungsvariable $PYTHONPATH um ein entsprechendes Verzeichnis zu erweitern, wo die Pakete als unprivilegierter Benutzer, abgelegt wurden, zu finden sind. Policy-Datei erstellen
BIND-9.11 verwendet zwar sinnvolle Default-Parameter, wenn keine /etc/dnssec-policy.conf vorhanden ist, und auch ansonsten keine gelesen wird, aber man hat mit einer angepassten Policy-Datei bessere Kontrolle über das Schlüsselmanagement.dnssec-policy.conf Verzeichnis
Je nach Distribution unterscheidet sich unter Umständen das Verzeichnis, in dem die dnssec-policy.conf gesucht wird. Im allgemeinen ist das dasselbe Verzeichnis, in dem sich auch named.conf befindet.
Das Kommando
python -c "from isc import utils; print(utils.sysconfdir)"
liefert das Verzeichnis zurück.
Beispiel dnssec-policy.conf-Datei:policy default {
algorithm RSASHA256; # RSASHA256-Algorithmus verwenden
directory "/var/bind/keys"; # Verzeichnis, in dem die Schlüssel abgelegt werden
# Key parameters
keyttl 86400; # TTL der Schlüssel
key-size ksk 2048; # 2048 Bit Key-signing key
key-size zsk 2048; # 2048 Bit Zone-signing key
# roll parameters
#roll-period ksk 2y; # Manuelle Interaktion mit der parent-Zone nötig, kein KSK-rollover zu empfehlen!
roll-period zsk 6mo; # 6 Monate
#standby ksk 1; # 1 KSK als standby pro Zone vorhalten (noch nicht implementiert!)
#standby zsk 1; # 1 ZSK als standby pro Zone vorhalten (noch nicht implementiert!)
pre-publish zsk 20d; # pre-publish ZSK 20 Tage
post-publish zsk 20d; # post-publish ZSK 20 Tage
pre-publish ksk 20d;
post-publish ksk 20d;
};
zone dev.ws.dnssec.bayern { # Zonen-spefizische Parameter
coverage 1y; # coverage-Periode für die Schlüssel erzeugt werden
policy default; # "default"-Policy für diese Zone anwenden
};
NB: Das in der dnssec-policy.conf angegebene Schlüsselverzeichnis muss existieren
dnssec-keymgr erlaubt auch einen Rollover des KSK. Da dies aber immer noch eine manuelle Interaktion mit dem Registrar der TLD erfordert, um den DS-Record der Parentzone anzupassen, ist das NICHT zu empfehlen!
KSK Rollover sollten durch Systemadministratoren durchgeführt werden, nachdem sichergestellt wurde, dass ein entsprechender DS-Eintrag für den neuen Schlüssel in der Parentzone angelegt wurde. Dies kann durch Skripte unterstützt, aber NICHT AUTOMATISIERT werden.
Wenn für den KSK, wie empfohlen, keine roll-period definiert ist, wird ein KSK erzeugt, der nie automatisch inaktiv wird, z.B.:
Kdev.ws.dnssec.bayern.+007+61728.key
; This is a key-signing key, keyid 61728, for dev.ws.dnssec.bayern.
; Created: 20170116154406 (Mon Jan 16 16:44:06 2017)
; Publish: 20170116154406 (Mon Jan 16 16:44:06 2017)
; Activate: 20170116154406 (Mon Jan 16 16:44:06 2017)
dev.ws.dnssec.bayern. 400 IN DNSKEY 257 3 7 AwEAAbINck2fSoTFi4JiJbI2LfuXfIHOb7rujq3ruWSBsWZbsc7X2tdA.....
5. Schlüssel-Verwaltung
Der initiale Aufruf mit dem Zonen-Namen als Parameter erzeugt dann Schlüssel über die in "coverage" definierte Periode - falls diese nicht angegeben wurde, werden default Schlüssel für sechs Monate erzeugt:
dnssec-keymgr dev.ws.dnssec.bayern
Die Schlüssel werden dann in das unter directory angebene Verzeichnis geschrieben.
Konsekutive Aufrufe, um neue Schlüssel bei drohendem Ablauf der coverage-Periode zu erzeugen, werden am besten in einem cron-Job definiert, beispielsweise
0 1 * * * dnssec-keymgr
dnssec-keymgr sollte mindestens einmal pro Tag aufgerufen werden (in diesem Beispiel um 1:00 morgens, problemlos aber auch häufiger). Hierzu muss die Zone nicht mehr explizit angegeben werden. dnssec-keymgr erzeugt neue Schlüssel für die Zonen, für die schon Schlüssel im Schlüsselverzeichnis (z.B. /var/bin/keys) vorhanden sind.
6. BIND für das automatische Signieren konfigurieren
Damit BIND die durch dnssec-keymgr erzeugten und in /var/bind/keys/ abgelegten Schlüssel für das Signieren bei Bedarf verwendet, muss noch die Konfiguration in named.conf angepasst werden:
Das Schlüssel-Verzeichnis muss über den Parameter key-directory angegeben werden, in unserem Beispiel ist es Zonen-spezifisch. Dieses muss natürlich mit dem in der /etc/dnssec-policy.conf angegebenen übereinstimmen (oder die Schlüssel per cron kopiert werden - das verkompliziert das Ganze aber unnötig).
autodnssec maintain; veranlaßt BIND anhand der Gültigkeitsdaten in den Metadaten der Schlüssel bei Bedarf die Zone mit dem neuen Schlüssel zu signieren.
update-policy local; muss zwingend mit angegeben werden, damit BIND hier selbstständig tätig werden kann. Ohne diesen Parameter wird auch ein Fehler geworfen (oder es muss inline-signing aktiviert sein, aber das setzt ein anderes Setup voraus).
named.conf
zone dev.ws.dnssec.bayern {
type master;
file "/etc/bind/dev.ws.dnssec.bayern.zone";
key-directory "/var/bind/keys";
auto-dnssec maintain;
update-policy local;
};
BIND erkennt beim Start, dass die Zone signiert werden soll (auto-dnssec maintain), und ein sogenanntes Key-event fällig ist. Der gerade gültige ZSK wird zum Signieren verwendet und anhand der Pre-Publish und Post-Publish-Regeln Schlüssel und Signaturen in die Zone eingebunden.
BIND-Logfile
19-Jan-2017 12:39:36.052 debug 3: managed-keys-zone: Verifying DNSKEY set for zone '.' using key 19036/8: success
19-Jan-2017 12:39:36.052 debug 1: set_refreshkeytimer: managed-keys-zone : enter
19-Jan-2017 12:39:36.052 debug 1: managed-keys-zone: next key refresh: 20-Jan-2017 12:39:36.052
19-Jan-2017 12:39:36.052 debug 1: zone_settimer: managed-keys-zone : enter
19-Jan-2017 12:39:36.052 debug 1: zone_journal: managed-keys-zone : enter
19-Jan-2017 12:39:36.052 debug 1: journal file managed-keys.bind.jnl does not exist, creating it
19-Jan-2017 12:39:36.052 debug 3: writing to journal
19-Jan-2017 12:39:36.055 debug 1: zone_needdump: managed-keys-zone : enter
19-Jan-2017 12:39:36.055 debug 1: zone_settimer: managed-keys-zone : enter
19-Jan-2017 12:39:36.100 debug 3: validating ./DNSKEY: starting
19-Jan-2017 12:39:36.100 debug 3: validating ./DNSKEY: attempting positive response validation
19-Jan-2017 12:39:36.100 debug 3: validating ./DNSKEY: verify rdataset (keyid=19036): success
19-Jan-2017 12:39:36.100 debug 3: validating ./DNSKEY: signed by trusted key; marking as secure
19-Jan-2017 12:39:36.100 debug 3: validating ./NS: in fetch_callback_validator
19-Jan-2017 12:39:36.101 debug 3: validating ./NS: keyset with trust secure
19-Jan-2017 12:39:36.101 debug 3: validating ./NS: resuming validate
19-Jan-2017 12:39:36.101 debug 3: validating ./NS: verify rdataset (keyid=61045): success
19-Jan-2017 12:39:36.101 debug 3: validating ./NS: marking as secure, noqname proof not needed
Journal-Datei statt signierter Plaintext Zonen-Datei
Es muss beachtet werden, dass mit den Optionen update-policy local und auto-dnssec maintain BIND nicht mehr auf einer signierten Zonen-Datei im plaintext ASCII Format arbeitet, sondern nimmt die im Zonen-Abschnitt angegebene textbasierte Zonen-Datei "/etc/bind/dev.ws.dnssec.bayern.zone" nur als Input.
Die originale Zonen-Datei bleibt unverändert und BIND signiert die Zone in einer binären Zonen-Datei "/etc/bind/ws01.ws.dnssec.bayern.zone.signed", die im Speicher gehalten wird. Alle konsekutiven dynamischen Änderungen werden in einer Journal-Datei geführt. Bei einem Neustart wird der aktuelle Zonenzustand aus der .signed-Datei und den Journaleinträgen rekonstruiert.
Verwandte Artikel
There is no content with the specified labels