Subject: [DNSOP] How to respond to ANY and RRSIG queries when you don't want to

From: Tony Finch <[email-masked]>
Date: Mon, 16 Mar 2015 11:25:33 +0000

This note is a consolidation of several messages to the IETF DNSOP
working group last week.

The principal motivation for not answering ANY queries is to allow for
simplified implementations which do not need to enumerate all the data
at a particular QNAME. This note also covers RRSIG queries, because
they need essentially the same enumeration mechanism as ANY queries;
the difference between an ANY and an RRSIG response is the non-RRSIG
records are omitted from the latter.

The aim of this suggestion is to provide answers that will satisfy the
client without harming interoperability, although you do lose a
debugging tool. Error responses (such as NOTIMP or REFUSED) make
clients retry at other servers, which is undesirable. NOERROR / NODATA
responses are cached in a way that causes queries for other RRtypes to
get erroneous NODATA responses.

1. When the server is authoritative for the QNAME's zone.

Respond as if the QTYPE had been CNAME.

That is, provide a CNAME answer if the QNAME is a CNAME, or provide a
NOERROR / NODATA response if other types are present at the QNAME.
This applies to wildcard matching too.

If the response would be NOERROR / NODATA and the zone is not signed,
synthesize a NULL RR and use that as the answer.

If the QTYPE was RRSIG, drop non-RRSIG records from the answer.

2. When the server is answering from cache.

If there is a cache entry for the QNAME, respond as in point 1.

Otherwise, if RD=0, respond in the standard manner (with the best
available referral).

Otherwise, if RD=1, make a query upstream with QTYPE=CNAME, then
respond as in point 1.

Comment.

This is simpler than I expected it to be. I started doing a case
analysis -- zone is unsigned or signed with NSEC or NSEC3, QNAME is a
CNAME or isn't, recursion or not, etc. -- but the way to handle each
case turned out to be very similar. The key insight came from saying,
respond with a CNAME answer if there is one, or respond with NOERROR /
NODATA - which is exactly the response you would give to a CNAME
query. This leads to the suggestion of turning ANY queries into CNAME
queries when recursing.

Tony.
-- 
f.anthony.n.finch  <[email-masked]>  http://dotat.at/
Northwest Southeast Iceland: Southwesterly 5 to 7, occasionally gale 8,
becoming variable, mainly northeasterly 4. Very rough or high, becoming rough
later. Occasional rain. Good, occasionally poor.

---

From: Robert Edmonds <[email-masked]>
Date: Mon, 16 Mar 2015 14:32:00 -0400

> synthesize a NULL RR and use that as the answer.

It seems a little bit off to re-use the NULL RRtype, which has been
reserved for experimental use, for this.  There are at least some
(marginal) uses of the type, e.g., the popular DNS tunneling tool
"iodine" [0] will make use of NULL RRs.  Which is perfectly OK, it's
marked "experimental", after all.  This fact might be used by security
monitors as a detection signature (e.g., [1] explicitly notes the use of
NULL RRs by iodine), just like qtype=*.  (Just noting this possibility,
not passing judgment on whether such signatures are a good or bad idea.)

"NULL" is hard to grep for in the commit messages, source code, and
documentation of C/C++ based DNS software implementations, due to the
obvious overlap with the C preprocessor macro of the same name, and the
use of the word "null" in other DNS terminology (e.g., "the null label
of the root").

I also note BIND appears to accept NULL RRs in zone files, even though
RFC 1035 says "NULL RRs are not allowed in master files."  Knot 1.4
rejects NULL RRs in zones.  (I tried searching for a later RFC that
might mention NULL RRs but ran into the aforementioned terminology
conflict.)

Anyway, I recommend that the NULL RRtype be completely preserved for
experimental uses and that a new RRtype be specifically allocated for
the exclusive purpose of these synthetic responses, and that its
definition require that it MUST NOT appear in zone files.  Perhaps
"GNDN" would be a good mnemonic, for the obvious [2] reference.

[0] http://code.kryo.se/iodine/

[1] http://www.sans.org/reading-room/whitepapers/dns/detecting-dns-tunneling-34152

[2] http://en.wikipedia.org/wiki/Jefferies_tube

-- 
Robert Edmonds

---

From: Andras Salamon <[email-masked]>
Date: Tue, 17 Mar 2015 12:32:08 +0000

On Mon, Mar 16, 2015 at 11:25:33AM +0000, Tony Finch wrote:
>query.

This is elegant, except for the base case of what record type to
synthesize in the NOERROR/NODATA case.

Robert Edmonds pointed out that using NULL is not a perfect solution
here.  On the other hand, I am not convinced that creating a completely
new record type is better than NULL for achieving interoperability
with broken implementations.  These solutions are both likely to lead
to problems.

Because NOERROR/NODATA are cached, these should be avoided.  But are
problems with NULL or a new data type really a good tradeoff against
the undesirable behaviour of clients retrying at other servers?

-- Andras Salamon                   [email-masked]

---

From: Tony Finch <[email-masked]>
Date: Tue, 17 Mar 2015 13:38:06 +0000

> with broken implementations.  These solutions are both likely to lead

What problems do you anticipate? It seems benign in my limited testing so
far (though I have only tried two high-quality resolver implementations).

Tony.
-- 
f.anthony.n.finch  <[email-masked]>  http://dotat.at/
Southeast Iceland: Variable 3 at first in northwest, otherwise cyclonic 4 or
5, increasing 5 to 7, perhaps gale 8 later. Moderate or rough. Occasional rain
or snow. Moderate, occasionally very poor later.