When loading dnssec-policies, inherit from default

Most of the settings (durations) are already inheriting from the default
because they use the constants from lib/dns/kasp.h. We need them as
constants so we can use them in named-checkconf to verify the policy
parameters.

The NSEC(3) parameters and keys should come from the actual default
policy. Change the call to cfg_kasp_fromconfig() to include the default
kasp. We also no longer need to corner case where config is NULL we load
the built-in policy: the built-in policies are now loaded when config is
set to named_g_config.

Finally, add a debug log (it is useful to see which policies are being
loaded).

(cherry picked from commit 20acb8d3a3)
This commit is contained in:
Matthijs Mekking 2022-06-21 12:40:12 +02:00
parent 03c0c72aeb
commit e16cfce91d
3 changed files with 80 additions and 37 deletions

View file

@ -8479,6 +8479,7 @@ load_configuration(const char *filename, named_server_t *server,
const cfg_obj_t *kasps;
dns_kasp_t *kasp = NULL;
dns_kasp_t *kasp_next = NULL;
dns_kasp_t *default_kasp = NULL;
dns_kasplist_t tmpkasplist, kasplist;
const cfg_obj_t *views;
dns_view_t *view = NULL;
@ -9205,10 +9206,10 @@ load_configuration(const char *filename, named_server_t *server,
(void)configure_session_key(maps, server, named_g_mctx, first_time);
/*
* Create the DNSSEC key and signing policies (KASP).
* Create the built-in kasp policies ("default", "insecure").
*/
kasps = NULL;
(void)cfg_map_get(config, "dnssec-policy", &kasps);
(void)cfg_map_get(named_g_config, "dnssec-policy", &kasps);
for (element = cfg_list_first(kasps); element != NULL;
element = cfg_list_next(element))
{
@ -9218,25 +9219,31 @@ load_configuration(const char *filename, named_server_t *server,
named_g_lctx, &kasplist, &kasp));
INSIST(kasp != NULL);
dns_kasp_freeze(kasp);
if (strcmp(dns_kasp_getname(kasp), "default") == 0) {
dns_kasp_attach(kasp, &default_kasp);
}
dns_kasp_detach(&kasp);
}
INSIST(default_kasp != NULL);
/*
* Create the built-in kasp policies ("default", "insecure").
* Create the DNSSEC key and signing policies (KASP).
*/
kasp = NULL;
CHECK(cfg_kasp_fromconfig(NULL, "default", named_g_mctx, named_g_lctx,
&kasplist, &kasp));
INSIST(kasp != NULL);
dns_kasp_freeze(kasp);
dns_kasp_detach(&kasp);
kasp = NULL;
CHECK(cfg_kasp_fromconfig(NULL, "insecure", named_g_mctx, named_g_lctx,
&kasplist, &kasp));
INSIST(kasp != NULL);
dns_kasp_freeze(kasp);
dns_kasp_detach(&kasp);
kasps = NULL;
(void)cfg_map_get(config, "dnssec-policy", &kasps);
for (element = cfg_list_first(kasps); element != NULL;
element = cfg_list_next(element))
{
cfg_obj_t *kconfig = cfg_listelt_value(element);
kasp = NULL;
CHECK(cfg_kasp_fromconfig(kconfig, default_kasp, named_g_mctx,
named_g_lctx, &kasplist, &kasp));
INSIST(kasp != NULL);
dns_kasp_freeze(kasp);
dns_kasp_detach(&kasp);
}
dns_kasp_detach(&default_kasp);
tmpkasplist = server->kasplist;
server->kasplist = kasplist;
kasplist = tmpkasplist;

View file

@ -26,14 +26,15 @@
ISC_LANG_BEGINDECLS
isc_result_t
cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx,
isc_log_t *logctx, dns_kasplist_t *kasplist,
dns_kasp_t **kaspp);
cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
isc_mem_t *mctx, isc_log_t *logctx,
dns_kasplist_t *kasplist, dns_kasp_t **kaspp);
/*%<
* Create and configure a KASP. If 'config' is NULL, a built-in configuration
* is used, referred to by 'name'. If a 'kasplist' is provided, a lookup
* happens and if a KASP already exists with the same name, no new KASP is
* created, and no attach to 'kaspp' happens.
* Create and configure a KASP. If 'default_kasp' is not NULL, the built-in
* default configuration is used to set values that are not explicitly set in
* the policy. If a 'kasplist' is provided, a lookup happens and if a KASP
* already exists with the same name, no new KASP is created, and no attach to
* 'kaspp' happens.
*
* Requires:
*

View file

@ -311,9 +311,9 @@ cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
}
isc_result_t
cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx,
isc_log_t *logctx, dns_kasplist_t *kasplist,
dns_kasp_t **kaspp) {
cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
isc_mem_t *mctx, isc_log_t *logctx,
dns_kasplist_t *kasplist, dns_kasp_t **kaspp) {
isc_result_t result;
const cfg_obj_t *maps[2];
const cfg_obj_t *koptions = NULL;
@ -336,6 +336,9 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx,
kaspname = cfg_obj_asstring(cfg_tuple_get(config, "name"));
INSIST(kaspname != NULL);
cfg_obj_log(config, logctx, ISC_LOG_DEBUG(1),
"dnssec-policy: load policy '%s'", kaspname);
result = dns_kasplist_find(kasplist, kaspname, &kasp);
if (result == ISC_R_SUCCESS) {
@ -456,7 +459,6 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx,
goto cleanup;
}
}
INSIST(!(dns_kasp_keylist_empty(kasp)));
dns_kasp_freeze(kasp);
for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
kkey = ISC_LIST_NEXT(kkey, link))
@ -509,23 +511,56 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx,
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
} else if (strcmp(kaspname, "insecure") == 0) {
/* "dnssec-policy insecure": key list must be empty */
INSIST(strcmp(kaspname, "insecure") == 0);
INSIST(dns_kasp_keylist_empty(kasp));
} else {
/* No keys clause configured, use the "default". */
result = cfg_kaspkey_fromconfig(NULL, kasp, logctx, 0, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup;
} else if (default_kasp && strcmp(kaspname, "insecure") != 0) {
dns_kasp_key_t *key, *new_key;
/*
* If there are no specific keys configured in the policy,
* inherit from the default policy (except for the built-in
* "insecure" policy).
*/
for (key = ISC_LIST_HEAD(dns_kasp_keys(default_kasp));
key != NULL; key = ISC_LIST_NEXT(key, link))
{
/* Create a new key reference. */
new_key = NULL;
result = dns_kasp_key_create(kasp, &new_key);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
if (dns_kasp_key_ksk(key)) {
new_key->role |= DNS_KASP_KEY_ROLE_KSK;
}
if (dns_kasp_key_zsk(key)) {
new_key->role |= DNS_KASP_KEY_ROLE_ZSK;
}
new_key->lifetime = dns_kasp_key_lifetime(key);
new_key->algorithm = dns_kasp_key_algorithm(key);
new_key->length = dns_kasp_key_size(key);
dns_kasp_addkey(kasp, new_key);
}
}
if (strcmp(kaspname, "insecure") == 0) {
/* "dnssec-policy insecure": key list must be empty */
INSIST(dns_kasp_keylist_empty(kasp));
} else if (default_kasp != NULL) {
/* There must be keys configured. */
INSIST(!(dns_kasp_keylist_empty(kasp)));
}
/* Configuration: NSEC3 */
(void)confget(maps, "nsec3param", &nsec3);
if (nsec3 == NULL) {
dns_kasp_setnsec3(kasp, false);
if (default_kasp != NULL && dns_kasp_nsec3(default_kasp)) {
dns_kasp_setnsec3param(
kasp, dns_kasp_nsec3iter(default_kasp),
(dns_kasp_nsec3flags(default_kasp) == 0x01),
dns_kasp_nsec3saltlen(default_kasp));
} else {
dns_kasp_setnsec3(kasp, false);
}
} else {
dns_kasp_setnsec3(kasp, true);
result = cfg_nsec3param_fromconfig(nsec3, kasp, logctx);