return result;
}
-static isc_result_t
-mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) {
- const cfg_listelt_t *element;
- const cfg_obj_t *obj;
- const char *str;
- dns_fixedname_t fixed;
- dns_name_t *name;
- bool value;
- isc_result_t result;
- isc_buffer_t b;
-
- name = dns_fixedname_initname(&fixed);
- for (element = cfg_list_first(mbs); element != NULL;
- element = cfg_list_next(element))
- {
- obj = cfg_listelt_value(element);
- str = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
- isc_buffer_constinit(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
- value = cfg_obj_asboolean(cfg_tuple_get(obj, "value"));
- CHECK(dns_resolver_setmustbesecure(resolver, name, value));
- }
-
- result = ISC_R_SUCCESS;
-
-cleanup:
- return result;
-}
-
/*%
* Get a dispatch appropriate for the resolver of a given view.
*/
CHECK(configure_view_dnsseckeys(view, vconfig, config, bindkeys,
auto_root));
- obj = NULL;
- result = named_config_get(maps, "dnssec-must-be-secure", &obj);
- if (result == ISC_R_SUCCESS) {
- CHECK(mustbesecure(obj, view->resolver));
- }
-
obj = NULL;
result = named_config_get(maps, "nta-recheck", &obj);
INSIST(result == ISC_R_SUCCESS);
insecure NS ns.insecure
ns.insecure A 10.53.0.3
-; A insecure subdomain
-mustbesecure NS ns.mustbesecure
-ns.mustbesecure A 10.53.0.3
-
z A 10.0.0.26
nsec3 NS ns.nsec3
insecure NS ns.insecure
ns.insecure A 10.53.0.3
-; A insecure subdomain
-mustbesecure NS ns.mustbesecure
-ns.mustbesecure A 10.53.0.3
-
z A 10.0.0.26
nsec3 NS ns.nsec3
listen-on-v6 { none; };
recursion yes;
dnssec-validation yes;
- dnssec-must-be-secure mustbesecure.example yes;
};
zone "." {
dnssec-validation yes;
max-zone-ttl 600;
- dnssec-must-be-secure mustbesecure.example yes;
-
sortlist { };
};
grep "option 'managed-keys' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
grep "option 'trusted-keys' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
grep "option 'max-zone-ttl' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
-grep "option 'dnssec-must-be-secure' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
grep "option 'sortlist' is deprecated" <checkconf.out$n.1 >/dev/null || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
dynamic NS dynamic
dynamic A 10.53.0.3
-; A insecure subdomain
-mustbesecure NS ns.mustbesecure
-ns.mustbesecure A 10.53.0.3
-
; A subdomain with expired signatures
expired NS ns.expired
ns.expired A 10.53.0.3
dynamic NS dynamic
dynamic A 10.53.0.3
-; A insecure subdomain
-mustbesecure NS ns.mustbesecure
-ns.mustbesecure A 10.53.0.3
-
; A subdomain with expired signatures
expired NS ns.expired
ns.expired A 10.53.0.3
listen-on-v6 { none; };
recursion yes;
dnssec-validation yes;
- dnssec-must-be-secure mustbesecure.example yes;
minimal-responses no;
nta-lifetime 12s;
listen-on-v6 { none; };
recursion yes;
dnssec-validation yes;
- dnssec-must-be-secure . yes;
/* only SHA-256 is enabled */
disable-ds-digests . { SHA-1; SHA-384; 5; 6; 7; 8; 9; };
assert res.flags & dns.flags.AD
-def test_dsdigest_bad():
- """Check that validation with not supported digest types
- and "dnssec-must-be-secure yes;" results in SERVFAIL"""
- msg = dns.message.make_query("a.bad.", "A", want_dnssec=True)
- res = isctest.query.tcp(
- msg,
- "10.53.0.3",
- )
- isctest.check.servfail(res)
-
-
def test_dsdigest_insecure():
"""Check that validation with not supported digest algorithms is insecure"""
msg_ds = dns.message.make_query("bad.", "DS", want_dnssec=True)
dynamic NS dynamic
dynamic A 10.53.0.3
-; A insecure subdomain
-mustbesecure NS ns.mustbesecure
-ns.mustbesecure A 10.53.0.3
-
; A rfc2535 signed zone w/ CNAME
rfc2535 NS ns.rfc2535
ns.rfc2535 A 10.53.0.3
If all supported digest types are disabled, the zones covered by
:any:`disable-ds-digests` are treated as insecure.
-.. namedconf:statement:: dnssec-must-be-secure
- :tags: deprecated
- :short: Defines hierarchies that must or may not be secure (signed and validated).
-
- This option is deprecated and will be removed in a future release.
-
- This specifies hierarchies which must be or may not be secure (signed and
- validated). If ``yes``, then :iscman:`named` only accepts answers if
- they are secure. If ``no``, then normal DNSSEC validation applies,
- allowing insecure answers to be accepted. The specified domain
- must be defined as a trust anchor, for instance in a :any:`trust-anchors`
- statement, or ``dnssec-validation auto`` must be active.
-
.. namedconf:statement:: dns64
:tags: query
:short: Instructs :iscman:`named` to return mapped IPv4 addresses to AAAA queries when there are no AAAA records.
dnssec-accept-expired <boolean>;
dnssec-dnskey-kskonly <boolean>; // obsolete
dnssec-loadkeys-interval <integer>;
- dnssec-must-be-secure <string> <boolean>; // may occur multiple times, deprecated
dnssec-policy <string>;
dnssec-secure-to-insecure <boolean>; // obsolete
dnssec-update-mode ( maintain | no-resign ); // obsolete
dnssec-accept-expired <boolean>;
dnssec-dnskey-kskonly <boolean>; // obsolete
dnssec-loadkeys-interval <integer>;
- dnssec-must-be-secure <string> <boolean>; // may occur multiple times, deprecated
dnssec-policy <string>;
dnssec-secure-to-insecure <boolean>; // obsolete
dnssec-update-mode ( maintain | no-resign ); // obsolete
* crypto libraries if it was not specifically disabled.
*/
-isc_result_t
-dns_resolver_setmustbesecure(dns_resolver_t *resolver, const dns_name_t *name,
- bool value);
-
-bool
-dns_resolver_getmustbesecure(dns_resolver_t *resolver, const dns_name_t *name);
-
void
dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int timeout);
/*%<
dns_fixedname_t wild;
dns_fixedname_t closest;
ISC_LINK(dns_validator_t) link;
- bool mustbesecure;
unsigned int depth;
unsigned int authcount;
unsigned int authfail;
ISC_LIST(alternate_t) alternates;
dns_nametree_t *algorithms;
dns_nametree_t *digests;
- dns_nametree_t *mustbesecure;
unsigned int spillatmax;
unsigned int spillatmin;
isc_timer_t *spillattimer;
dns_nametree_detach(&res->algorithms);
dns_nametree_detach(&res->digests);
- dns_nametree_detach(&res->mustbesecure);
if (res->querystats != NULL) {
dns_stats_detach(&res->querystats);
&res->algorithms);
dns_nametree_create(res->mctx, DNS_NAMETREE_BITS, "ds-digests",
&res->digests);
- dns_nametree_create(res->mctx, DNS_NAMETREE_BOOL,
- "dnssec-must-be-secure", &res->mustbesecure);
res->namepools = isc_mem_cget(res->mctx, res->nloops,
sizeof(res->namepools[0]));
return dst_ds_digest_supported(digest_type);
}
-isc_result_t
-dns_resolver_setmustbesecure(dns_resolver_t *resolver, const dns_name_t *name,
- bool value) {
- isc_result_t result;
-
- REQUIRE(VALID_RESOLVER(resolver));
-
- result = dns_nametree_add(resolver->mustbesecure, name, value);
- return result;
-}
-
-bool
-dns_resolver_getmustbesecure(dns_resolver_t *resolver, const dns_name_t *name) {
- REQUIRE(VALID_RESOLVER(resolver));
-
- return dns_nametree_covered(resolver->mustbesecure, name, NULL, 0);
-}
-
void
dns_resolver_getclientsperquery(dns_resolver_t *resolver, uint32_t *cur,
uint32_t *min, uint32_t *max) {
/*%
* Mark the rdatasets in val->vstat with trust level "answer",
* indicating that they did not validate, but could be cached as insecure.
- *
- * If we are validating a name that is marked as "must be secure", log a
- * warning and return DNS_R_MUSTBESECURE instead.
*/
static isc_result_t
-markanswer(dns_validator_t *val, const char *where, const char *mbstext) {
- if (val->mustbesecure && mbstext != NULL) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure, %s", mbstext);
- return DNS_R_MUSTBESECURE;
- }
-
+markanswer(dns_validator_t *val, const char *where) {
validator_log(val, ISC_LOG_DEBUG(3), "marking as answer (%s)", where);
if (val->rdataset != NULL) {
dns_rdataset_settrust(val->rdataset, dns_trust_answer);
* insecurity. If this is a zone cut, that
* means we're insecure.
*/
- result = markanswer(
- val, "fetch_callback_ds",
- "no DS and this is a delegation");
+ result = markanswer(val, "fetch_callback_ds");
break;
}
FALLTHROUGH;
NEGATIVE(&val->frdataset) &&
isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET))
{
- result = markanswer(val, "validator_callback_ds",
- "no DS and this is a delegation");
+ result = markanswer(val, "validator_callback_ds");
} else if ((val->attributes & VALATTR_INSECURITY) != 0) {
result = proveunsecure(val, have_dsset, true);
} else {
if (!val->supported_algorithm) {
validator_log(val, ISC_LOG_DEBUG(3),
"no supported algorithm/digest (DS)");
- result = markanswer(
- val, "validate_dnskey (3)",
- "no supported algorithm/digest (DS)");
+ result = markanswer(val, "validate_dnskey (3)");
break;
}
FALLTHROUGH;
INSIST(val->dsset != NULL);
if (val->dsset->trust < dns_trust_secure) {
- result = markanswer(val, "validate_dnskey (2)", "insecure DS");
+ result = markanswer(val, "validate_dnskey (2)");
goto cleanup;
}
if (result == DNS_R_NSEC3ITERRANGE) {
validator_log(val, ISC_LOG_DEBUG(3),
"too many iterations");
- markanswer(val, "validate_nx (3)", NULL);
+ markanswer(val, "validate_nx (3)");
return ISC_R_SUCCESS;
}
}
validator_log(val, ISC_LOG_DEBUG(3),
"optout proof found");
val->optout = true;
- markanswer(val, "validate_nx (1)", NULL);
+ markanswer(val, "validate_nx (1)");
return ISC_R_SUCCESS;
} else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) {
validator_log(val, ISC_LOG_DEBUG(3),
"unknown NSEC3 hash algorithm found");
- markanswer(val, "validate_nx (2)", NULL);
+ markanswer(val, "validate_nx (2)");
return ISC_R_SUCCESS;
}
if (result == DNS_R_NSEC3ITERRANGE) {
validator_log(val, ISC_LOG_DEBUG(3),
"too many iterations");
- markanswer(val, "validate_nx (4)", NULL);
+ markanswer(val, "validate_nx (4)");
return ISC_R_SUCCESS;
}
}
val, ISC_LOG_DEBUG(3),
"no supported algorithm/digest (%s/DS)",
namebuf);
- *resp = markanswer(val, "proveunsecure (5)",
- "no supported "
- "algorithm/digest (DS)");
+ *resp = markanswer(val, "proveunsecure (5)");
return ISC_R_COMPLETE;
}
NULL) == ISC_R_SUCCESS &&
dns_name_equal(tname, found))
{
- *resp = markanswer(val, "proveunsecure (3)",
- "no DS at zone cut");
+ *resp = markanswer(val, "proveunsecure (3)");
return ISC_R_COMPLETE;
}
}
if (isdelegation(tname, &val->frdataset, result)) {
- *resp = markanswer(val, "proveunsecure (4)",
- "this is a delegation");
+ *resp = markanswer(val, "proveunsecure (4)");
return ISC_R_COMPLETE;
}
result = dns_keytable_finddeepestmatch(val->keytable, secroot, secroot);
if (result == ISC_R_NOTFOUND) {
validator_log(val, ISC_LOG_DEBUG(3), "not beneath secure root");
- return markanswer(val, "proveunsecure (1)",
- "not beneath secure root");
+ return markanswer(val, "proveunsecure (1)");
} else if (result != ISC_R_SUCCESS) {
return result;
}
validator_log(val, ISC_LOG_DEBUG(3),
"no supported algorithm/digest (%s/DS)",
namebuf);
- result = markanswer(val, "proveunsecure (2)", namebuf);
+ result = markanswer(val, "proveunsecure (2)");
goto out;
}
val->labels++;
isc_counter_attach(gqc, &val->gqc);
}
- val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
dns_rdataset_init(&val->fdsset);
dns_rdataset_init(&val->frdataset);
dns_rdataset_init(&val->fsigrdataset);
return result;
}
-static isc_result_t
-mustbesecure(const cfg_obj_t *secure, isc_symtab_t *symtab, isc_mem_t *mctx) {
- const cfg_obj_t *obj;
- char namebuf[DNS_NAME_FORMATSIZE];
- const char *str;
- dns_fixedname_t fixed;
- dns_name_t *name;
- isc_buffer_t b;
- isc_result_t result = ISC_R_SUCCESS;
-
- name = dns_fixedname_initname(&fixed);
- obj = cfg_tuple_get(secure, "name");
- str = cfg_obj_asstring(obj);
- isc_buffer_constinit(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
- if (result != ISC_R_SUCCESS) {
- cfg_obj_log(obj, ISC_LOG_ERROR, "bad domain name '%s'", str);
- } else {
- dns_name_format(name, namebuf, sizeof(namebuf));
- result = exists(secure, namebuf, 1, symtab,
- "dnssec-must-be-secure '%s': already exists "
- "previous definition: %s:%u",
- mctx);
- }
- return result;
-}
-
static isc_result_t
checkacl(const char *aclname, cfg_aclconfctx_t *actx, const cfg_obj_t *zconfig,
const cfg_obj_t *voptions, const cfg_obj_t *config, isc_mem_t *mctx) {
unsigned int i;
const cfg_obj_t *obj = NULL;
const cfg_listelt_t *element;
- isc_symtab_t *symtab = NULL;
const char *str;
isc_buffer_t b;
uint32_t lifetime = 3600;
}
}
- /*
- * Check dnssec-must-be-secure.
- */
- obj = NULL;
- (void)cfg_map_get(options, "dnssec-must-be-secure", &obj);
- if (obj != NULL) {
- tresult = isc_symtab_create(mctx, 100, freekey, mctx, false,
- &symtab);
- if (tresult != ISC_R_SUCCESS) {
- result = tresult;
- } else {
- for (element = cfg_list_first(obj); element != NULL;
- element = cfg_list_next(element))
- {
- obj = cfg_listelt_value(element);
- tresult = mustbesecure(obj, symtab, mctx);
- if (result == ISC_R_SUCCESS &&
- tresult != ISC_R_SUCCESS)
- {
- result = tresult;
- }
- }
- }
- if (symtab != NULL) {
- isc_symtab_destroy(&symtab);
- }
- }
-
/*
* Check server/contacts for syntactic validity.
*/
cfg_doc_tuple, &cfg_rep_tuple, disabledsdigest_fields
};
-static cfg_tuplefielddef_t mustbesecure_fields[] = {
- { "name", &cfg_type_astring, 0 },
- { "value", &cfg_type_boolean, 0 },
- { NULL, NULL, 0 }
-};
-
-static cfg_type_t cfg_type_mustbesecure = {
- "mustbesecure", cfg_parse_tuple, cfg_print_tuple,
- cfg_doc_tuple, &cfg_rep_tuple, mustbesecure_fields
-};
-
static const char *masterformat_enums[] = { "raw", "text", NULL };
static cfg_type_t cfg_type_masterformat = {
"masterformat", cfg_parse_enum, cfg_print_ustring,
{ "dnssec-enable", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "dnssec-lookaside", NULL,
CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_ANCIENT },
- { "dnssec-must-be-secure", &cfg_type_mustbesecure,
- CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_DEPRECATED },
+ { "dnssec-must-be-secure", NULL,
+ CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_ANCIENT },
{ "dnssec-validation", &cfg_type_boolorauto, 0 },
#ifdef HAVE_DNSTAP
{ "dnstap", &cfg_type_dnstap, CFG_CLAUSEFLAG_OPTIONAL },