2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

dnssec-signzone can now create multiple CDS RRs

Change the commandline option -G to take a string that determines what
sync records should be published. It is a comma-separated string with
each element being either "cdnskey", or "cds:<algorithm>", where
<algorithm> is a valid digest type. Duplicates are suppressed.
This commit is contained in:
Matthijs Mekking
2023-02-21 08:50:04 +01:00
parent ea4130d6bd
commit b1633b71b0
3 changed files with 99 additions and 32 deletions

View File

@@ -173,7 +173,7 @@ static bool output_stdout = false;
static bool set_maxttl = false;
static dns_ttl_t maxttl = 0;
static bool no_max_check = false;
static bool ignore_sync = false;
static const char *sync_records = "cdnskey,cds:sha-256";
#define INCSTAT(counter) \
if (printstats) { \
@@ -2733,6 +2733,51 @@ clear_keylist(dns_dnsseckeylist_t *list) {
}
}
static void
add_digest(char *str, size_t dlen, dns_kasp_digestlist_t *digests,
bool *cdnskey) {
isc_result_t result;
isc_textregion_t r;
dns_dsdigest_t alg;
dns_kasp_digest_t *digest;
if (dlen == 7 && strncmp(str, "cdnskey", dlen) == 0) {
*cdnskey = true;
return;
}
if (dlen < 5 || strncmp(str, "cds:", 4) != 0) {
fatal("digest must specify cds:algorithm ('%.*s')", (int)dlen,
str);
}
r.base = str + 4;
r.length = dlen - 4;
result = dns_dsdigest_fromtext(&alg, &r);
if (result == DNS_R_UNKNOWN) {
fatal("bad digest '%.*s'", (int)dlen, str);
} else if (result != ISC_R_SUCCESS) {
fatal("bad digest '%.*s': %s", (int)dlen, str,
isc_result_totext(result));
} else if (!dst_ds_digest_supported(alg)) {
fatal("unsupported digest '%.*s'", (int)dlen, str);
}
/* Suppress duplicates */
for (dns_kasp_digest_t *d = ISC_LIST_HEAD(*digests); d != NULL;
d = ISC_LIST_NEXT(d, link))
{
if (d->digest == alg) {
return;
}
}
digest = isc_mem_get(mctx, sizeof(*digest));
digest->digest = alg;
ISC_LINK_INIT(digest, link);
ISC_LIST_APPEND(*digests, digest, link);
}
static void
build_final_keylist(void) {
isc_result_t result;
@@ -2743,23 +2788,38 @@ build_final_keylist(void) {
char name[DNS_NAME_FORMATSIZE];
dns_rdataset_t cdsset, cdnskeyset, soaset;
dns_kasp_digestlist_t digests;
dns_kasp_digest_t digest = {
.digest = DNS_DSDIGEST_SHA256,
.link = ISC_LINK_INITIALIZER,
};
dns_kasp_digest_t *d, *d_next;
bool cdnskey = false;
ISC_LIST_INIT(rmkeys);
ISC_LIST_INIT(matchkeys);
ISC_LIST_INIT(digests);
if (!ignore_sync) {
ISC_LIST_APPEND(digests, &digest, link);
}
dns_rdataset_init(&soaset);
dns_rdataset_init(&cdsset);
dns_rdataset_init(&cdnskeyset);
if (strlen(sync_records) > 0) {
const char delim = ',';
char *digest;
char *s;
size_t dlen;
DE_CONST(sync_records, digest);
next_digest:
s = strchr(digest, delim);
if (s == NULL) {
dlen = strlen(digest);
add_digest(digest, dlen, &digests, &cdnskey);
goto findkeys;
}
dlen = s - digest;
add_digest(digest, dlen, &digests, &cdnskey);
digest = s + 1;
goto next_digest;
}
findkeys:
/*
* Find keys that match this zone in the key repository.
*/
@@ -2828,8 +2888,10 @@ build_final_keylist(void) {
clear_keylist(&rmkeys);
clear_keylist(&matchkeys);
if (!ignore_sync) {
ISC_LIST_UNLINK(digests, &digest, link);
for (d = ISC_LIST_HEAD(digests); d != NULL; d = d_next) {
d_next = ISC_LIST_NEXT(d, link);
ISC_LIST_UNLINK(digests, d, link);
isc_mem_put(mctx, d, sizeof(*d));
}
INSIST(ISC_LIST_EMPTY(digests));
}
@@ -3162,6 +3224,8 @@ usage(void) {
fprintf(stderr, "\t-g:\t");
fprintf(stderr, "update DS records based on child zones' "
"dsset-* files\n");
fprintf(stderr, "\t-G sync-records:\t");
fprintf(stderr, "what CDNSKEY and CDS to publish\n");
fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n");
fprintf(stderr, "\t\tRRSIG start time "
"- absolute|offset (now - 1 hour)\n");
@@ -3303,8 +3367,8 @@ main(int argc, char *argv[]) {
atomic_init(&finished, false);
/* Unused letters: Bb G J q Yy (and F is reserved). */
#define CMDLINE_FLAGS \
"3:AaCc:Dd:E:e:f:FgGhH:i:I:j:J:K:k:L:l:m:M:n:N:o:O:PpQqRr:s:ST:tuUv:" \
#define CMDLINE_FLAGS \
"3:AaCc:Dd:E:e:f:FgG:hH:i:I:j:J:K:k:L:l:m:M:n:N:o:O:PpQqRr:s:ST:tuUv:" \
"VX:xzZ:"
/*
@@ -3411,7 +3475,7 @@ main(int argc, char *argv[]) {
break;
case 'G':
ignore_sync = true;
sync_records = isc_commandline_argument;
break;
case 'H':

View File

@@ -21,7 +21,7 @@ dnssec-signzone - DNSSEC zone signing tool
Synopsis
~~~~~~~~
:program:`dnssec-signzone` [**-a**] [**-c** class] [**-d** directory] [**-D**] [**-E** engine] [**-e** end-time] [**-f** output-file] [**-g**] [**-G**] [**-h**] [**-i** interval] [**-I** input-format] [**-j** jitter] [**-K** directory] [**-k** key] [**-L** serial] [**-M** maxttl] [**-N** soa-serial-format] [**-o** origin] [**-O** output-format] [**-P**] [**-Q**] [**-q**] [**-R**] [**-S**] [**-s** start-time] [**-T** ttl] [**-t**] [**-u**] [**-v** level] [**-V**] [**-X** extended end-time] [**-x**] [**-z**] [**-3** salt] [**-H** iterations] [**-A**] {zonefile} [key...]
:program:`dnssec-signzone` [**-a**] [**-c** class] [**-d** directory] [**-D**] [**-E** engine] [**-e** end-time] [**-f** output-file] [**-g**] [**-G sync-records**] [**-h**] [**-i** interval] [**-I** input-format] [**-j** jitter] [**-K** directory] [**-k** key] [**-L** serial] [**-M** maxttl] [**-N** soa-serial-format] [**-o** origin] [**-O** output-format] [**-P**] [**-Q**] [**-q**] [**-R**] [**-S**] [**-s** start-time] [**-T** ttl] [**-t**] [**-u**] [**-v** level] [**-V**] [**-X** extended end-time] [**-x**] [**-z**] [**-3** salt] [**-H** iterations] [**-A**] {zonefile} [key...]
Description
~~~~~~~~~~~
@@ -76,9 +76,12 @@ Options
This option indicates that DS records for child zones should be generated from a ``dsset-`` or ``keyset-``
file. Existing DS records are removed.
.. option:: -G
.. option:: -G sync-records
This option indicates that CDS and CDNSKEY records should not be generated from the given key set.
This option indicates which CDS and CDNSKEY records should be generated. ``sync-records`` is a
comma-separated string with the following allowed items: ``cdnskey``, and ``cds:<digest-type>``,
where ``digest-type`` is an allowed algorithm such as SHA-256 (2), or SHA-384 (4).
Only works in combination with smart signing (``-S``).
.. option:: -K directory

View File

@@ -888,7 +888,7 @@ $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" > s
cat template.db.in "${CSK}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 2:
# It is time to introduce the new CSK.
@@ -916,7 +916,7 @@ $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" > s
cat template.db.in "${CSK}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 3:
# It is time to submit the DS and to roll signatures.
@@ -971,7 +971,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 4:
# Some time later all the ZRRSIG records should be from the new CSK, and the
@@ -1018,7 +1018,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 5:
# After the DS is swapped in step 4, also the KRRSIG records can be removed.
@@ -1054,7 +1054,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 6:
# After the retire interval has passed the predecessor DNSKEY can be
@@ -1098,7 +1098,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 7:
# Some time later the predecessor DNSKEY enters the HIDDEN state.
@@ -1133,7 +1133,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 8:
# The predecessor DNSKEY can be purged.
@@ -1168,7 +1168,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
#
# The zones at csk-roll2.autosign represent the various steps of a CSK rollover
@@ -1187,7 +1187,7 @@ $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" > s
cat template.db.in "${CSK}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 2:
# It is time to introduce the new CSK.
@@ -1215,7 +1215,7 @@ $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" > s
cat template.db.in "${CSK}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 3:
# It is time to submit the DS and to roll signatures.
@@ -1270,7 +1270,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 4:
# Some time later all the ZRRSIG records should be from the new CSK, and the
@@ -1318,7 +1318,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 5:
# Some time later the DS can be swapped and the old DNSKEY can be removed from
@@ -1355,7 +1355,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 6:
# Some time later the predecessor DNSKEY enters the HIDDEN state.
@@ -1391,7 +1391,7 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
# Step 7:
# The predecessor DNSKEY can be purged, but purge-keys is disabled.
@@ -1426,4 +1426,4 @@ cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile"
cp $infile $zonefile
$SIGNER -S -z -x -G -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1
$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1