mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 13:20:00 -04:00
Merge branch '997-make-ntas-work-with-validating-forwarders-v9_14' into 'v9_14'
Make NTAs work with validating forwarders See merge request isc-projects/bind9!1922
This commit is contained in:
commit
ddb09b8046
9 changed files with 115 additions and 25 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
5232. [bug] Negative trust anchors did not work with "forward only;"
|
||||
to validating resolvers. [GL #997]
|
||||
|
||||
5231. [protocol] Add support for displaying CLIENT-TAG and SERVER-TAG.
|
||||
[GL #960]
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ cp trusted.conf ../ns3/trusted.conf
|
|||
cp trusted.conf ../ns4/trusted.conf
|
||||
cp trusted.conf ../ns6/trusted.conf
|
||||
cp trusted.conf ../ns7/trusted.conf
|
||||
cp trusted.conf ../ns9/trusted.conf
|
||||
|
||||
# ...or with a managed key.
|
||||
keyfile_to_managed_keys "$keyname" > managed.conf
|
||||
|
|
|
|||
38
bin/tests/system/dnssec/ns9/named.conf.in
Normal file
38
bin/tests/system/dnssec/ns9/named.conf.in
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
// NS9
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.9;
|
||||
notify-source 10.53.0.9;
|
||||
transfer-source 10.53.0.9;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.9; };
|
||||
listen-on-v6 { none; };
|
||||
recursion yes;
|
||||
dnssec-enable yes;
|
||||
dnssec-validation yes;
|
||||
forward only;
|
||||
forwarders { 10.53.0.4; };
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
include "trusted.conf";
|
||||
|
|
@ -27,6 +27,8 @@ copy_setports ns6/named.conf.in ns6/named.conf
|
|||
copy_setports ns7/named.conf.in ns7/named.conf
|
||||
copy_setports ns8/named.conf.in ns8/named.conf
|
||||
|
||||
copy_setports ns9/named.conf.in ns9/named.conf
|
||||
|
||||
(
|
||||
cd ns1
|
||||
$SHELL sign.sh
|
||||
|
|
|
|||
|
|
@ -2300,9 +2300,31 @@ fi
|
|||
# cleanup
|
||||
rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.3 2>/dev/null
|
||||
|
||||
n=$((n+1))
|
||||
if [ "$ret" -ne 0 ]; then echo_i "failed - NTA lifetime clamping failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "checking that NTAs work with 'forward only;' to a validating resolver ($n)"
|
||||
ret=0
|
||||
# Sanity check behavior without an NTA in place.
|
||||
dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.1 || ret=1
|
||||
grep "SERVFAIL" dig.out.ns9.test$n.1 > /dev/null || ret=1
|
||||
grep "ANSWER: 0" dig.out.ns9.test$n.1 > /dev/null || ret=1
|
||||
grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.1 > /dev/null && ret=1
|
||||
# Add an NTA, expecting that to cause resolution to succeed.
|
||||
rndccmd 10.53.0.9 nta badds.example > rndc.out.ns9.test$n.1 2>&1 || ret=1
|
||||
dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.2 || ret=1
|
||||
grep "NOERROR" dig.out.ns9.test$n.2 > /dev/null || ret=1
|
||||
grep "ANSWER: 2" dig.out.ns9.test$n.2 > /dev/null || ret=1
|
||||
grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.2 > /dev/null && ret=1
|
||||
# Remove the NTA, expecting that to cause resolution to fail again.
|
||||
rndccmd 10.53.0.9 nta -remove badds.example > rndc.out.ns9.test$n.2 2>&1 || ret=1
|
||||
dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.3 || ret=1
|
||||
grep "SERVFAIL" dig.out.ns9.test$n.3 > /dev/null || ret=1
|
||||
grep "ANSWER: 0" dig.out.ns9.test$n.3 > /dev/null || ret=1
|
||||
grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.3 > /dev/null && ret=1
|
||||
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "completed NTA tests"
|
||||
|
||||
|
|
|
|||
|
|
@ -1190,14 +1190,16 @@ dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp);
|
|||
|
||||
isc_result_t
|
||||
dns_view_issecuredomain(dns_view_t *view, const dns_name_t *name,
|
||||
isc_stdtime_t now, bool checknta,
|
||||
isc_stdtime_t now, bool checknta, bool *ntap,
|
||||
bool *secure_domain);
|
||||
/*%<
|
||||
* Is 'name' at or beneath a trusted key, and not covered by a valid
|
||||
* negative trust anchor? Put answer in '*secure_domain'.
|
||||
*
|
||||
* If 'checknta' is false, ignore the NTA table in determining
|
||||
* whether this is a secure domain.
|
||||
* whether this is a secure domain. If 'checknta' is not false, and if
|
||||
* 'ntap' is non-NULL, then '*ntap' will be updated with true if the
|
||||
* name is covered by an NTA.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'view' is valid.
|
||||
|
|
|
|||
|
|
@ -2328,8 +2328,7 @@ compute_cc(resquery_t *query, unsigned char *cookie, size_t len) {
|
|||
|
||||
static isc_result_t
|
||||
issecuredomain(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
|
||||
isc_stdtime_t now, bool checknta,
|
||||
bool *issecure)
|
||||
isc_stdtime_t now, bool checknta, bool *ntap, bool *issecure)
|
||||
{
|
||||
dns_name_t suffix;
|
||||
unsigned int labels;
|
||||
|
|
@ -2347,7 +2346,8 @@ issecuredomain(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
|
|||
name = &suffix;
|
||||
}
|
||||
|
||||
return (dns_view_issecuredomain(view, name, now, checknta, issecure));
|
||||
return (dns_view_issecuredomain(view, name, now, checknta,
|
||||
ntap, issecure));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
@ -2451,24 +2451,30 @@ resquery_send(resquery_t *query) {
|
|||
* question is under a secure entry point and this is a
|
||||
* recursive/forward query -- unless the client said not to.
|
||||
*/
|
||||
if ((query->options & DNS_FETCHOPT_NOCDFLAG) != 0)
|
||||
if ((query->options & DNS_FETCHOPT_NOCDFLAG) != 0) {
|
||||
/* Do nothing */
|
||||
;
|
||||
else if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0)
|
||||
} else if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
|
||||
fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
|
||||
else if (res->view->enablevalidation &&
|
||||
((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0))
|
||||
} else if (res->view->enablevalidation &&
|
||||
((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0))
|
||||
{
|
||||
bool checknta = ((query->options & DNS_FETCHOPT_NONTA) == 0);
|
||||
bool ntacovered = false;
|
||||
result = issecuredomain(res->view, &fctx->name, fctx->type,
|
||||
isc_time_seconds(&query->start),
|
||||
checknta, &secure_domain);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
checknta, &ntacovered, &secure_domain);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
secure_domain = false;
|
||||
if (res->view->dlv != NULL)
|
||||
}
|
||||
if (res->view->dlv != NULL) {
|
||||
secure_domain = true;
|
||||
if (secure_domain)
|
||||
}
|
||||
|
||||
if (secure_domain ||
|
||||
(ISFORWARDER(query->addrinfo) && ntacovered))
|
||||
{
|
||||
fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -5923,7 +5929,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
|
|||
|
||||
if (res->view->enablevalidation) {
|
||||
result = issecuredomain(res->view, name, fctx->type,
|
||||
now, checknta, &secure_domain);
|
||||
now, checknta, NULL, &secure_domain);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -6518,7 +6524,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||
|
||||
if (fctx->res->view->enablevalidation) {
|
||||
result = issecuredomain(res->view, name, fctx->type,
|
||||
now, checknta, &secure_domain);
|
||||
now, checknta, NULL, &secure_domain);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
|
|
|
|||
|
|
@ -676,15 +676,17 @@ nta_test(void **state) {
|
|||
/* Should be secure */
|
||||
result = dns_view_issecuredomain(myview,
|
||||
str2name("test.secure.example"),
|
||||
now, true, &issecure);
|
||||
now, true, &covered, &issecure);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_false(covered);
|
||||
assert_true(issecure);
|
||||
|
||||
/* Should not be secure */
|
||||
result = dns_view_issecuredomain(myview,
|
||||
str2name("test.insecure.example"),
|
||||
now, true, &issecure);
|
||||
now, true, &covered, &issecure);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_true(covered);
|
||||
assert_false(issecure);
|
||||
|
||||
/* NTA covered */
|
||||
|
|
@ -700,14 +702,16 @@ nta_test(void **state) {
|
|||
/* As of now + 2, the NTA should be clear */
|
||||
result = dns_view_issecuredomain(myview,
|
||||
str2name("test.insecure.example"),
|
||||
now + 2, true, &issecure);
|
||||
now + 2, true, &covered, &issecure);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_false(covered);
|
||||
assert_true(issecure);
|
||||
|
||||
/* Now check deletion */
|
||||
result = dns_view_issecuredomain(myview, str2name("test.new.example"),
|
||||
now, true, &issecure);
|
||||
now, true, &covered, &issecure);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_false(covered);
|
||||
assert_true(issecure);
|
||||
|
||||
result = dns_ntatable_add(ntatable, str2name("new.example"),
|
||||
|
|
@ -715,16 +719,18 @@ nta_test(void **state) {
|
|||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = dns_view_issecuredomain(myview, str2name("test.new.example"),
|
||||
now, true, &issecure);
|
||||
now, true, &covered, &issecure);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_true(covered);
|
||||
assert_false(issecure);
|
||||
|
||||
result = dns_ntatable_delete(ntatable, str2name("new.example"));
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = dns_view_issecuredomain(myview, str2name("test.new.example"),
|
||||
now, true, &issecure);
|
||||
now, true, &covered, &issecure);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_false(covered);
|
||||
assert_true(issecure);
|
||||
|
||||
/* Clean up */
|
||||
|
|
|
|||
|
|
@ -1911,7 +1911,7 @@ dns_view_ntacovers(dns_view_t *view, isc_stdtime_t now,
|
|||
|
||||
isc_result_t
|
||||
dns_view_issecuredomain(dns_view_t *view, const dns_name_t *name,
|
||||
isc_stdtime_t now, bool checknta,
|
||||
isc_stdtime_t now, bool checknta, bool *ntap,
|
||||
bool *secure_domain)
|
||||
{
|
||||
isc_result_t result;
|
||||
|
|
@ -1921,19 +1921,29 @@ dns_view_issecuredomain(dns_view_t *view, const dns_name_t *name,
|
|||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
if (view->secroots_priv == NULL)
|
||||
if (view->secroots_priv == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
anchor = dns_fixedname_initname(&fn);
|
||||
|
||||
result = dns_keytable_issecuredomain(view->secroots_priv, name,
|
||||
anchor, &secure);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (ntap != NULL) {
|
||||
*ntap = false;
|
||||
}
|
||||
if (checknta && secure && view->ntatable_priv != NULL &&
|
||||
dns_ntatable_covered(view->ntatable_priv, now, name, anchor))
|
||||
{
|
||||
if (ntap != NULL) {
|
||||
*ntap = true;
|
||||
}
|
||||
secure = false;
|
||||
}
|
||||
|
||||
*secure_domain = secure;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
|
|
|||
Loading…
Reference in a new issue