]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Don't roll offline keys
authorMatthijs Mekking <matthijs@isc.org>
Mon, 12 Apr 2021 12:40:46 +0000 (14:40 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 5 May 2021 10:49:49 +0000 (12:49 +0200)
When checking the current DNSSEC state against the policy, consider
offline keys. If we didn't found an active key, check if the key is
offline by checking the public key list. If there is a match in the
public key list (the key data is retrieved from the .key and the
.state files), treat the key as offline and don't create a successor
key for it.

(cherry picked from commit 3e6fc49c165c203b3d2c3c58b93bcb18d18fcf40)

lib/dns/include/dns/keymgr.h
lib/dns/keymgr.c
lib/dns/zone.c

index 6c7e17ceee96a6c9a404271f61349cb073e2c26c..ae4ab5da1352942dd00fb49aefc5da165d613c68 100644 (file)
@@ -26,12 +26,12 @@ ISC_LANG_BEGINDECLS
 isc_result_t
 dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
               const char *directory, isc_mem_t *mctx,
-              dns_dnsseckeylist_t *keyring, dns_kasp_t *kasp,
-              isc_stdtime_t now, isc_stdtime_t *nexttime);
+              dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *dnskeys,
+              dns_kasp_t *kasp, isc_stdtime_t now, isc_stdtime_t *nexttime);
 /*%<
- * Manage keys in 'keylist' and update timing data according to 'kasp' policy.
+ * Manage keys in 'keyring' and update timing data according to 'kasp' policy.
  * Create new keys for 'origin' if necessary in 'directory'.  Append all such
- * keys, along with use hints gleaned from their metadata, onto 'keylist'.
+ * keys, along with use hints gleaned from their metadata, onto 'keyring'.
  *
  * Update key states and store changes back to disk. Store when to run next
  * in 'nexttime'.
index b4efb3aeb26712f95e5a9bd419f13560aad2c4ee..02dbd711e2c3b398208a17657c9b62b653080a0f 100644 (file)
@@ -1640,8 +1640,9 @@ static isc_result_t
 keymgr_key_rollover(dns_kasp_key_t *kaspkey, dns_dnsseckey_t *active_key,
                    dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *newkeys,
                    const dns_name_t *origin, dns_rdataclass_t rdclass,
-                   dns_kasp_t *kasp, uint32_t lifetime, isc_stdtime_t now,
-                   isc_stdtime_t *nexttime, isc_mem_t *mctx) {
+                   dns_kasp_t *kasp, uint32_t lifetime, bool rollover,
+                   isc_stdtime_t now, isc_stdtime_t *nexttime,
+                   isc_mem_t *mctx) {
        char keystr[DST_KEY_FORMATSIZE];
        isc_stdtime_t retire = 0, active = 0, prepub = 0;
        dns_dnsseckey_t *new_key = NULL;
@@ -1723,6 +1724,20 @@ keymgr_key_rollover(dns_kasp_key_t *kaspkey, dns_dnsseckey_t *active_key,
 
        /* It is time to do key rollover, we need a new key. */
 
+       /*
+        * If rollover is not allowed, warn.
+        */
+       if (!rollover) {
+               dst_key_format(active_key->key, keystr, sizeof(keystr));
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
+                             DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING,
+                             "keymgr: DNSKEY %s (%s) is offline in policy %s, "
+                             "cannot start rollover",
+                             keystr, keymgr_keyrole(active_key->key),
+                             dns_kasp_getname(kasp));
+               return (ISC_R_SUCCESS);
+       }
+
        /*
         * Check if there is a key available in pool because keys
         * may have been pregenerated with dnssec-keygen.
@@ -1929,8 +1944,8 @@ keymgr_purge_keyfile(dst_key_t *key, const char *dir, int type) {
 isc_result_t
 dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
               const char *directory, isc_mem_t *mctx,
-              dns_dnsseckeylist_t *keyring, dns_kasp_t *kasp,
-              isc_stdtime_t now, isc_stdtime_t *nexttime) {
+              dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *dnskeys,
+              dns_kasp_t *kasp, isc_stdtime_t now, isc_stdtime_t *nexttime) {
        isc_result_t result = ISC_R_SUCCESS;
        dns_dnsseckeylist_t newkeys;
        dns_kasp_key_t *kkey;
@@ -1974,8 +1989,17 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
                        dst_key_format(dkey->key, keystr, sizeof(keystr));
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
                                      DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1),
-                                     "keymgr: keyring: dnskey %s (policy %s)",
-                                     keystr, dns_kasp_getname(kasp));
+                                     "keymgr: keyring: %s (policy %s)", keystr,
+                                     dns_kasp_getname(kasp));
+               }
+               for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*dnskeys);
+                    dkey != NULL; dkey = ISC_LIST_NEXT(dkey, link))
+               {
+                       dst_key_format(dkey->key, keystr, sizeof(keystr));
+                       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
+                                     DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1),
+                                     "keymgr: dnskeys: %s (policy %s)", keystr,
+                                     dns_kasp_getname(kasp));
                }
        }
 
@@ -2029,6 +2053,7 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
        {
                uint32_t lifetime = dns_kasp_key_lifetime(kkey);
                dns_dnsseckey_t *active_key = NULL;
+               bool rollover_allowed = true;
 
                /* Do we have keys available for this kasp key? */
                for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring);
@@ -2089,10 +2114,43 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
                        }
                }
 
+               if (active_key == NULL) {
+                       /*
+                        * We didn't found an active key, perhaps the .private
+                        * key file is offline. If so, we don't want to create
+                        * a successor key. Check if we have an appropriate
+                        * state file.
+                        */
+                       for (dns_dnsseckey_t *dnskey = ISC_LIST_HEAD(*dnskeys);
+                            dnskey != NULL;
+                            dnskey = ISC_LIST_NEXT(dnskey, link))
+                       {
+                               if (keymgr_dnsseckey_kaspkey_match(dnskey,
+                                                                  kkey)) {
+                                       /* Found a match. */
+                                       dst_key_format(dnskey->key, keystr,
+                                                      sizeof(keystr));
+                                       isc_log_write(
+                                               dns_lctx,
+                                               DNS_LOGCATEGORY_DNSSEC,
+                                               DNS_LOGMODULE_DNSSEC,
+                                               ISC_LOG_DEBUG(1),
+                                               "keymgr: DNSKEY %s (%s) "
+                                               "offline, policy %s",
+                                               keystr,
+                                               keymgr_keyrole(dnskey->key),
+                                               dns_kasp_getname(kasp));
+                                       rollover_allowed = false;
+                                       active_key = dnskey;
+                                       break;
+                               }
+                       }
+               }
+
                /* See if this key requires a rollover. */
-               RETERR(keymgr_key_rollover(kkey, active_key, keyring, &newkeys,
-                                          origin, rdclass, kasp, lifetime, now,
-                                          nexttime, mctx));
+               RETERR(keymgr_key_rollover(
+                       kkey, active_key, keyring, &newkeys, origin, rdclass,
+                       kasp, lifetime, rollover_allowed, now, nexttime, mctx));
        }
 
        /* Walked all kasp key configurations.  Append new keys. */
index 17d7ca239352fde39e86428288ffa92df5df59d2..cdc151a5b01118fc7c746f8940547a0b19369890 100644 (file)
@@ -19809,8 +19809,8 @@ zone_rekey(dns_zone_t *zone) {
        if (kasp != NULL) {
                if (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND) {
                        result = dns_keymgr_run(&zone->origin, zone->rdclass,
-                                               dir, mctx, &keys, kasp, now,
-                                               &nexttime);
+                                               dir, mctx, &keys, &dnskeys,
+                                               kasp, now, &nexttime);
                        if (result != ISC_R_SUCCESS) {
                                dnssec_log(zone, ISC_LOG_ERROR,
                                           "zone_rekey:dns_dnssec_keymgr "