Blog What We Do Support Community
Developers
Login Sign up

RFC8482 - Saying goodbye to ANY

by Marek Majkowski.

Ladies and gentlemen, I would like you to welcome the new shiny RFC8482, which effectively deprecates the DNS ANY query type. DNS ANY was a "meta-query" - think of it as a similar thing to the common A, AAAA, MX or SRV query types, but unlike these it wasn't a real query type - it was special. Unlike the standard query types, ANY didn't age well. It was hard to implement on modern DNS servers, the semantics were poorly understood by the community and it unnecessarily exposed the DNS protocol to abuse. RFC8482 allows us to clean it up - it's a good thing.

Screenshot-from-2019-03-15-14-22-51

But let's rewind a bit.

Historical context

It all started in 2015, when we were looking at the code of our authoritative DNS server. The code flow was generally fine, but it was all peppered with naughty statements like this:

if qtype == "ANY" {
    // special case
}

This special code was ugly and error prone. This got us thinking: do we really need it? "ANY" is not a popular query type - no legitimate software uses it (with the notable exception of qmail).

11235945713_5bf22a701d_z

Image by Christopher MichelCC BY 2.0

ANY is hard for modern DNS servers

"ANY" queries, also called "* queries" in old RFCs, are supposed to return "all records" (citing RFC1035). There are two problems with this notion.

First, it assumes the server is able to retrieve "all records". In our implementation - we can't. Our DNS server, like many modern implementations, doesn't have a single "zone" file listing all properties of a DNS zone. This design allows us to respond fast and with information always up to date, but it makes it incredibly hard to retrieve "all records". Correct handling of "ANY" adds unreasonable code complexity for an obscure, rarely used query type.

Second, many of the DNS responses are generated on-demand. To mention just two use cases:

Storing data in modern databases and dynamically generating responses poses a fundamental problem to ANY.

ANY is hard for clients

Around the same time a catastrophe happened - Firefox started shipping with DNS code issuing "ANY" types. The intention was, as usual, benign. Firefox developers wanted to get the TTL value for A and AAAA queries.

To cite a DNS guru Andrew Sullivan:

In general, ANY is useful for troubleshooting but should never be used
for regular operation. Its output is unpredictable given the effects
of caches. It can return enormous result sets.

In user code you can't rely on anything sane to come out of an "ANY" query. While an "ANY" query has somewhat defined semantics on the DNS authoritative side, it's undefined on the DNS resolver side. Such a query can confuse the resolver:

  • Should it forward the "ANY" query to authoritative?
  • Should it respond with any record that is already in cache?
  • Should it do some a mixture of the above behaviors?
  • Should it cache the result of "ANY" query and re-use the data for other queries?

Different implementations do different things. "ANY" does not mean "ALL", which is the main source of confusion. To our joy, Firefox quickly backpedaled on the change and stopped issuing ANY queries.

ANY is hard for network operators

Screenshot-from-2019-03-15-14-44-58

A typical 50Gbps DNS amplification targeting one of our customers. The attack lasted about 4 hours.

Furthermore, since the "ANY" query can generate a large response, they were often used for DNS reflection attacks. Authoritative providers receive a spoofed ANY query and send the large answer to a target, potentially causing DoS damage. We have blogged about that many times:

The DoS problem with ANY is really old. Here is a discussion about a patch to bind tweaking ANY from 2013.

There is also a second angle to the ANY DoS problem. Some reports suggested that performant DNS servers (authoritative or resolvers) can fill their outbound network capacity with a large number of ANY responses.

The recommendation is simple - network operators must use "response rate limiting" when answering large DNS queries, otherwise they pose a DoS threat. The "ANY" query type just happens to often give such large responses, while providing little value to legitimate users.

Killing ANY

In 2015 frustrated with the experience we announced we would like to stop giving responses to "ANY" queries and wrote a (controversial at a time) blog post:

A year later we followed up explaining possible solutions:

And here we come today! With RFC8482 we have an RFC proposed standard clarifying that controversial query.

Screenshot-from-2019-03-15-13-19-21

ANY queries are a background noise. Under normal circumstances, we see a very small volume of ANY queries.

The future for our users

What precisely can be done about "ANY" queries? RFC8482 specifies that:

A DNS responder that receives an ANY query MAY decline to provide a
conventional ANY response or MAY instead send a response with a
single RRset (or a larger subset of available RRsets) in the answer
section.

This clearly defines the corner case - from now on the authoritative server may respond with, well, any query type to an "ANY" query. Sometimes simple stuff like this matters most.

This opens a gate for implementers - we can prepare a simple answer to these queries. As an implementer you may stick "A", or "AAAA" or anything else in the response if you wish. Furthermore, the spec recommends returning a special (and rarely used thus far) HINFO type. This is in fact what we do:

$ dig ANY cloudflare.com @ns3.cloudflare.com. 
;; ANSWER SECTION:
cloudflare.com.		3789	IN	HINFO	"ANY obsoleted" "See draft-ietf-dnsop-refuse-any"

Oh, we need to update the message to mention the fresh RFC number! NS1 agrees with our implementation:

$ dig ANY nsone.net @dns1.p01.nsone.net.
;; ANSWER SECTION:
nsone.net.		3600	IN	HINFO	"ANY not supported." "See draft-ietf-dnsop-refuse-any"

Our ultimate hero is wikipedia.org, which does exactly what the RFC recommends:

$ dig ANY wikipedia.org @ns0.wikimedia.org.
;; ANSWER SECTION:
wikipedia.org.		3600	IN	HINFO	"RFC8482" ""

On our resolver service we stop ANY queries with NOTIMP code. This makes us more confident the resolver isn't used to perform DNS reflections:

$ dig ANY cloudflare.com @1.1.1.1
;; ->>HEADER<<- opcode: QUERY, status: NOTIMP, id: 14151

The future for developers

On the client side, just don't use ANY DNS queries. On the DNS server side - you are allowed to rip out all the gory QTYPE::ANY handling code, and replace it with a top level HINFO message or first RRset found. Enjoy cleaning your codebase!

Summary

It took the DNS community some time to agree on the specifics, but here we are at the end. RFC8482 cleans up the last remaining DNS meta-qtype, and allows for simpler DNS authoritative and DNS resolver implementations. It finally clearly defines the semantics of ANY queries going through resolvers and reduces the DoS risk for the whole Internet.

Not all the effort must go to new shiny protocols and developments, sometimes, cleaning the bitrot is as important. Similar cleanups are being done in other areas. Keep up the good work!

We would like to thank the co-authors of RFC8482, and the community scrutiny and feedback. For us, RFC8482 is definitely a good thing, and allowed us to simplify our codebase and make the Internet safer.

Mission accomplished! One step at a time we can help make the Internet a better place.

comments powered by Disqus