]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Allow DNSKEY when syncing secure journal/db
authorMatthijs Mekking <matthijs@isc.org>
Wed, 5 Oct 2022 11:36:42 +0000 (13:36 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Tue, 23 May 2023 06:52:01 +0000 (08:52 +0200)
When synchronizing the journal or database from the unsigned version of
the zone to the secure version of the zone, allow DNSKEY records to be
synced, because these may be added by the user with the sole intent to
publish the record (not used for signing). This may be the case for
example in the multisigner model 2 (RFC 8901).

Additional code needs to be added to ensure that we do not remove DNSKEY
records that are under our control. Keys under our control are keys that
are used for signing the zone and thus that we have key files for.

Same counts for CDNSKEY and CDS (records that are derived from keys).

lib/dns/zone.c
lib/ns/update.c

index ae96df07abec2bbb355bc4ff60bd0ee69833c9c2..c18fe4bff88a3301b2112e7170a3409f90a02552 100644 (file)
@@ -16020,7 +16020,6 @@ dns_zone_dnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, bool *inuse) {
                break;
        }
 
-out:
        while (!ISC_LIST_EMPTY(keylist)) {
                key = ISC_LIST_HEAD(keylist);
                ISC_LIST_UNLINK(keylist, key, link);
@@ -16085,14 +16084,32 @@ sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
                        continue;
                }
 
+               /*
+                * Skip DNSSEC records that BIND maintains with inline-signing.
+                */
                if (rdata->type == dns_rdatatype_nsec ||
                    rdata->type == dns_rdatatype_rrsig ||
                    rdata->type == dns_rdatatype_nsec3 ||
-                   rdata->type == dns_rdatatype_dnskey ||
                    rdata->type == dns_rdatatype_nsec3param)
                {
                        continue;
                }
+               /*
+                * Allow DNSKEY, CDNSKEY, CDS because users should be able to
+                * update the zone with these records from a different provider,
+                * but skip records that are under our control.
+                */
+               if (rdata->type == dns_rdatatype_dnskey ||
+                   rdata->type == dns_rdatatype_cdnskey ||
+                   rdata->type == dns_rdatatype_cds)
+               {
+                       bool inuse = false;
+                       isc_result_t r = dns_zone_dnskey_inuse(zone, rdata,
+                                                              &inuse);
+                       if (r == ISC_R_SUCCESS && inuse) {
+                               continue;
+                       }
+               }
 
                op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
 
@@ -16138,9 +16155,11 @@ sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
 
        for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) {
                next = ISC_LIST_NEXT(tuple, link);
+               /*
+                * Skip DNSSEC records that BIND maintains with inline-signing.
+                */
                if (tuple->rdata.type == dns_rdatatype_nsec ||
                    tuple->rdata.type == dns_rdatatype_rrsig ||
-                   tuple->rdata.type == dns_rdatatype_dnskey ||
                    tuple->rdata.type == dns_rdatatype_nsec3 ||
                    tuple->rdata.type == dns_rdatatype_nsec3param)
                {
@@ -16148,6 +16167,26 @@ sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
                        dns_difftuple_free(&tuple);
                        continue;
                }
+
+               /*
+                * Allow DNSKEY, CDNSKEY, CDS because users should be able to
+                * update the zone with these records from a different provider,
+                * but skip records that are under our control.
+                */
+               if (tuple->rdata.type == dns_rdatatype_dnskey ||
+                   tuple->rdata.type == dns_rdatatype_cdnskey ||
+                   tuple->rdata.type == dns_rdatatype_cds)
+               {
+                       bool inuse = false;
+                       isc_result_t r = dns_zone_dnskey_inuse(
+                               seczone, &tuple->rdata, &inuse);
+                       if (r == ISC_R_SUCCESS && inuse) {
+                               ISC_LIST_UNLINK(diff->tuples, tuple, link);
+                               dns_difftuple_free(&tuple);
+                               continue;
+                       }
+               }
+
                if (tuple->rdata.type == dns_rdatatype_soa) {
                        if (tuple->op == DNS_DIFFOP_DEL) {
                                INSIST(oldtuple == NULL);
index bd3d3af3d404df32f38957a86c441a6dcbf37144..493637f1475ba5c71f770391d59757125c50ca7e 100644 (file)
@@ -3377,6 +3377,30 @@ update_action(void *arg) {
                                                continue;
                                        }
                                }
+                               /*
+                                * Don't remove DNSKEY, CDNSKEY, CDS records
+                                * that are in use (under our control).
+                                */
+                               if (rdata.type == dns_rdatatype_dnskey ||
+                                   rdata.type == dns_rdatatype_cdnskey ||
+                                   rdata.type == dns_rdatatype_cds)
+                               {
+                                       isc_result_t r;
+                                       bool inuse = false;
+                                       r = dns_zone_dnskey_inuse(zone, &rdata,
+                                                                 &inuse);
+                                       if (r != ISC_R_SUCCESS) {
+                                               FAIL(r);
+                                       }
+                                       if (inuse) {
+                                               update_log(client, zone,
+                                                          LOGLEVEL_PROTOCOL,
+                                                          "attempt to "
+                                                          "delete in use "
+                                                          "DNSKEY ignored");
+                                               continue;
+                                       }
+                               }
                        }
                        dns_name_format(name, namestr, sizeof(namestr));
                        dns_rdatatype_format(rdata.type, typestr,