diff --git a/CHANGES b/CHANGES index 01ec0b7b26..a0ceea14bb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +5369. [func] Add the ability to specify whether or not to wait + for nameserver domain names to be looked up, with + a new RPZ modifying directive 'nsdname-wait-recurse'. + [GL #1138] + 5368. [bug] Named failed to restart if 'rndc addzone' names contained special characters (e.g. '/'). [GL #1655] diff --git a/bin/named/server.c b/bin/named/server.c index 781d9e013d..2836429de3 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -2557,6 +2557,13 @@ configure_rpz(dns_view_t *view, const cfg_obj_t **maps, zones->p.qname_wait_recurse = false; } + sub_obj = cfg_tuple_get(rpz_obj, "nsdname-wait-recurse"); + if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj)) { + zones->p.nsdname_wait_recurse = true; + } else { + zones->p.nsdname_wait_recurse = false; + } + sub_obj = cfg_tuple_get(rpz_obj, "nsip-wait-recurse"); if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj)) { zones->p.nsip_wait_recurse = true; diff --git a/bin/tests/system/rpzrecurse/clean.sh b/bin/tests/system/rpzrecurse/clean.sh index ffd9dfd50a..9117a241eb 100644 --- a/bin/tests/system/rpzrecurse/clean.sh +++ b/bin/tests/system/rpzrecurse/clean.sh @@ -22,7 +22,7 @@ rm -f ns2/*.queries rm -f ns2/named.[0-9]*.conf rm -f ns2/named.conf.header -rm -f ns3/named2.conf +rm -f ns3/named.conf rm -f dnsrps*.conf dnsrpzd* rm -f ns*/session.key diff --git a/bin/tests/system/rpzrecurse/ns3/named3.conf.in b/bin/tests/system/rpzrecurse/ns3/named3.conf.in new file mode 100644 index 0000000000..73470fafbd --- /dev/null +++ b/bin/tests/system/rpzrecurse/ns3/named3.conf.in @@ -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. + */ + +include "../../common/rndc.key"; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + recursion yes; + dnssec-validation yes; + response-policy { zone "policy"; } nsdname-wait-recurse no + nsdname-enable yes; + + include "../dnsrps.conf"; +}; + +zone "policy" { type master; file "policy.db"; }; + +zone "example.tld" { type master; file "example.db"; }; + +zone "." { type master; file "root.db"; }; diff --git a/bin/tests/system/rpzrecurse/setup.sh b/bin/tests/system/rpzrecurse/setup.sh index 36786a72de..9ab709fc9d 100644 --- a/bin/tests/system/rpzrecurse/setup.sh +++ b/bin/tests/system/rpzrecurse/setup.sh @@ -42,7 +42,6 @@ copy_setports ns2/named.conf.header.in ns2/named.conf.header copy_setports ns2/named.default.conf ns2/named.conf copy_setports ns3/named1.conf.in ns3/named.conf -copy_setports ns3/named2.conf.in ns3/named2.conf copy_setports ns4/named.conf.in ns4/named.conf diff --git a/bin/tests/system/rpzrecurse/tests.sh b/bin/tests/system/rpzrecurse/tests.sh index 3679d35c8f..7b1f206389 100644 --- a/bin/tests/system/rpzrecurse/tests.sh +++ b/bin/tests/system/rpzrecurse/tests.sh @@ -474,15 +474,17 @@ for mode in native dnsrps; do status=1 } - # Check for invalid prefix length error - t=`expr $t + 1` - echo_i "testing for invalid prefix length error (${t})" - add_test_marker 10.53.0.2 - run_server invalidprefixlength - grep "invalid rpz IP address \"1000.4.0.53.10.rpz-client-ip.invalidprefixlength\"; invalid prefix length of 1000$" ns2/named.run > /dev/null || { - echo_ic "failed: expected that invalid prefix length error would be logged" - status=1 - } + if [ "$mode" = "native" ]; then + # Check for invalid prefix length error + t=`expr $t + 1` + echo_i "testing for invalid prefix length error (${t})" + add_test_marker 10.53.0.2 + run_server invalidprefixlength + grep "invalid rpz IP address \"1000.4.0.53.10.rpz-client-ip.invalidprefixlength\"; invalid prefix length of 1000$" ns2/named.run > /dev/null || { + echo_ic "failed: expected that invalid prefix length error would be logged" + status=1 + } + fi t=`expr $t + 1` echo_i "checking 'nsip-wait-recurse no' is faster than 'nsip-wait-recurse yes' ($t)" @@ -493,10 +495,10 @@ for mode in native dnsrps; do $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a > dig.out.yes.$t t2=`$PERL -e 'print time()."\n";'` p1=`expr $t2 - $t1` - echo_i "elasped time $p1 seconds" + echo_i "elapsed time $p1 seconds" $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush - cp -f ns3/named2.conf ns3/named.conf + copy_setports ns3/named2.conf.in ns3/named.conf $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload > /dev/null echo_i "timing 'nsip-wait-recurse no'" @@ -504,12 +506,44 @@ for mode in native dnsrps; do $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a > dig.out.no.$t t4=`$PERL -e 'print time()."\n";'` p2=`expr $t4 - $t3` - echo_i "elasped time $p2 seconds" + echo_i "elapsed time $p2 seconds" if test $p1 -le $p2; then ret=1; fi if test $ret != 0; then echo_i "failed"; fi status=`expr $status + $ret` + $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush + # restore original named.conf + copy_setports ns3/named1.conf.in ns3/named.conf + $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload > /dev/null + + t=`expr $t + 1` + echo_i "checking 'nsdname-wait-recurse no' is faster than 'nsdname-wait-recurse yes' ($t)" + add_test_marker 10.53.0.2 + echo_i "timing 'nsdname-wait-recurse yes' (default)" + ret=0 + t1=`$PERL -e 'print time()."\n";'` + $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a > dig.out.yes.$t + t2=`$PERL -e 'print time()."\n";'` + p1=`expr $t2 - $t1` + echo_i "elapsed time $p1 seconds" + + $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush + copy_setports ns3/named3.conf.in ns3/named.conf + $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload > /dev/null + + echo_i "timing 'nsdname-wait-recurse no'" + t3=`$PERL -e 'print time()."\n";'` + $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a > dig.out.no.$t + t4=`$PERL -e 'print time()."\n";'` + p2=`expr $t4 - $t3` + echo_i "elapsed time $p2 seconds" + + if test $p1 -le $p2; then ret=1; fi + if test $ret != 0; then echo_i "failed"; fi + status=`expr $status + $ret` + + [ $status -ne 0 ] && pf=fail || pf=pass case $mode in native) diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 6fc046e950..e291dc88d0 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -9843,18 +9843,36 @@ deny-answer-aliases { "example.net"; }; NSDNAME triggers match names of authoritative servers - for the query name, a parent of the query name, a CNAME for - query name, or a parent of a CNAME. - They are encoded as subdomains of - rpz-nsdname relativized - to the RPZ origin name. - NSIP triggers match IP addresses in A and - AAAA RRsets for domains that can be checked against NSDNAME - policy records. - The nsdname-enable phrase turns NSDNAME + for the query name, a parent of the query name, a CNAME + for query name, or a parent of a CNAME. They are + encoded as subdomains of rpz-nsdname + relativized to the RPZ origin name. NSIP triggers match + IP addresses in A and AAAA RRsets for domains that can + be checked against NSDNAME policy records. The + nsdname-enable phrase turns NSDNAME triggers off or on for a single policy zone or all zones. + + If authoritative nameservers for the query name are not + yet known, named will recursively + look up the authoritative servers for the query name + before applying an RPZ-NSDNAME rule. + This can cause a processing delay. To speed up + processing at the cost of precision, the + nsdname-wait-recurse option + can be used: when set to no, + RPZ-NSDNAME rules will only be applied when authoritative + servers for the query name have already been looked up and + cached. If authoritative servers for the query name + are not in the cache, then the RPZ-NSDNAME rule will be + ignored, but the authoritative servers for the query name + will be looked up in the background, and the rule will be + applied to subsequent queries. The default is + yes, meaning RPZ-NSDNAME + rules should always be applied even if authoritative + servers for the query name need to be looked up first. + diff --git a/doc/arm/notes-9.17.0.xml b/doc/arm/notes-9.17.0.xml index 7f0227a95b..5234ccec7e 100644 --- a/doc/arm/notes-9.17.0.xml +++ b/doc/arm/notes-9.17.0.xml @@ -49,6 +49,19 @@ 100%. [GL #1515] + + + A new RPZ option nsdname-wait-recurse + controls whether RPZ-NSDNAME rules should always be applied + even if the names of authoritative name servers for the query + name need to be looked up recurively first. The default is + yes. Setting it to + no speeds up initial responses by skipping + RPZ-NSDNAME rules when name server domain names are not yet + in the cache. The names will be looked up in the background and + the rule will be applied for subsequent queries. [GL #1138] + + diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h index 4e834d7fe4..966aaee0ed 100644 --- a/lib/dns/include/dns/rpz.h +++ b/lib/dns/include/dns/rpz.h @@ -203,6 +203,7 @@ struct dns_rpz_popt { bool break_dnssec; bool qname_wait_recurse; bool nsip_wait_recurse; + bool nsdname_wait_recurse; unsigned int min_ns_labels; dns_rpz_num_t num_zones; }; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index d3b0d6a41f..55e16c997b 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1736,6 +1736,7 @@ static cfg_tuplefielddef_t rpz_fields[] = { { "min-update-interval", &cfg_type_duration, 0 }, { "min-ns-dots", &cfg_type_uint32, 0 }, { "nsip-wait-recurse", &cfg_type_boolean, 0 }, + { "nsdname-wait-recurse", &cfg_type_boolean, 0 }, { "qname-wait-recurse", &cfg_type_boolean, 0 }, { "recursive-only", &cfg_type_boolean, 0 }, { "nsip-enable", &cfg_type_boolean, 0 }, diff --git a/lib/ns/query.c b/lib/ns/query.c index 482b3f3b01..a503109db0 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -2826,7 +2826,10 @@ rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, */ if (rpz_type == DNS_RPZ_TYPE_IP) { result = DNS_R_NXRRSET; - } else if (!client->view->rpzs->p.nsip_wait_recurse) { + } else if (!client->view->rpzs->p.nsip_wait_recurse || + (!client->view->rpzs->p.nsdname_wait_recurse && + rpz_type == DNS_RPZ_TYPE_NSDNAME)) + { query_rpzfetch(client, name, type); result = DNS_R_NXRRSET; } else {