Commit b8a96323 authored by Evan Hunt's avatar Evan Hunt

[master] complete NTA work

3882.	[func]		By default, negative trust anchors will be tested
			periodically to see whether data below them can be
			validated, and if so, they will be allowed to
			expire early. The "rndc nta -force" option
			overrides this behvaior.  The default NTA lifetime
			and the recheck frequency can be configured by the
			"nta-lifetime" and "nta-recheck" options. [RT #36146]
parent 8eb2d262
3882. [func] By default, negative trust anchors will be tested
periodically to see whether data below them can be
validated, and if so, they will be allowed to
expire early. The "rndc nta -force" option
overrides this behvaior. The default NTA lifetime
and the recheck frequency can be configured by the
"nta-lifetime" and "nta-recheck" options. [RT #36146]
3881. [bug] Address memory leak with UPDATE error handling.
[RT #36303]
......
......@@ -53,6 +53,7 @@
static char defaultconf[] = "\
options {\n\
automatic-interface-scan yes;\n\
bindkeys-file \"" NS_SYSCONFDIR "/bind.keys\";\n\
# blackhole {none;};\n"
#ifndef WIN32
" coresize default;\n\
......@@ -78,8 +79,9 @@ options {\n\
memstatistics-file \"named.memstats\";\n\
multiple-cnames no;\n\
# named-xfer <obsolete>;\n\
nta-lifetime 3600;\n\
nta-recheck 300;\n\
# pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\
bindkeys-file \"" NS_SYSCONFDIR "/bind.keys\";\n\
port 53;\n\
prefetch 2 9;\n\
recursing-file \"named.recursing\";\n\
......
......@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id$ */
/*! \file */
#include <config.h>
......
......@@ -826,7 +826,7 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
return (ISC_R_UNEXPECTED);
}
result = dns_view_initntatable(view, mctx);
result = dns_view_initntatable(view, ns_g_taskmgr, ns_g_timermgr);
if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
......@@ -3566,6 +3566,16 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
if (result == ISC_R_SUCCESS)
CHECK(mustbesecure(obj, view->resolver));
obj = NULL;
result = ns_config_get(maps, "nta-recheck", &obj);
INSIST(result == ISC_R_SUCCESS);
view->nta_recheck = cfg_obj_asuint32(obj);
obj = NULL;
result = ns_config_get(maps, "nta-lifetime", &obj);
INSIST(result == ISC_R_SUCCESS);
view->nta_lifetime = cfg_obj_asuint32(obj);
obj = NULL;
result = ns_config_get(maps, "preferred-glue", &obj);
if (result == ISC_R_SUCCESS) {
......@@ -3626,6 +3636,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
} else {
empty_zones_enable = ISC_FALSE;
}
if (empty_zones_enable && !lwresd_g_useresolvconf) {
const char *empty;
int empty_zone = 0;
......@@ -7768,6 +7779,7 @@ isc_result_t
ns_server_dumpsecroots(ns_server_t *server, char *args) {
dns_view_t *view;
dns_keytable_t *secroots = NULL;
dns_ntatable_t *ntatable = NULL;
isc_result_t result;
char *ptr;
FILE *fp = NULL;
......@@ -7801,11 +7813,25 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
result = ISC_R_SUCCESS;
continue;
}
fprintf(fp, "\n Start view %s\n\n", view->name);
fprintf(fp, "\n Start view %s\n", view->name);
fprintf(fp, " Secure roots:\n\n");
result = dns_keytable_dump(secroots, fp);
if (result != ISC_R_SUCCESS)
fprintf(fp, " dumpsecroots failed: %s\n",
isc_result_totext(result));
if (ntatable != NULL)
dns_ntatable_detach(&ntatable);
result = dns_view_getntatable(view, &ntatable);
if (result == ISC_R_NOTFOUND) {
result = ISC_R_SUCCESS;
continue;
}
fprintf(fp, "\n Negative trust anchors:\n\n");
result = dns_ntatable_dump(ntatable, fp);
if (result != ISC_R_SUCCESS)
fprintf(fp, " dumpntatable failed: %s\n",
isc_result_totext(result));
}
if (ptr != NULL)
ptr = next_token(&args, " \t");
......@@ -7814,6 +7840,8 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
cleanup:
if (secroots != NULL)
dns_keytable_detach(&secroots);
if (ntatable != NULL)
dns_ntatable_detach(&ntatable);
if (fp != NULL)
(void)isc_stdio_close(fp);
if (result == ISC_R_SUCCESS)
......@@ -9772,15 +9800,18 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t *text) {
dns_view_t *view;
dns_ntatable_t *ntatable = NULL;
isc_result_t result;
char *ptr, *nametext, *viewname;
char *ptr, *nametext = NULL, *viewname;
isc_stdtime_t now, when;
isc_time_t t;
char tbuf[64];
const char *msg = NULL;
isc_boolean_t dump = ISC_FALSE, force = ISC_FALSE;
dns_fixedname_t fn;
dns_name_t *ntaname;
dns_ttl_t ntattl;
isc_textregion_t tr;
isc_boolean_t ttlset = ISC_FALSE;
UNUSED(force);
dns_fixedname_init(&fn);
ntaname = dns_fixedname_name(&fn);
......@@ -9790,8 +9821,78 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t *text) {
if (ptr == NULL)
return (ISC_R_UNEXPECTEDEND);
for (;;) {
size_t len;
/* Check for options */
ptr = next_token(&args, " \t");
if (ptr == NULL)
return (ISC_R_UNEXPECTEDEND);
len = strlen(ptr);
if (strncasecmp(ptr, "-dump", len) == 0)
dump = ISC_TRUE;
else if (strncasecmp(ptr, "-remove", len) == 0) {
ntattl = 0;
ttlset = ISC_TRUE;
} else if (strncasecmp(ptr, "-force", len) == 0) {
force = ISC_TRUE;
continue;
} else if (strncasecmp(ptr, "-lifetime", len) == 0) {
isc_textregion_t tr;
ptr = next_token(&args, " \t");
if (ptr == NULL) {
msg = "No lifetime specified";
CHECK(ISC_R_UNEXPECTEDEND);
}
tr.base = ptr;
tr.length = strlen(ptr);
result = dns_ttl_fromtext(&tr, &ntattl);
if (result != ISC_R_SUCCESS) {
msg = "could not parse NTA lifetime";
CHECK(result);
}
if (ntattl > 86400) {
msg = "NTA lifetime cannot exceed one day";
CHECK(ISC_R_RANGE);
}
ttlset = ISC_TRUE;
continue;
} else
nametext = ptr;
break;
}
/*
* If -dump was specified, list NTA's and return
*/
if (dump) {
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
if (ntatable != NULL)
dns_ntatable_detach(&ntatable);
result = dns_view_getntatable(view, &ntatable);
if (result == ISC_R_NOTFOUND) {
result = ISC_R_SUCCESS;
continue;
}
CHECK(dns_ntatable_totext(ntatable, text));
}
goto cleanup;
}
/* Get the NTA name. */
nametext = next_token(&args, " \t");
if (nametext == NULL)
nametext = next_token(&args, " \t");
if (nametext == NULL)
return (ISC_R_UNEXPECTEDEND);
......@@ -9804,26 +9905,10 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t *text) {
CHECK(dns_name_fromtext(ntaname, &b, dns_rootname, 0, NULL));
}
/* Get the NTA duration. */
ptr = next_token(&args, " \t");
if (ptr == NULL)
return (ISC_R_UNEXPECTEDEND);
tr.base = ptr;
tr.length = strlen(ptr);
CHECK(dns_ttl_fromtext(&tr, &ntattl));
if (ntattl > 86400) {
msg = "NTA cannot exceed one day";
CHECK(ISC_R_RANGE);
}
/* Look for the view name. */
viewname = next_token(&args, " \t");
/* Set up the NTA */
isc_stdtime_get(&now);
when = now + ntattl;
result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
......@@ -9835,6 +9920,12 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t *text) {
strcmp(view->name, viewname) != 0)
continue;
if (view->nta_lifetime == 0 || view->nta_recheck == 0)
continue;
if (!ttlset)
ntattl = view->nta_lifetime;
if (ntatable != NULL)
dns_ntatable_detach(&ntatable);
......@@ -9851,11 +9942,13 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t *text) {
nametext, view->name,
isc_result_totext(result));
isc_time_set(&t, when, 0);
isc_time_formattimestamp(&t, tbuf, sizeof(tbuf));
if (ntattl != 0) {
CHECK(dns_ntatable_add(ntatable, ntaname,
force, now, ntattl));
if (ntattl > 0) {
CHECK(dns_ntatable_add(ntatable, ntaname, when));
when = now + ntattl;
isc_time_set(&t, when, 0);
isc_time_formattimestamp(&t, tbuf, sizeof(tbuf));
CHECK(putstr(text, "Negative trust anchor added: "));
CHECK(putstr(text, nametext));
......
......@@ -463,10 +463,9 @@
<term><userinput>secroots <optional><replaceable>view ...</replaceable></optional></userinput></term>
<listitem>
<para>
Dump the server's security roots to the secroots
file for the specified views. If no view is
specified, security roots for all
views are dumped.
Dump the server's security roots and negative trust anchors
to the secroots file for the specified views. If no view is
specified, all views are dumped.
</para>
</listitem>
</varlistentry>
......@@ -597,12 +596,19 @@
</varlistentry>
<varlistentry>
<term><userinput>nta <replaceable>domain</replaceable> <replaceable>duration</replaceable> </userinput></term>
<term><userinput>nta
<optional>( -d | -f | -r | -l <replaceable>duration</replaceable>)</optional>
<replaceable>domain</replaceable>
<optional><replaceable>view</replaceable></optional>
</userinput></term>
<listitem>
<para>
Sets a DNSSEC negative trust anchor (NTA)
for <option>domain</option>, with a lifetime of
<option>duration</option> (up to a limit of one day).
<option>lifetime</option>. The default lifetime is
configured in <file>named.conf</file> via the
<option>nta-lifetime</option>, and defaults to
one hour. The lifetime cannot exceed one day.
</para>
<para>
A negative trust anchor selectively disables
......@@ -617,13 +623,40 @@
restarted (NTA's do not persist across restarts).
</para>
<para>
TTL-style suffixes can be used to specify
<option>duration</option> in seconds, minutes, or hours.
An existing NTA can be removed by using the
<option>-remove</option> option.
</para>
<para>
An NTA's lifetime can be specified with the
<option>-lifetime</option> option. TTL-style
suffixes can be used to specify the lifetime in
seconds, minutes, or hours. If the specified NTA
already exists, its lifetime will be updated to the
new value. Setting <option>lifetime</option> to zero
is equivalent to <option>-remove</option>.
</para>
<para>
If <option>-dump</option> is used, any other arguments
are ignored, and a list of existing NTAs is printed
(note that this may include NTAs that are expired but
have not yet been cleaned up).
</para>
<para>
Normally, <command>named</command> will periodically
test to see whether data below an NTA can now be
validated (see the <option>nta-recheck</option> option
in the Administrator Reference Manual for details).
If data can be validated, then the NTA is regarded as
no longer necessary, and will be allowed to expire
early. The <option>-force</option> overrides this
behavior and forces an NTA to persist for its entire
lifetime, regardless of whether data could be
validated if the NTA were not present.
</para>
<para>
If the specified domain already has an NTA, its duration
will be updated to the new value. Setting
<option>duration</option> to zero will delete the NTA.
All of these options can be shortened, i.e., to
<option>-l</option>, <option>-r</option>, <option>-d</option>,
and <option>-f</option>.
</para>
</listitem>
</varlistentry>
......
......@@ -51,7 +51,7 @@ linecount=`grep "\./RSAMD5/.* ; managed" ns2/named.secroots | wc -l`
linecount=`grep "dlv.isc.org/RSAMD5/.* ; managed" ns2/named.secroots | wc -l`
[ "$linecount" -eq 2 ] || ret=1
linecount=`cat ns2/named.secroots | wc -l`
[ "$linecount" -eq 13 ] || ret=1
[ "$linecount" -eq 28 ] || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
......
......@@ -65,6 +65,10 @@ ns.insecure A 10.53.0.3
bogus NS ns.bogus
ns.bogus A 10.53.0.3
; A subdomain with a corrupt DS
badds NS ns.badds
ns.badds A 10.53.0.3
; A dynamic secure subdomain
dynamic NS dynamic
dynamic A 10.53.0.3
......
......@@ -26,11 +26,10 @@ zonefile=example.db
( cd ../ns3 && $SHELL sign.sh )
for subdomain in secure bogus dynamic keyless nsec3 optout nsec3-unknown \
optout-unknown multiple rsasha256 rsasha512 kskonly update-nsec3 \
auto-nsec auto-nsec3 secure.below-cname ttlpatch split-dnssec \
split-smart expired expiring upper lower
for subdomain in secure badds bogus dynamic keyless nsec3 optout \
nsec3-unknown optout-unknown multiple rsasha256 rsasha512 \
kskonly update-nsec3 auto-nsec auto-nsec3 secure.below-cname \
ttlpatch split-dnssec split-smart expired expiring upper lower
do
cp ../ns3/dsset-$subdomain.example. .
done
......
......@@ -28,5 +28,6 @@ ns A 10.53.0.3
a A 10.0.0.1
b A 10.0.0.2
c A 10.0.0.3
d A 10.0.0.4
z A 10.0.0.26
......@@ -68,6 +68,12 @@ zone "bogus.example" {
allow-update { any; };
};
zone "badds.example" {
type master;
file "badds.example.db.signed";
allow-update { any; };
};
zone "dynamic.example" {
type master;
file "dynamic.example.db.signed";
......
......@@ -26,7 +26,11 @@ ns3 A 10.53.0.3
a A 10.0.0.1
b A 10.0.0.2
c A 10.0.0.3
d A 10.0.0.4
e A 10.0.0.5
f A 10.0.0.6
g A 10.0.0.7
z A 10.0.0.26
a.a.a.a.a.a.a.a.a.a.e A 10.0.0.27
x CNAME a
......
......@@ -459,3 +459,18 @@ zonefile=siginterval.example.db
kskname=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
zskname=`$KEYGEN -q -3 -r $RANDFILE $zone`
cp $infile $zonefile
#
# A zone with a bad DS in the parent
# (sourced from bogus.example.db.in)
#
zone=badds.example.
infile=bogus.example.db.in
zonefile=badds.example.db
keyname=`$KEYGEN -q -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone`
cat $infile $keyname.key >$zonefile
$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
sed -e 's/bogus/badds/g' < dsset-bogus.example. > dsset-badds.example.
......@@ -34,6 +34,9 @@ options {
dnssec-validation yes;
dnssec-must-be-secure mustbesecure.example yes;
nta-lifetime 10s;
nta-recheck 7s;
# Note: We only reference the bind.keys file here to confirm that it
# is *not* being used. It contains the real root key, and we're
# using a local toy root zone for the tests, so it wouldn't work.
......
......@@ -26,6 +26,7 @@ cd ns1 && $SHELL sign.sh
echo "a.bogus.example. A 10.0.0.22" >>../ns3/bogus.example.db.signed
echo "b.bogus.example. A 10.0.0.23" >>../ns3/bogus.example.db.signed
echo "c.bogus.example. A 10.0.0.23" >>../ns3/bogus.example.db.signed
cd ../ns3 && cp -f siginterval1.conf siginterval.conf
cd ../ns4 && cp -f named1.conf named.conf
......
......@@ -1568,7 +1568,7 @@ keyid=`cat ns1/managed.key.id`
linecount=`grep "./RSAMD5/$keyid ; trusted" ns4/named.secroots | wc -l`
[ "$linecount" -eq 1 ] || ret=1
linecount=`cat ns4/named.secroots | wc -l`
[ "$linecount" -eq 5 ] || ret=1
[ "$linecount" -eq 10 ] || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
......@@ -1654,26 +1654,88 @@ status=`expr $status + $ret`
echo "I:checking positive and negative validation with negative trust anchors ($n)"
ret=0
#
# check correct initial behavior
#
$DIG $DIGOPTS a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null || ret=1
$DIG $DIGOPTS a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.2 > /dev/null || ret=1
$DIG $DIGOPTS badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1
$DIG $DIGOPTS a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null || ret=1
#
# add negative trust anchors
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta bogus.example 15s 2>&1 | sed 's/^/I:ns4 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta secure.example 15s 2>&1 | sed 's/^/I:ns4 /'
#
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta -f -l 15s bogus.example 2>&1 | sed 's/^/I:ns4 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta badds.example 2>&1 | sed 's/^/I:ns4 /'
lines=`$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta -d | wc -l`
[ "$lines" -eq 2 ] || ret=1
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta secure.example 2>&1 | sed 's/^/I:ns4 /'
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta fakenode.secure.example 2>&1 | sed 's/^/I:ns4 /'
lines=`$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta -d | wc -l`
[ "$lines" -eq 4 ] || ret=1
#
# check behavior with NTA's in place
$DIG $DIGOPTS a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1
$DIG $DIGOPTS a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1
echo "I: waiting for NTA expiration"
sleep 15
# check correct behavior after expiry
$DIG $DIGOPTS b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.5 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.5 > /dev/null || ret=1
$DIG $DIGOPTS b.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.6 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.6 > /dev/null || ret=1
#
$DIG $DIGOPTS a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1
$DIG $DIGOPTS badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.5 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.5 > /dev/null && ret=1
$DIG $DIGOPTS a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.6 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.6 > /dev/null && ret=1
$DIG $DIGOPTS a.fakenode.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.7 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.7 > /dev/null && ret=1
echo "I: dumping secroots"
$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 secroots | sed 's/^/I:ns4 /'
grep "bogus.example: expiry" ns4/named.secroots > /dev/null || ret=1
grep "badds.example: expiry" ns4/named.secroots > /dev/null || ret=1
grep "secure.example: expiry" ns4/named.secroots > /dev/null || ret=1
grep "fakenode.secure.example: expiry" ns4/named.secroots > /dev/null || ret=1
echo "I: waiting for NTA rechecks/expirations"
#
# secure.example and badds.example used default nta-duration
# (configured as 10s in ns4/named1.conf), but nta recheck interval
# is configured to 7s, so at t=8 the NTAs for secure.example and
# fakenode.secure.example should both be lifted, but badds.example
# should still be going.
#
sleep 8
$DIG $DIGOPTS b.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.8 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.8 > /dev/null || ret=1
$DIG $DIGOPTS b.fakenode.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.9 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.9 > /dev/null || ret=1
grep "status: NXDOMAIN" dig.out.ns4.test$n.9 > /dev/null || ret=1
$DIG $DIGOPTS badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.10 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.10 > /dev/null && ret=1
#
# bogus.example was set to expire in 15s, so at t=11
# it should still be NTA'd, but badds.example used the default
# lifetime of 10s, so it should revert to SERVFAIL now.
#
sleep 3
$DIG $DIGOPTS b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.11 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.11 > /dev/null && ret=1
$DIG $DIGOPTS a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.12 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.12 > /dev/null || ret=1
$DIG $DIGOPTS c.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.13 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.13 > /dev/null || ret=1
#
# at t=16, all the NTAs should have expired.
#
sleep 5
# check correct behavior after bogus.example expiry
$DIG $DIGOPTS d.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.14 || ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.14 > /dev/null || ret=1
$DIG $DIGOPTS c.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.15 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.15 > /dev/null || ret=1
# check nta table has been cleaned up now
lines=`$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 nta -d | wc -l`
[ "$lines" -eq 0 ] || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
......
......@@ -4939,6 +4939,8 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> max-refresh-time <replaceable>number</replaceable> ; </optional>
<optional> min-retry-time <replaceable>number</replaceable> ; </optional>
<optional> max-retry-time <replaceable>number</replaceable> ; </optional>
<optional> nta-lifetime <replaceable>duration</replaceable> ; </optional>
<optional> nta-recheck <replaceable>duration</replaceable> ; </optional>
<optional> port <replaceable>ip_port</replaceable>; </optional>
<optional> dscp <replaceable>ip_dscp</replaceable></optional> ;
<optional> additional-from-auth <replaceable>yes_or_no</replaceable> ; </optional>
......@@ -5746,6 +5748,69 @@ options {
</listitem>
</varlistentry>
<varlistentry>
<term><command>nta-lifetime</command></term>
<listitem>
<para>
Species the default lifetime, in seconds,
that will be used for negative trust anchors added
via <command>rndc nta</command>.
</para>
<para>
A negative trust anchor selectively disables
DNSSEC validation for zones that known to be
failing because of misconfiguration rather than
an attack. When data to be validated is
at or below an active NTA (and above any other
configured trust anchors), <command>named</command> will
abort the DNSSEC validation process and treat the data as
insecure rather than bogus. This continues until the
NTA's lifetime is elapsed, or until the server is
restarted (NTA's do not persist across restarts).
</para>
<para>
For convienience, TTL-style time unit suffixes can be
used to specify the NTA lifetime in seconds, minutes
or hours. <option>nta-lifetime</option> defaults to
one hour. It cannot exceed one day.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>nta-recheck</command></term>
<listitem>
<para>
Species how often to check whether negative
trust anchors added via <command>rndc nta</command>
are still necessary.
</para>
<para>
A negative trust anchor is normally used when a
domain has stopped validating due to operator error;
it temporarily disables DNSSEC validation for that
domain. In the interest of ensuring that DNSSEC
validation is turned back on as soon as possible,
<command>named</command> will periodically send a
query to the domain, ignoring negative trust anchors,
to find out whether it can now be validated. If so,
the negative trust anchor is allowed to expire early.