Use NS rather than A records for qname-minimization relaxed

Remove all references to DNS_FETCHOPT_QMIN_USE_A and adjust
the expected tests results in the qmin system test.

(cherry picked from commit dd00b3c50b)
This commit is contained in:
Mark Andrews 2023-05-23 16:59:40 +10:00 committed by Ondřej Surý
parent 0eb73bb6a3
commit b3a97da7a7
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41
5 changed files with 62 additions and 92 deletions

View file

@ -154,20 +154,20 @@ grep "icky.icky.icky.ptang.zoop.boing.good. 1 IN A 192.0.2.1" dig.out.test$n > /
sleep 1
sort ans2/query.log > ans2/query.log.sorted
cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
ADDR _.boing.good.
ADDR _.zoop.boing.good.
ADDR a.bit.longer.ns.name.good.
ADDR a.bit.longer.ns.name.good.
ADDR ns2.good.
ADDR ns3.good.
ADDR ns3.good.
NS boing.good.
NS zoop.boing.good.
__EOF
cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
ADDR _.ptang.zoop.boing.good.
ADDR _.icky.ptang.zoop.boing.good.
NS ptang.zoop.boing.good.
NS icky.ptang.zoop.boing.good.
__EOF
cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
ADDR _.icky.icky.ptang.zoop.boing.good.
NS icky.icky.ptang.zoop.boing.good.
ADDR icky.icky.icky.ptang.zoop.boing.good.
__EOF
for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
@ -203,20 +203,18 @@ grep "icky.icky.icky.ptang.zoop.boing.bad. 1 IN A 192.0.2.1" dig.out.test$n > /d
sleep 1
sort ans2/query.log > ans2/query.log.sorted
cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
ADDR _.boing.bad.
ADDR _.zoop.boing.bad.
ADDR a.bit.longer.ns.name.bad.
ADDR a.bit.longer.ns.name.bad.
ADDR icky.icky.icky.ptang.zoop.boing.bad.
ADDR ns2.bad.
ADDR ns3.bad.
ADDR ns3.bad.
NS boing.bad.
__EOF
cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
ADDR _.ptang.zoop.boing.bad.
ADDR _.icky.ptang.zoop.boing.bad.
ADDR icky.icky.icky.ptang.zoop.boing.bad.
__EOF
cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
ADDR _.icky.icky.ptang.zoop.boing.bad.
ADDR icky.icky.icky.ptang.zoop.boing.bad.
__EOF
for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
@ -251,16 +249,15 @@ $DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.ugly. @10.53.0.7 > dig.out.test$n
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
grep "icky.icky.icky.ptang.zoop.boing.ugly. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
sleep 1
sort ans2/query.log > ans2/query.log.sorted
cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
ADDR _.boing.ugly.
ADDR a.bit.longer.ns.name.ugly.
ADDR a.bit.longer.ns.name.ugly.
ADDR icky.icky.icky.ptang.zoop.boing.ugly.
ADDR ns2.ugly.
ADDR ns3.ugly.
ADDR ns3.ugly.
NS boing.ugly.
__EOF
echo "ADDR icky.icky.icky.ptang.zoop.boing.ugly." | diff ans3/query.log - > /dev/null || ret=1
echo "ADDR icky.icky.icky.ptang.zoop.boing.ugly." | diff ans4/query.log - > /dev/null || ret=1
@ -270,7 +267,7 @@ status=$((status+ret))
$RNDCCMD 10.53.0.7 flush
n=$((n+1))
echo_i "information that minimization was unsuccessful for .ugly is logged ($n)"
echo_i "information that minimization was unsuccessful for .ugly is logged in relaxed mode ($n)"
ret=0
wait_for_log 5 "success resolving 'icky.icky.icky.ptang.zoop.boing.ugly/A' after disabling qname minimization" ns7/named.run > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@ -458,9 +455,9 @@ grep "a\.b\.stale\..*1.*IN.*TXT.*hooray" dig.out.test$n > /dev/null || ret=1
sleep 1
sort ans2/query.log > ans2/query.log.sorted
cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
ADDR _.b.stale.
ADDR ns.b.stale.
ADDR ns2.stale.
NS b.stale.
__EOF
test -f ans3/query.log && ret=1
sort ans4/query.log > ans4/query.log.sorted
@ -523,7 +520,7 @@ grep "a\.b\.stale\..*1.*IN.*TXT.*hooray" dig.out.test$n > /dev/null || ret=1
sleep 1
sort ans2/query.log > ans2/query.log.sorted
cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
ADDR _.b.stale.
NS b.stale.
__EOF
test -f ans3/query.log && ret=1
sort ans4/query.log > ans4/query.log.sorted

View file

@ -1399,21 +1399,22 @@ default is used.
:tags: query
:short: Controls QNAME minimization behavior in the BIND 9 resolver.
When this is set to ``strict``, BIND follows the QNAME
minimization algorithm to the letter, as specified in :rfc:`7816`.
When this is set to ``strict``, BIND follows the QNAME minimization
algorithm to the letter, as specified in :rfc:`7816`.
Setting this option to ``relaxed`` causes BIND to fall back to
normal (non-minimized) query mode when it receives either NXDOMAIN or
other unexpected responses (e.g., SERVFAIL, improper zone cut,
REFUSED) to a minimized query. A resolver can use a leading
underscore, like ``_.example.com``, in an attempt to improve
interoperability. (See :rfc:`7816` section 3.)
normal (non-minimized) query mode when it receives either NXDOMAIN
or other unexpected responses (e.g., SERVFAIL, improper zone
cut, REFUSED) to a minimized query.
In ``relaxed`` mode ``named`` makes NS queries for ``<domain>`` as it
walks down the tree.
``disabled`` disables QNAME minimization completely.
``off`` is a synonym for ``disabled``.
The current default is ``relaxed``, but it
may be changed to ``strict`` in a future release.
The current default is ``relaxed``, but it may be changed to
``strict`` in a future release.
.. namedconf:statement:: tkey-gssapi-keytab
:tags: security

View file

@ -105,31 +105,21 @@ typedef enum { dns_quotatype_zone = 0, dns_quotatype_server } dns_quotatype_t;
/* RESERVED ECS 0x00001000 */
/* RESERVED ECS 0x00002000 */
/* RESERVED TCPCLIENT 0x00004000 */
#define DNS_FETCHOPT_NOCACHED 0x00008000 /*%< Force cache update. */
#define DNS_FETCHOPT_QMINIMIZE \
0x00010000 /*%< Use qname \
* minimization. */
#define DNS_FETCHOPT_NOFOLLOW \
0x00020000 /*%< Don't follow \
* delegations */
#define DNS_FETCHOPT_QMIN_STRICT \
0x00040000 /*%< Do not work around \
* servers that return \
* errors on non-empty \
* terminals. */
#define DNS_FETCHOPT_QMIN_USE_A \
0x00080000 /*%< Use A type queries \
* instead of NS when \
* doing minimization */
#define DNS_FETCHOPT_QMIN_SKIP_IP6A \
0x00100000 /*%< Skip some labels \
* when doing qname \
* minimization on \
#define DNS_FETCHOPT_NOCACHED 0x00008000 /*%< Force cache update. */
#define DNS_FETCHOPT_QMINIMIZE 0x00010000 /*%< Use qname minimization. */
#define DNS_FETCHOPT_NOFOLLOW \
0x00020000 /*%< Don't retrieve the NS RRset from the child zone when a \
* delegation is returned in response to a NS query. */
#define DNS_FETCHOPT_QMIN_STRICT \
0x00040000 /*%< Do not work around servers that return errors on \
* non-empty terminals. */
#define DNS_FETCHOPT_QMIN_SKIP_IP6A \
0x00080000 /*%< Skip some labels when doing qname minimization on \
* ip6.arpa. */
#define DNS_FETCHOPT_NOFORWARD \
0x00200000 /*%< Do not use forwarders \
* if possible. */
#define DNS_FETCHOPT_NOFORWARD \
0x00100000 /*%< Do not use forwarders if possible. */
/* UNUSED 0x00200000 */
/* Reserved in use by adb.c 0x00400000 */
#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000
#define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000

View file

@ -649,11 +649,6 @@ static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 };
static const dns_name_t ip6_arpa = DNS_NAME_INITABSOLUTE(ip6_arpa_data,
ip6_arpa_offsets);
static unsigned char underscore_data[] = "\001_";
static unsigned char underscore_offsets[] = { 0 };
static const dns_name_t underscore_name =
DNS_NAME_INITNONABSOLUTE(underscore_data, underscore_offsets);
static void
destroy(dns_resolver_t *res);
static isc_result_t
@ -4225,11 +4220,14 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
}
/*
* In "_ A" mode we're asking for _.domain -
* resolver by default will follow delegations
* then, we don't want that.
* Turn on NOFOLLOW in relaxed mode so that QNAME minimisation
* doesn't cause additional queries to resolve the target of the
* QNAME minimisation request when a referral is returned. This
* will also reduce the impact of mis-matched NS RRsets where
* the child's NS RRset is garbage. If a delegation is
* discovered DNS_R_DELEGATION will be returned to resume_qmin.
*/
if ((options & DNS_FETCHOPT_QMIN_USE_A) != 0) {
if ((options & DNS_FETCHOPT_QMIN_STRICT) == 0) {
options |= DNS_FETCHOPT_NOFOLLOW;
}
fctx_addref(fctx);
@ -4315,22 +4313,15 @@ resume_qmin(isc_task_t *task, isc_event_t *event) {
}
UNLOCK(&res->buckets[bucketnum].lock);
if (result == ISC_R_CANCELED) {
switch (result) {
case ISC_R_SHUTTINGDOWN:
case ISC_R_CANCELED:
goto cleanup;
}
/*
* If we're doing "_ A"-style minimization we can get
* NX answer to minimized query - we need to continue then.
*
* Otherwise - either disable minimization if we're
* in relaxed mode or fail if we're in strict mode.
*/
if ((NXDOMAIN_RESULT(result) &&
(fctx->options & DNS_FETCHOPT_QMIN_USE_A) == 0) ||
result == DNS_R_FORMERR || result == DNS_R_REMOTEFORMERR ||
result == ISC_R_FAILURE)
{
case DNS_R_NXDOMAIN:
case DNS_R_NCACHENXDOMAIN:
case DNS_R_FORMERR:
case DNS_R_REMOTEFORMERR:
case ISC_R_FAILURE:
if ((fctx->options & DNS_FETCHOPT_QMIN_STRICT) == 0) {
fctx->qmin_labels = DNS_MAX_LABELS + 1;
/*
@ -4342,6 +4333,14 @@ resume_qmin(isc_task_t *task, isc_event_t *event) {
} else {
goto cleanup;
}
break;
default:
/*
* When DNS_FETCHOPT_NOFOLLOW is set and a delegation
* was discovered, DNS_R_DELEGATION is returned and is
* processed here.
*/
break;
}
if (dns_rdataset_isassociated(&fctx->nameservers)) {
@ -8017,7 +8016,8 @@ resquery_response(isc_result_t eresult, isc_region_t *region, void *arg) {
case DNS_R_CHASEDSSERVERS:
break;
case DNS_R_DELEGATION:
/* With NOFOLLOW we want to pass the result code
/*
* With NOFOLLOW we want to pass the result code.
*/
if ((fctx->options & DNS_FETCHOPT_NOFOLLOW) == 0) {
result = ISC_R_SUCCESS;
@ -10802,24 +10802,8 @@ fctx_minimize_qname(fetchctx_t *fctx) {
dns_fixedname_t fname;
dns_name_t *name = dns_fixedname_initname(&fname);
dns_name_split(fctx->name, fctx->qmin_labels, NULL, name);
if ((fctx->options & DNS_FETCHOPT_QMIN_USE_A) != 0) {
isc_buffer_t dbuf;
dns_fixedname_t tmpname;
dns_name_t *tname = dns_fixedname_initname(&tmpname);
char ndata[DNS_NAME_MAXWIRE];
isc_buffer_init(&dbuf, ndata, DNS_NAME_MAXWIRE);
dns_fixedname_init(&tmpname);
result = dns_name_concatenate(&underscore_name, name,
tname, &dbuf);
if (result == ISC_R_SUCCESS) {
dns_name_copy(tname, fctx->qminname);
}
fctx->qmintype = dns_rdatatype_a;
} else {
dns_name_copy(name, fctx->qminname);
fctx->qmintype = dns_rdatatype_ns;
}
dns_name_copy(name, fctx->qminname);
fctx->qmintype = dns_rdatatype_ns;
fctx->minimized = true;
} else {
/* Minimization is done, we'll ask for whole qname */

View file

@ -12389,8 +12389,6 @@ ns_query_start(ns_client_t *client, isc_nmhandle_t *handle) {
DNS_FETCHOPT_QMIN_SKIP_IP6A;
if (client->view->qmin_strict) {
client->query.fetchoptions |= DNS_FETCHOPT_QMIN_STRICT;
} else {
client->query.fetchoptions |= DNS_FETCHOPT_QMIN_USE_A;
}
}