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.

  1. BIND 9.11-Quellen entpacken und ./configure laufen lassen
  2. Im Verzeichnis ./bin/python/ make ausführen
  3. Python isc-Package-Dateien kopieren
  4. dnssec-keymgr kopieren
  5. Policy-Datei anlegen
  6. Schlüssel-Verwaltung mit dnssec-keymgr
  7. BIND 9.9.x für automatisches dnssec konfigurieren


  1. 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.html

    Downloaden 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 Verzeichnis
    tar xzf bind-9.11.0-P1.tar.gz

    Die folgenden Abhängigkeiten existieren und sollten am besten mit dem Paketmanager nach-installiert werden
    apt-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:


    make

    Uns 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/python

    make



  2. Python isc-Package-Dateien kopieren

    In ./bin/python/ befindet sich ein Unterverzeichnis "isc", das die BIND-9.11-Pythonmodule beinhaltet.

  3. 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.



  4. 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

Es ist kein Inhalt mit den angegebenen Stichworten vorhanden