From aec7cc96fe9c4e6dae6b6fcf02e4d100b4a2cb30 Mon Sep 17 00:00:00 2001 From: Libor Peltan Date: Mon, 7 Feb 2022 19:25:36 +0100 Subject: [PATCH] dnssec/DS-check: allow delay post-active after KSK submission --- doc/man/knot.conf.5in | 8 ++++++++ doc/reference.rst | 12 ++++++++++++ src/knot/conf/schema.c | 2 ++ src/knot/conf/schema.h | 1 + src/knot/dnssec/context.c | 3 +++ src/knot/dnssec/ds_query.c | 2 +- src/knot/dnssec/kasp/policy.h | 1 + tests-extra/tests/dnssec/key_rollovers/test.py | 5 +++-- tests-extra/tools/dnstest/server.py | 3 +++ 9 files changed, 34 insertions(+), 3 deletions(-) diff --git a/doc/man/knot.conf.5in b/doc/man/knot.conf.5in index 86e9250e5..b2231fbfd 100644 --- a/doc/man/knot.conf.5in +++ b/doc/man/knot.conf.5in @@ -1258,6 +1258,7 @@ submission: parent: remote_id | remotes_id ... check\-interval: TIME timeout: TIME + parent\-delay: TIME .ft P .fi .UNINDENT @@ -1294,6 +1295,13 @@ successful, even if all the checks were negative or no parents are configured. Set to 0 for infinity. .sp \fIDefault:\fP 0 +.SS parent\-delay +.sp +After successful parent DS check, wait for this period before continuing the next +key roll\-over step. This delay shall cover the propagation delay of update in the +parent zone. +.sp +\fIDefault:\fP 0 .SH POLICY SECTION .sp DNSSEC policy configuration. diff --git a/doc/reference.rst b/doc/reference.rst index efe338c64..ef42fdfba 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -1356,6 +1356,7 @@ Parameters of KSK submission checks. parent: remote_id | remotes_id ... check-interval: TIME timeout: TIME + parent-delay: TIME .. _submission_id: @@ -1401,6 +1402,17 @@ Set to 0 for infinity. *Default:* 0 +.. _submission_parent-delay: + +parent-delay +------------ + +After successful parent DS check, wait for this period before continuing the next +key roll-over step. This delay shall cover the propagation delay of update in the +parent zone. + +*Default:* 0 + .. _Policy section: Policy section diff --git a/src/knot/conf/schema.c b/src/knot/conf/schema.c index 370266234..c5c37c82a 100644 --- a/src/knot/conf/schema.c +++ b/src/knot/conf/schema.c @@ -353,6 +353,8 @@ static const yp_item_t desc_submission[] = { CONF_IO_FRLD_ZONES }, { C_TIMEOUT, YP_TINT, YP_VINT = { 0, UINT32_MAX, 0, YP_STIME }, CONF_IO_FRLD_ZONES }, + { C_PARENT_DELAY, YP_TINT, YP_VINT = { 0, UINT32_MAX, 0, YP_STIME }, + CONF_IO_FRLD_ZONES }, { C_COMMENT, YP_TSTR, YP_VNONE }, { NULL } }; diff --git a/src/knot/conf/schema.h b/src/knot/conf/schema.h index f325c7caf..d47516e71 100644 --- a/src/knot/conf/schema.h +++ b/src/knot/conf/schema.h @@ -89,6 +89,7 @@ #define C_NSID "\x04""nsid" #define C_OFFLINE_KSK "\x0B""offline-ksk" #define C_PARENT "\x06""parent" +#define C_PARENT_DELAY "\x0C""parent-delay" #define C_PIDFILE "\x07""pidfile" #define C_POLICY "\x06""policy" #define C_PROPAG_DELAY "\x11""propagation-delay" diff --git a/src/knot/dnssec/context.c b/src/knot/dnssec/context.c index af4a749f7..b8d3ee9aa 100644 --- a/src/knot/dnssec/context.c +++ b/src/knot/dnssec/context.c @@ -131,6 +131,9 @@ static void policy_load(knot_kasp_policy_t *policy, conf_t *conf, conf_val_t *id } conf_mix_iter_next(&iter); } + + val = conf_id_get(conf, C_SBM, C_PARENT_DELAY, &ksk_sbm); + policy->ksk_sbm_delay = conf_int(&val); } val = conf_id_get(conf, C_POLICY, C_SIGNING_THREADS, id); diff --git a/src/knot/dnssec/ds_query.c b/src/knot/dnssec/ds_query.c index e8d146f38..152af8412 100644 --- a/src/knot/dnssec/ds_query.c +++ b/src/knot/dnssec/ds_query.c @@ -251,7 +251,7 @@ int knot_parent_ds_query(kdnssec_ctx_t *kctx, zone_keyset_t *keyset, size_t time if (key->is_ready && !key->is_pub_only) { assert(key->is_ksk); if (parents_have_ds(kctx, key, timeout, &max_ds_ttl)) { - return knot_dnssec_ksk_sbm_confirm(kctx, max_ds_ttl); + return knot_dnssec_ksk_sbm_confirm(kctx, max_ds_ttl + kctx->policy->ksk_sbm_delay); } else { return KNOT_ENOENT; } diff --git a/src/knot/dnssec/kasp/policy.h b/src/knot/dnssec/kasp/policy.h index d53adb5ac..8d9031ac6 100644 --- a/src/knot/dnssec/kasp/policy.h +++ b/src/knot/dnssec/kasp/policy.h @@ -121,6 +121,7 @@ typedef struct { // various uint32_t ksk_sbm_timeout; // like knot_time_t uint32_t ksk_sbm_check_interval; // like knot_time_t + uint32_t ksk_sbm_delay; unsigned cds_cdnskey_publish; dnssec_key_digest_t cds_dt; // digest type for CDS parent_dynarray_t parents; diff --git a/tests-extra/tests/dnssec/key_rollovers/test.py b/tests-extra/tests/dnssec/key_rollovers/test.py index 1b1c561f5..49f4dd4f4 100644 --- a/tests-extra/tests/dnssec/key_rollovers/test.py +++ b/tests-extra/tests/dnssec/key_rollovers/test.py @@ -195,7 +195,7 @@ def watch_alg_rollover(t, server, zone, slave, before_keys, after_keys, desc, se check_zone(server, zone, slave, before_keys + after_keys, 2, 1, 2, msg) msg = desc + ": post active" - wait_for_count(t, server, "DNSKEY", after_keys, 5, 20, msg) + wait_for_count(t, server, "DNSKEY", after_keys, 11, 26, msg) check_zone(server, zone, slave, after_keys, 1, 1, 2, msg) msg = desc + ": old alg removed" @@ -232,7 +232,7 @@ def watch_ksk_rollover(t, server, zone, slave, before_keys, after_keys, total_ke check_zone(server, zone, slave, total_keys, 2, 1, 1, msg) # else skip the test as we have no control on KSK and ZSK retiring asynchronously - t.sleep(5) # cca DS TTL + t.sleep(11) # cca DS TTL + parent-delay wait_for_count(t, server, "SOA", 1, 0, 1, "NOOP") msg = desc + ": old key removed" @@ -275,6 +275,7 @@ child.dnssec(child_zone).delete_delay = DELETE_DELAY child.dnssec(child_zone).propagation_delay = 11 child.dnssec(child_zone).ksk_sbm_check = [ parent ] child.dnssec(child_zone).ksk_sbm_check_interval = 2 +child.dnssec(child_zone).ksk_sbm_delay = 6 child.dnssec(child_zone).ksk_shared = True child.dnssec(child_zone).cds_publish = "always" if DOUBLE_DS: diff --git a/tests-extra/tools/dnstest/server.py b/tests-extra/tools/dnstest/server.py index e45fa5bcb..691074422 100644 --- a/tests-extra/tools/dnstest/server.py +++ b/tests-extra/tools/dnstest/server.py @@ -64,6 +64,7 @@ class ZoneDnssec(object): self.ksk_sbm_check = [] self.ksk_sbm_check_interval = None self.ksk_sbm_timeout = None + self.ksk_sbm_delay = None self.ds_push = None self.ksk_shared = None self.shared_policy_with = None @@ -1384,6 +1385,8 @@ class Knot(Server): self._str(s, "check-interval", z.dnssec.ksk_sbm_check_interval) if z.dnssec.ksk_sbm_timeout is not None: self._str(s, "timeout", z.dnssec.ksk_sbm_timeout) + if z.dnssec.ksk_sbm_delay is not None: + self._str(s, "parent-delay", z.dnssec.ksk_sbm_delay) if have_sbm: s.end()