2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-28 13:08:06 +00:00

dnssec-signzone -Z none removes ZONEMD records

"dnssec-signzone -Z none" removes pre-existing ZONEMD records from a
signed zone. If followed by another -Z option, a new ZONEMD record
will be added to replace the existing ones. This can be used, for
instance, to switch from one scheme/digest to the other.
This commit is contained in:
Evan Hunt 2025-08-27 11:45:11 -07:00
parent fcbd4bea02
commit 8db40614c4
3 changed files with 92 additions and 22 deletions

View File

@ -173,7 +173,9 @@ static bool set_maxttl = false;
static dns_ttl_t maxttl = 0;
static bool no_max_check = false;
static const char *sync_records = "cdnskey,cds:sha-256";
uint8_t zonemd_scheme[2] = { 0 }, zonemd_digest[2] = { 0 };
static bool add_zonemd = false;
static bool del_zonemd = false;
#define INCSTAT(counter) \
if (printstats) { \
@ -1963,7 +1965,7 @@ addnsec3param(const unsigned char *salt, size_t salt_len,
if (result == DNS_R_UNCHANGED) {
result = ISC_R_SUCCESS;
}
check_result(result, "dddnsec3param: dns_db_deleterdataset()");
check_result(result, "addnsec3param: dns_db_deleterdataset()");
result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset,
DNS_DBADD_MERGE, NULL);
@ -2217,6 +2219,35 @@ addzonemd(uint8_t scheme, uint8_t digest_type) {
dns_db_detachnode(&node);
}
static void
setup_zonemd(void) {
if (del_zonemd) {
/* Delete any current ZONEMD records.*/
isc_result_t result;
dns_dbnode_t *node = NULL;
result = dns_db_getoriginnode(gdb, &node);
check_result(result, "dns_db_getoriginnode()");
result = dns_db_deleterdataset(gdb, node, gversion,
dns_rdatatype_zonemd, 0);
dns_db_detachnode(&node);
if (result == DNS_R_UNCHANGED) {
result = ISC_R_SUCCESS;
}
check_result(result, "dns_db_deleterdataset()");
}
if (add_zonemd) {
for (size_t i = 0; i < ARRAY_SIZE(zonemd_scheme); i++) {
if (zonemd_scheme[i] != 0) {
addzonemd(zonemd_scheme[i], zonemd_digest[i]);
}
}
}
}
static void
rrset_cleanup(dns_name_t *name, dns_rdataset_t *rdataset, dns_diff_t *add,
dns_diff_t *del) {
@ -3389,7 +3420,6 @@ main(int argc, char *argv[]) {
bool set_optout = false;
bool set_iter = false;
bool nonsecify = false;
uint8_t zonemd_scheme[2] = { 0 }, zonemd_digest[2] = { 0 };
atomic_init(&shuttingdown, false);
atomic_init(&finished, false);
@ -3685,13 +3715,17 @@ main(int argc, char *argv[]) {
break;
case 'Z':
add_zonemd = true;
if (strcasecmp(isc_commandline_argument,
"simple-sha384") == 0 ||
strcasecmp(isc_commandline_argument, "sha384") ==
0 ||
strcmp(isc_commandline_argument, "-") == 0)
if (strcasecmp(isc_commandline_argument, "none") == 0) {
del_zonemd = true;
memset(zonemd_scheme, 0, sizeof(zonemd_scheme));
memset(zonemd_digest, 0, sizeof(zonemd_digest));
} else if (strcasecmp(isc_commandline_argument,
"simple-sha384") == 0 ||
strcasecmp(isc_commandline_argument,
"sha384") == 0 ||
strcmp(isc_commandline_argument, "-") == 0)
{
add_zonemd = true;
for (size_t i = 0;
i < ARRAY_SIZE(zonemd_scheme); i++)
{
@ -3713,6 +3747,7 @@ main(int argc, char *argv[]) {
strcasecmp(isc_commandline_argument,
"sha512") == 0)
{
add_zonemd = true;
for (size_t i = 0;
i < ARRAY_SIZE(zonemd_scheme); i++)
{
@ -4043,13 +4078,8 @@ main(int argc, char *argv[]) {
/* Remove duplicates and cap TTLs at maxttl */
cleanup_zone();
if (add_zonemd) {
for (size_t i = 0; i < ARRAY_SIZE(zonemd_scheme); i++) {
if (zonemd_scheme[i] != 0) {
addzonemd(zonemd_scheme[i], zonemd_digest[i]);
}
}
}
/* Set up ZONEMD records */
setup_zonemd();
if (!nonsecify) {
if (IS_NSEC3) {

View File

@ -403,13 +403,17 @@ Options
.. option:: -Z method
This option causes a ZONEMD record to be added to the signed zone,
if there wasn't a ZONEMD already present. The ``method`` parameter
indicates the scheme and digest type to use: valid options are
``simple-sha384`` (or ``sha384``, or ``-``) for scheme SIMPLE
and digest type SHA384, and ``simple-sha512`` (or ``sha512``)
for scheme SIMPLE and digest type SHA512. Multiple ``-Z`` options
can be used simultaneously to add multiple ZONEMD records.
This option causes a ZONEMD record to be added to, or removed from,
the signed zone. The ``method`` parameter indicates the scheme and
digest type to use: valid options are ``simple-sha384`` (or
``sha384``, or ``-``) for scheme SIMPLE and digest type SHA384,
and ``simple-sha512`` (or ``sha512``) for scheme SIMPLE and digest
type SHA512. ``-Z none`` removes all ZONEMD records.
Multiple ``-Z`` options can be used simultaneously, and are processed
in order. This allows multiple ZONEMD records to be added with a single
command, or (by specifying ``none`` first) existing ZONEMD records to
be removed and replaced.
.. option:: zonefile

View File

@ -279,6 +279,42 @@ n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_ic "check that dnssec-signzone -Z none removes ZONEMD records ($n)"
ret=0
(
cd signer/general || exit 1
rm -f signed.zone
$SIGNER -Z none -f signed.zone -o example.com. test14.zone >signer.out.$n
count=$(grep -c "ZONEMD.90000 1 1 " signed.zone)
test $count -eq 1 && exit 1
count=$(grep -c "ZONEMD.90000 1 2 " signed.zone)
test $count -eq 1 && exit 1
count=$(grep -c "RRSIG.ZONEMD" signed.zone)
test $count -eq 1 && exit 1
test -f signed.zone
) || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_ic "check that dnssec-signzone -Z none -Z - keeps one ZONEMD record ($n)"
ret=0
(
cd signer/general || exit 1
rm -f signed.zone
$SIGNER -Z none -Z - -f signed.zone -o example.com. test14.zone >signer.out.$n
count=$(grep -c "ZONEMD.90000 1 1 " signed.zone)
test $count -eq 1 || exit 1
count=$(grep -c "ZONEMD.90000 1 2 " signed.zone)
test $count -eq 1 && exit 1
count=$(grep -c "RRSIG.ZONEMD" signed.zone)
test $count -eq 1 || exit 1
test -f signed.zone
) || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
get_default_algorithm_key_ids_from_sigs() {
zone=$1