From 63c5b453e0feab71d1647f4cff00d2e1b5da61ed Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Mon, 17 Feb 2025 12:05:25 +0100 Subject: [PATCH] Add manual-mode config option Add a new option 'manual-mode' to 'dnssec-policy'. The intended use is that if it is enabled, it will not automatically move to the next state transition (RUMOURED, UNRETENTIVE), only after manual confirmation. The intended state transition should be logged. --- bin/named/config.c | 2 ++ bin/tests/system/checkconf/good.conf.j2 | 1 + doc/arm/reference.rst | 10 ++++++++++ doc/misc/dnssec-policy.default.conf | 1 + doc/misc/options | 1 + lib/dns/include/dns/kasp.h | 25 +++++++++++++++++++++++++ lib/dns/kasp.c | 16 ++++++++++++++++ lib/isccfg/kaspconf.c | 9 ++++++++- lib/isccfg/namedconf.c | 1 + 9 files changed, 65 insertions(+), 1 deletion(-) diff --git a/bin/named/config.c b/bin/named/config.c index cb58713c8a..380c8ebc51 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -309,6 +309,7 @@ dnssec-policy \"default\" {\n\ cds-digest-types { 2; };\n\ dnskey-ttl " DNS_KASP_KEY_TTL ";\n\ inline-signing yes;\n\ + manual-mode no;\n\ offline-ksk no;\n\ publish-safety " DNS_KASP_PUBLISH_SAFETY "; \n\ retire-safety " DNS_KASP_RETIRE_SAFETY "; \n\ @@ -327,6 +328,7 @@ dnssec-policy \"insecure\" {\n\ max-zone-ttl 0; \n\ keys { };\n\ inline-signing yes;\n\ + manual-mode no;\n\ };\n\ \n\ " diff --git a/bin/tests/system/checkconf/good.conf.j2 b/bin/tests/system/checkconf/good.conf.j2 index 876b086787..fc33cb6503 100644 --- a/bin/tests/system/checkconf/good.conf.j2 +++ b/bin/tests/system/checkconf/good.conf.j2 @@ -27,6 +27,7 @@ dnssec-policy "test" { zsk lifetime P30D algorithm 13; csk key-store "hsm" lifetime P30D algorithm 8 2048; }; + manual-mode no; max-zone-ttl 86400; nsec3param ; parent-ds-ttl 7200; diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 0592c64bf7..c0fb31ecad 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -6408,6 +6408,16 @@ keys ``insecure``. In this specific case, the existing key files should be moved to the zone's ``key-directory`` from the new configuration. +.. namedconf:statement:: manual-mode + :tags: dnssec + :short: Run key management in a manual mode. + + If enabled, BIND 9 does not automatically start and progress key rollovers, + instead the change is logged. Only after manual confirmation with + :option:`rndc dnssec -step ` the change is made. + + This feature is off by default. + .. namedconf:statement:: offline-ksk :tags: dnssec :short: Specifies whether the DNSKEY, CDS, and CDNSKEY RRsets are being signed offline. diff --git a/doc/misc/dnssec-policy.default.conf b/doc/misc/dnssec-policy.default.conf index d5571bac04..ce99f978fe 100644 --- a/doc/misc/dnssec-policy.default.conf +++ b/doc/misc/dnssec-policy.default.conf @@ -33,6 +33,7 @@ dnssec-policy "default" { signatures-validity-dnskey 14d; // Zone parameters + manual-mode no; inline-signing yes; max-zone-ttl 86400; zone-propagation-delay 300; diff --git a/doc/misc/options b/doc/misc/options index 3215fc7af7..5bb047d95a 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -16,6 +16,7 @@ dnssec-policy { dnskey-ttl ; inline-signing ; keys { ( csk | ksk | zsk ) [ key-directory | key-store ] lifetime algorithm [ tag-range ] [ ]; ... }; + manual-mode ; max-zone-ttl ; nsec3param [ iterations ] [ optout ] [ salt-length ]; offline-ksk ; diff --git a/lib/dns/include/dns/kasp.h b/lib/dns/include/dns/kasp.h index e2b0ea94df..999e08ddcb 100644 --- a/lib/dns/include/dns/kasp.h +++ b/lib/dns/include/dns/kasp.h @@ -108,6 +108,7 @@ struct dns_kasp { dns_ttl_t zone_max_ttl; uint32_t zone_propagation_delay; bool inline_signing; + bool manual_mode; /* Parent settings */ dns_ttl_t parent_ds_ttl; @@ -439,6 +440,30 @@ dns_kasp_setinlinesigning(dns_kasp_t *kasp, bool value); *\li 'kasp' is a valid, thawed kasp. */ +bool +dns_kasp_manualmode(dns_kasp_t *kasp); +/*%< + * Should we use manual-mode for this DNSSEC policy? + * + * Requires: + * + *\li 'kasp' is a valid, frozen kasp. + * + * Returns: + * + *\li true or false. + */ + +void +dns_kasp_setmanualmode(dns_kasp_t *kasp, bool value); +/*%< + * Set manual-mode. + * + * Requires: + * + *\li 'kasp' is a valid, thawed kasp. + */ + dns_ttl_t dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback); /*%< diff --git a/lib/dns/kasp.c b/lib/dns/kasp.c index 722c069d3a..884e3e33ec 100644 --- a/lib/dns/kasp.c +++ b/lib/dns/kasp.c @@ -273,6 +273,22 @@ dns_kasp_setinlinesigning(dns_kasp_t *kasp, bool value) { kasp->inline_signing = value; } +bool +dns_kasp_manualmode(dns_kasp_t *kasp) { + REQUIRE(DNS_KASP_VALID(kasp)); + REQUIRE(kasp->frozen); + + return kasp->manual_mode; +} + +void +dns_kasp_setmanualmode(dns_kasp_t *kasp, bool value) { + REQUIRE(DNS_KASP_VALID(kasp)); + REQUIRE(!kasp->frozen); + + kasp->manual_mode = value; +} + dns_ttl_t dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback) { REQUIRE(DNS_KASP_VALID(kasp)); diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c index 4bc62c0ba4..d83e0af46b 100644 --- a/lib/isccfg/kaspconf.c +++ b/lib/isccfg/kaspconf.c @@ -473,7 +473,7 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, uint32_t zonepropdelay = 0, parentpropdelay = 0; uint32_t ipub = 0, iret = 0; uint32_t ksk_min_lifetime = 0, zsk_min_lifetime = 0; - bool offline_ksk = false; + bool offline_ksk = false, manual_mode = false; REQUIRE(config != NULL); REQUIRE(kaspp != NULL && *kaspp == NULL); @@ -578,6 +578,13 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, dns_kasp_setinlinesigning(kasp, true); } + obj = NULL; + (void)confget(maps, "manual-mode", &obj); + if (obj != NULL) { + manual_mode = cfg_obj_asboolean(obj); + } + dns_kasp_setmanualmode(kasp, manual_mode); + maxttl = get_duration(maps, "max-zone-ttl", DNS_KASP_ZONE_MAXTTL); dns_kasp_setzonemaxttl(kasp, maxttl); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 67824c75e8..6d204ebeeb 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -2213,6 +2213,7 @@ static cfg_clausedef_t dnssecpolicy_clauses[] = { { "dnskey-ttl", &cfg_type_duration, 0 }, { "inline-signing", &cfg_type_boolean, 0 }, { "keys", &cfg_type_kaspkeys, 0 }, + { "manual-mode", &cfg_type_boolean, 0 }, { "max-zone-ttl", &cfg_type_duration, 0 }, { "nsec3param", &cfg_type_nsec3, 0 }, { "offline-ksk", &cfg_type_boolean, 0 },