Subject: DNS: Order of CNAME and A in Authoritative Reply.

From: Ralph Corderoy <[email-masked]>
Date: Tue, 11 Aug 2015 15:09:09 +0100

Hi,

If a non-recursive DNS query for an A RR is sent to the authoritative
server for both the queried CNAME and the A RR that's its value, it does
not seem to be clearly stated in the RFCs that the CNAME answer shall
precede the A answer in the reply.

BIND/named seems to have done the obvious from early on, appending the
CNAME to the reply, and then appending the A.  Clients have come to
depend on this behaviour, assuming on seeing the CNAME that they can
switch horses to the CNAME's value and continue processing the packet
from that point.  DNS servers that don't follow this unwritten
convention thus break some of the many and varied clients that already
exist.

How do we get the desired behaviour clarified so implementers of servers
and clients have a reference when trying to resolve their disagreement?
IMO, the CNAME should precede the A, but that still isn't precise
enough.  Some are asking if it's sufficient that all CNAME precede all
A.

Here's some background.

http://tools.ietf.org/html/rfc1034#section-4.3.1 says

    If recursive service is requested and available, the recursive
    response to a query will be one of the following:

       - The answer to the query, possibly preface by one or more CNAME
         RRs that specify aliases encountered on the way to an answer.

but this is a non-recursive query.

http://tools.ietf.org/html/rfc1034#section-4.3.2 says

                If the data at the node is a CNAME, and QTYPE doesn't
                match CNAME, copy the CNAME RR into the answer section
                of the response, change QNAME to the canonical name in
                the CNAME RR, and go back to step 1.

but copying doesn't state an order, strictly, and 4.3.2 starts by saying

    The actual algorithm used by the name server will depend on the
    local OS and data structures used to store RRs.

so someone arguing otherwise can say other algorithms are valid.

I've been talking with Robert Elz, co-author of RFC 2181, Clarifications
to the DNS Specification, July 1997.  He briefly shared a room with
Kevin Dunlap when the latter was working on an early BIND at UCB.  His
opinion is the order isn't stated, and that no one considered it
relevant.  Then client implementations came to depend on BIND's
ordering, as it led to simpler code.  I agree.

An ad hoc survey of clients...

    4.3BSD's named built the reply in the obvious (CNAME, A) order, and
    its client expected the same.

    glibc and dietlibc both expect (CNAME, A).

    uclibc stops on seeing the CNAME, sending another request!  But it
    means it happens to `work' with (A, CNAME).

    Finally Go came along in 2008, probably influenced by Plan 9's
    implementation, though I haven't checked that.  It alters what it
    wants on seeing the CNAME, and restarts parsing the whole packet.

So an (A foo?) query greeted with an (A bar=1, CNAME foo=bar, A bar=2)
reply would have 4.3BSD, glibc, and dietlibc think foo was 2, uclibc
would see 1 and 2 in the next reply, and Go sees 1 and 2 now.

This issue arose with a server that was replying (CNAME foo=bar, A
bar=1), but randomising the order for `round robin'.  This meant `ping
foo' failed to look up the host 50% of the time.

It seems clear to me that the decades of DNS clients, many of which are
still in service, but will never be altered, depend on (CNAME, A).
Better rules to new DNS-server writers are needed, unless someone can
point out what I've missed.  There are still unanswered questions, e.g.
is all CNAME before A sufficient.  I'd expect the answer should be
whatever that early BIND generated is now what's demanded, i.e. no, it
must be (CNAME foo=bar1, A bar=1, CNAME xyzzy=bar2, A bar2=2).

I'm new to this list, and how these things work.  What's next?

-- 
Cheers, Ralph.
https://plus.google.com/+RalphCorderoy    LinkedIn: http://goo.gl/tBVpUF

---

From: Viktor Dukhovni <[email-masked]>
Date: Tue, 11 Aug 2015 14:35:41 +0000

> enough.  Some are asking if it's sufficient that all CNAME precede all

Which clients that are not recursive resolvers talk directly to
authoritative nameservers (not counting "nslookup", "dig", ...)?

If an order is to be specified, then it should not only order all
applicable CNAME RRs before any records that bear the final anwer,
but also order the CNAME records in a chain of CNAMEs, so that
the source CNAME precedes the target CNAME:

However, it is not clear why the order of records in a non-recursive
response needs to be constrained in any way.  Surely, recursive
resolvers can reorder the records as necessary?

-- 
	Viktor.

---

From: Ralph Corderoy <[email-masked]>
Date: Tue, 11 Aug 2015 15:56:03 +0100

Hi Viktor,

> > How do we get the desired behaviour clarified so implementers of
> > servers and clients have a reference when trying to resolve their
> > disagreement?  IMO, the CNAME should precede the A, but that still
> > isn't precise enough.  Some are asking if it's sufficient that all
> > CNAME precede all A.
>

Those, like ping, where a foo.local is provided by a local,
authoritative, nameserver.  DNS is increasing being used on a local
level, e.g. as a distributed key/value lookup.  That's one reason why
new servers are coming along and meeting old clients.

> applicable CNAME RRs before any records that bear the final anwer, but
> also order the CNAME records in a chain of CNAMEs, so that the source
> CNAME precedes the target CNAME:

I agree.  That would seem to give the simplest client implementation,
and probably matches early BIND.

> resolvers can reorder the records as necessary?

I have a lack of DNS Fu.  If the recursive resolver looking up (A?
foo.local) talked to the authoratitive server that answered (A
bar.local=1, CNAME foo.local=bar.local) then, assuming it understood
that completely answered the question, might it not simply copy the
answer back to the client without re-ordering?

Cheers, Ralph.

---

From: "Joe Abley" <[email-masked]>
Date: Tue, 11 Aug 2015 11:02:07 -0400

Hi Ralph,

> precede the A answer in the reply.

Paraphrasing with more detail, a query with RD=0, QTYPE=A and some QNAME 
is sent to an authoritative server. The corresponding owner name is a 
CNAME, with some target, and the target owner name has an A RRSet 
associated with it. The authoritative server responds with both the 
CNAME and the A RRSet in the ANSWER section, if it is able to include 
both elements authoritatively (i.e. it's authoritative for the target 
owner name).

The question is whether there is a specified order for the different 
RRSets present in the ANSWER section of the response, and the answer 
seems to be no.

The further question is whether the order is important.

> from that point.

What clients are you talking about, here?

> DNS servers that don't follow this unwritten

Can you support this with data?

Not suggesting that you're wrong, but these are interesting and 
surprising statements to me, and I'd like to learn more.

>   its client expected the same.

I'm not sure the behaviour of obsolete versions of BIND is especially 
relevant, although the history is interesting.

>   glibc and dietlibc both expect (CNAME, A).

Neither of those are generally clients of authoritative servers, I 
think.

>   means it happens to `work' with (A, CNAME).

This isn't a client of an authoritative server either.

>   wants on seeing the CNAME, and restarts parsing the whole packet.

Go the programming language? I'm confused as to how that's a client of 
an authoritative server, either.

Is it possible that you're actually talking about the behaviour of 
recursive servers when returning responses to stub resolvers?

Joe

---

From: Viktor Dukhovni <[email-masked]>
Date: Tue, 11 Aug 2015 15:11:41 +0000

> new servers are coming along and meeting old clients.

The ping program talks to whichever recursive resolver is specificed
in /etc/resolv.conf.  Perhaps in the case of ".local" and mDNS,
there are platform-specific variations in how such names are
resolved.

> answer back to the client without re-ordering?

Recursive resolvers construct answers from their caches, and may
need to query multiple nameservers to obtain the information needed
to provide the answer returned to the client.  They generally don't
just proxy response packets from upstream servers.

-- 
	Viktor.

---

From: Ralph Corderoy <[email-masked]>
Date: Tue, 11 Aug 2015 16:41:04 +0100

Hi Joe,

> Paraphrasing with more detail, a query with RD=0, QTYPE=A and some
> QNAME is sent to an authoritative server. The corresponding owner name
> is a CNAME, with some target, and the target owner name has an A RRSet

Agreed, and thanks for the precision.

> RRSets present in the ANSWER section of the response, and the answer

AFAIK.  An additional quote I forgot before that has come up when
discussing this off list:

    https://tools.ietf.org/html/rfc1034#section-3.6

    A domain name identifies a node.  Each node has a set of resource
    information, which may be empty.  The set of resource information
    associated with a particular name is composed of separate resource
    records (RRs).  The order of RRs in a set is not significant, and
    need not be preserved by name servers, resolvers, or other parts of
    the DNS.

(Note, this RFC pre-dates RRsets.)  Although it say "order is not
significant" that's only for those associated with a particular name,
i.e. all the A RRs for foo.com, as I read it.

> > BIND/named seems to have done the obvious from early on, appending
> > the CNAME to the reply, and then appending the A.  Clients have come
> > to depend on this behaviour, assuming on seeing the CNAME that they
> > can switch horses to the CNAME's value and continue processing the
> > packet from that point.
>

Well, ping(1), say, using glibc's resolver.

> > DNS servers that don't follow this unwritten convention thus break
> > some of the many and varied clients that already exist.
>

There's the 50%-round-robin-ping failure I mentioned before.  Examining
other stub resolvers showed glibc isn't alone in its assumption.

> >   4.3BSD's named built the reply in the obvious (CNAME, A) order,
> >   and its client expected the same.
>

Well, I was wondering how far back parsers of replies could have been
lead to believe a certain order was guaranteed.

> an authoritative server, either.

Go implements its own resolver rather than use the local libc's, e.g.
glibc's.  All of them are stub resolvers, yes, but if asked to look up
foo.bar.local and /etc/resolv.conf has only the authoritative bar.local
server in it then they get an authoritative response without a
third-party recursive resolver being involved.

> recursive servers when returning responses to stub resolvers?

No, not in this case.  Let's say I was, if the MITM recursive resolver
knew nothing, queried the authority and got (A, CNAME) back in the one
reply, is it defined that it's responsible for passing that back to the
stub in a particular order, e.g. (CNAME, A)?

Cheers, Ralph.

---

From: Viktor Dukhovni <[email-masked]>
Date: Tue, 11 Aug 2015 15:50:38 +0000

> third-party recursive resolver being involved.

[ Perhaps [email-masked] is the wrong list for this discussion. ]

Best practice is to not conflate authoritative and recursive DNS
servers.  If you put an authoritative rather than a recursive
resolver in /etc/resolv.conf, that's a misconfiguration.

I have a recursive resolver on 127.0.0.1:53 and an authoritative
nameserver on <public-ip>:53.  The /etc/resolv.conf file lists only
the recursive server on the loopback address.  The authoritative
server refuses recursive queries.

-- 
	Viktor.

---

From: Ralph Corderoy <[email-masked]>
Date: Tue, 11 Aug 2015 17:00:05 +0100

Hi Viktor,

> > Go implements its own resolver rather than use the local libc's,
> > e.g.  glibc's.  All of them are stub resolvers, yes, but if asked to
> > look up foo.bar.local and /etc/resolv.conf has only the
> > authoritative bar.local server in it then they get an authoritative
> > response without a third-party recursive resolver being involved.
> 

Agreed, it was pointed out to me off list that [email-masked] would be
better.  I'm happy for it to move, and suggest replies drop the ietf
list from the CC.

For cross-reference, the conversation on ietf starts
https://mailarchive.ietf.org/arch/search/?email_list=ietf&gbt=1&index=wdopuAP2ddLlQcdtX-iAWdUULZ8

> servers.  If you put an authoritative rather than a recursive resolver
> in /etc/resolv.conf, that's a misconfiguration.

OK.

> server refuses recursive queries.

That still leaves open the question of whether the stub resolvers can
assume, as many have apparently been doing for years, that they will be
given CNAME before A.

Cheers, Ralph.

---

From: "Joe Abley" <[email-masked]>
Date: Tue, 11 Aug 2015 13:34:35 -0400

Hi Viktor,

On 11 Aug 2015, at 11:11, Viktor Dukhovni wrote:

> in /etc/resolv.conf.

More detail is useful, here. The ping program uses a local API to translate a name into an address. In the case where that translation requires use of the DNS, a stub resolver sends a query to a recursive resolver. So probably the stub resolver that we're talking about here is one of those included in one of those libcs mentioned previously.

> Perhaps in the case of ".local" and mDNS,

In the case where that translation requires use of some other protocol like bonjour or tor, different mechanisms are used.

> need to query multiple nameservers

... recursive servers, authoritative servers, or both...

> to obtain the information needed

They are specified not to, in fact, in the sense that they have requirements such as RD/AD/CD processing, managing TTLs, etc.

Joe

---

From: Nico Williams <[email-masked]>
Date: Tue, 11 Aug 2015 13:00:40 -0500

On Tue, Aug 11, 2015 at 01:34:35PM -0400, Joe Abley wrote:
> More detail is useful, here. The ping program uses a local API to
> translate a name into an address. In the case where that translation
> requires use of the DNS, a stub resolver sends a query to a recursive
> resolver. So probably the stub resolver that we're talking about here
> is one of those included in one of those libcs mentioned previously.

ping or something else is kind of irrelevant as long as it's a program
using getaddrinfo() or similar system interface to the system stub
resolver or that uses the system stub resolver (as opposed to the
program being dig(1)).

The stub resolver then is the system's.  It should use whatever
/etc/resolv.conf says to use.  *That* has to be a recursive resolver.
If you want to have only an authoritative server for local. and no real
DNS, you still need a recursive resolver for this reason (answer
ordering).

> ... recursive servers, authoritative servers, or both...

Viktor is pointing out that /etc/resolv.conf can only point to a
recursive resolver.

Nico
--

---

From: "Joe Abley" <[email-masked]>
Date: Tue, 11 Aug 2015 14:10:45 -0400

On 11 Aug 2015, at 14:00, Nico Williams wrote:

> /etc/resolv.conf says to use.

... for names that require the DNS for resolution.

> *That* has to be a recursive resolver.

... or a proxy, or a server that is both a recursive resolver and an 
authority server.

> DNS, you still need a recursive resolver for this reason (answer

An authoritative server for local would be ill-advised if you want 
bonjour to work.

> Viktor is pointing out that /etc/resolv.conf can only point to a

... or a proxy, or a server that is both a recursive resolver and an 
authority server.

Joe

---

From: Mark Andrews <[email-masked]>
Date: Wed, 12 Aug 2015 06:58:50 +1000

In message <[email-masked]>, Ralph Corderoy writes:
> but copying doesn't state an order,

Actually the order of the RRsets in the answer section is defined
by that.  The order of the RRsets in the other sections isn't.

> strictly, and 4.3.2 starts by saying
>

Which allows you to use a hash table instead of a tree.  Or a hash
table and a tree.  Or to store the CNAME + pointer to the target
data so there is one lookup into the data store.  You can also use
a flat database.  The answers that are generated need to match those
that would be generate by processing the data in the tree structure
defined following the defined algorithm.

-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: [email-masked]

---

From: Tony Finch <[email-masked]>
Date: Wed, 12 Aug 2015 12:15:41 +0100

> resolver in /etc/resolv.conf, that's a misconfiguration.

Not really. Best practice is to ensure that name servers identified in NS
records are authoritative-only. Recursive servers are more complicated.

https://lists.isc.org/pipermail/bind-users/2015-August/095482.html
https://lists.isc.org/pipermail/bind-users/2015-August/095479.html

Tony.
-- 
f.anthony.n.finch  <[email-masked]>  http://dotat.at/
North Biscay: Northeasterly becoming cyclonic later, 5 or 6. Slight or
moderate. Thundery showers. Good, occasionally poor.