One little underscore reveals overloading

One little underscore reveals a hacky design move: to support DKIM (a protocol that authenticates email senders to fight spoofing), domains store their public keys in DNS, in a CNAME record, using a fake hostname of the form

s1._domainkey.foo.com

Why the underscore? Presumably so that the special string _domainkey doesn’t clash with a real hostname, since hostnames are not allowed to start with one. But then the CNAME record is supposed to map hostnames, and so some DNS providers prohibit underscores in them. Oops!

This is a classic example of overloading: gory details here.

I wonder: is this kind of thing responsible for much of the complexity in these kinds of systems, which makes basic sys admin tasks often very challenging?

Hi.

The underscore conventions is a standardized practice and is actually quite popular:

[Scoped Interpretation of DNS Resource Records through “Underscored” Naming of Attribute Leaves]
(RFC 8552 - Scoped Interpretation of DNS Resource Records through "Underscored" Naming of Attribute Leaves)

It looks like you believe domain names are supposed to be restricted to host names, but that was never in its design. Layered conventions are at the heart of many – /very/ many – Internet standards enhancement efforts, over the decades.

btw, from your blog entry, you note that some DNS service providers do not support underscore. Indeed, there are many examples of software or operations that fail to conform to standards. That hardly demonstrates that there is a problem with the standard.

Hi Dave,

Welcome!

I see you yourself are the author of 8552, so you obviously know much more about this than me!

No, I was not suggesting that domain names have to be hostnames. What I was saying was that there are two distinct purposes or functions that DNS provides, which are distinct enough to merit being viewed (in my terminology) as two different concepts. One is name resolution for routing, and the other essentially uses DNS as a database for arbitrary properties.

My understanding (correct me if I’m wrong) is that hostnames used in routing should not have underscores in them, but names with underscores can be used for the second purpose, and in that case they’re not hostnames.

Now the concept design point: it seems to me that the DNS protocol doesn’t support the second purpose fully enough: hence problems with TXT lookups returning records that aren’t of interest, eg. So instead of supporting that purpose in its own right, for example in the manner I suggested, people started using other record types, such as the use of CNAME for DKIM. But that now creates some confusion, because CNAME is designed for name resolution and (unlike TXT eg) not database lookup. So understandably some DNS providers thought that CNAME labels should not contain underscores, and that leads to trouble.

Does that make sense?

Daniel

1 Like

Daniel,

Taking this as a technical forum, I’ll indulge in some quibbling, along with trying to deal with more serious substance…

The term ‘database’ has a generic, simple, non-technical use, but in more technical contexts, it tends to refer to a relatively rich set of functionality, including searching. So, for example, rather than specifying exact details for getting a specific record, it can search based on partial names or by attributes. I note this, because the DNS does not support such functionality, which is an aspect of the DNS that is often missed. The technology of the DNS is typically referred to as doing a ‘lookup’ rather than a search, since the DNS requires an exact match to a specific name. So, it’s best thought of as doing simple key/value processing. That’s a quibble.

Another quibble is that your reference to ‘routing’ is understandable but, really, the information returned for such queries is an address, not a route. (Since I always look for an excuse to cite this paper, thanks for that excuse: https://dl.acm.org/doi/10.1145/9760.9761.) That said, the MX record creates the global routing mechanism for email. sigh.

Perhaps more substantive is the distinction between what a mechanism does vs. how it is used. The DNS has a limited, fixed set of functions. Arguably, really, it only has one: Take a specific name and return some attributes associated with it. Period. It ‘understands’ no semantics to any of this. For example, it does not distinguish between attributes containing addresses vs those containing some other kind of information.

So the distinctions occur at a higher layer and vary on the /use/ of the DNS, not on the underlying structure or function of the DNS itself. Limiting the lookup string to what is called a hostname, is a feature of such a higher-level use. The DNS, itself, does not know about that limitation. And, again, it does not know about ‘routing’ – actually ‘addressing’ – use, versus other use.

I haven’t reviewed the specification details for where hostname syntax is required, versus allowing fully general DNS node names. Those details are for a use of the DNS, not as something in the DNS itself. (As I recall, DNS documentation contains the concept of a host name, but discussion about it is, I believe, non-normative. Maybe I’ve got that wrong.) Anyhow, you are certainly correct that a node name containing an underscore means the domain name is not a host name. That is, in fact, why underscore was chosen: no chance of colliding with a hostname.

Getting to your ‘concept design’ point. Limitations such as not distinguishing among a set of TXT records under the same name are indeed a hassle. The underscore hack is a way of eliminating or at least reducing the problem. Distinctive RR records would be cleaner, of course, but the field experience with the DNS is that getting end-to-end support for new RRs has had an extremely problematic history. After some decades with this reality, people starting just working around it. Ugly, but practical.

To clarify: the underscore convention permits defining a place for semantically-constrained attributes, such as in TXT records. Such TXT records will be there for that semantic and not some other. (It’s not unreasonable to simplify all this to: The underscore naming hack separates unrelated records of the same type, such as TXT RRs.)

The reference to CNAME in DKIM is interesting. Note that RFC 6376 does not mention CNAME. While use of CNAMEs with DKIM is extremely common – and noted in an Informational RFC – it’s not in the DKIM spec itself.

A quick scan of some online documentation about this does treat things as TXT vs. CNAME. For sysadmin’s purposes, that simplification is probably reasonable. In terms of understanding DNS basics, it’s probably note.

Name resolution in the DNS is walking a sequence of node names. The CNAME construct is for that node-walking process, but makes a jump, while doing that resolution, over to another name sequence. It’s a DNS construct, not an explicit DKIM construct. (This goes back to the importance of recognizing layers of functionality.)

With all of that, I’m ultimately not understanding “But that now creates some confusion, because CNAME is designed for name resolution and (unlike TXT eg) not database lookup.”

Dave,

Thanks for these clarifications. Let’s get the easy things out of the way:

  1. Yes, I should have said address instead of route; that was sloppy.
  2. Yes, a database has more functionality than lookup, but I was using that term to contrast one concept with another. More on that below.

You’re right in noting that DNS is best thought of as just mapping names to values; and those names are often hostnames but don’t need to be. My observation is that this was not the original intent of DNS. As Wikipedia explains:

The resource records contained in the DNS associate domain names with other forms of information. These are most commonly used to map human-friendly domain names to the numerical IP addresses computers need to locate services and devices using the underlying network protocols, but have been extended over time to perform many other functions as well.

My interest is in this extension, and how it has design features in common with many extensions we make to software. The particular kind of extension that I’m focusing on is what I call overloading by piggybacking, in which you have a unit of functionality (which I call a concept) that serves a particular purpose, and you extend it to support a new purpose which is mostly but not completely compatible with it. For exactly the kinds of reasons you note (in this case, that getting support for new DNS records has “an extremely problematic history”), it is often preferable to stick with the piggybacking and pay the costs rather than attempt a cleaner redesign.

My post attempts to lay out the details of the piggybacking in this case, and argued as follows:

  1. The initial concept of DNS (c. 1983) was to translate hostnames to addresses.
  2. At some later point, it was realized that it would be useful to use DNS for other purposes, piggybacking on its ability to store attributes for hostnames. This led to the TXT record (c. 1993) which allowed you to store arbitrary values against a hostname.
  3. The TXT record mechanism had some flaws; in particular, it was so useful that TXT records became big and unwieldy, so people looked to finding ways to get a more limited lookup. This (and correct me on this if I’m wrong) is where keys containing underscores were helpful: they let you get back a smaller set of TXT records by looking up not foo.com but _mykey.foo.com.
  4. As protocols like DKIM evolved, people realized they could use these keys even for the records in DNS that had been designed for address lookup, so you could create a CNAME record, for example, that mapped _domainkey.foo.com to the hostname of a machine that holds the public key for foo.com’s DKIM service.

My theory of concepts says that a tradeoff like this inevitable has some negative consequences. I hypothesized that the fact that some DNS providers would not allow underscores in CNAME keys was one such consequence. But I can’t imagine that there aren’t others. Do you disagree?

The alternative, which I agree seems infeasible given the difficulty of changing something as deeply embedded as DNS, would be not just a new record type, but a new kind of lookup, where you have two arguments: the host name (foo.com) and the property (domainkey). Does that make sense?

Daniel, I fear that ‘initial use’ is confused with ‘overall intent’. Yes, initial use was mapping a name to an address. I’d guess it is still by far the dominant use. But the statistics of use don’t determine the intent of the design. They merely make a case for basic efficacy.

Since its inception, the DNS has been the target of all sorts of additional uses. This gives credence to a view that the ‘intent’ was to permit other uses. (Not proof of it, but still…)

As for overloading by piggybacking, the description of the concept you provide is reasonable, but I’ll suggest it does not apply here. DNS was designed for a few different kinds of extensibility. It is not ‘overloading’ to use that. It’s just… extending.

An example of extending in a way that appears not to have been anticipated is, indeed, the underscore hack, which is a means of creating a clean mechanism for defining attributes to a name. Absent that, DNS node names have no type or other attribute information. While the underscore hack is ugly, it’s also effective. (cf, DKIM as an overlay for key distribution. Ugly but effective. And remarkably simple, compared with, say, DANE.)

“My post attempts to lay out the details of the piggybacking in this case, and argued as follows:”

You might want to review RFC 1034 carefully. I think it makes clear that the DNS was intended for a much broader range of uses than just name to address mapping.

Hi Dave,

I had a chance to read many of the DNS RFCs carefully, including a crucial one that you modestly didn’t mention but which you authored yourself, and which explains the need for a registry of underscore labels.

I’ve updated my post with some notes at the bottom summarizing what I learned, and refining my explanation of where the overloading is. Clearly you’re right that the “underscore hack” as you call it is effective. What interests me from a design perspective is what costs there might be to pay for this, and whether it’s a symptom (as my original post suggested) that DNS itself might have offered more flexible key/value lookup functionality.

Daniel

Daniel, hi. A few responses:

  1. Cost of the _underscore hack: Seems to reasonably modest. Implementation cost at the creator is being able to create an _underscored subdomain and adding a TXT record to it. More difficult than it should be, with the tools some DNS providers offer, but easy with others. The other implementation cost is the DNS query by a receiver. That seems to be only one extra lookup – which includes traversals down one or a few subdomain names. (You note the possibility of multiple, competing TXT records, which I’ll comment on, below) All in all, the operational DNS world does not seem to view any of this as an interesting increase in overhead. 20 or 30 years ago, I think it did.

  2. For reference, the publication of RFC 8552 (on the use of underscored names) came more than 10 years after the first draft was written. There were some basic technical problems with the early versions of the draft but more importantly there was very strong resistance from the core DNS technical community and it killed work at that point. Publication was eventually possible only because of changes in that community (including one of its number pressing for the work to re-start.)

  3. Confusion. You cite CSNet phone numbers in the DNS. I developed and ran the CSNet email service for its first couple of years and the DNS didn’t exist yet; we used an independent (rather small) file with the phone numbers. That said, I didn’t track later CSNet developments. While I can imagine some ways to use the DNS for the phone numbers, note that the places being referred to, by a phone number, were not on the IP Internet, where the DNS was/is. They were only accessible by an email gateway. I don’t recall hearing about CSNet phone numbers in the DNS; do you have a reference to this? (I do know there was a major effort to get several independent services, including CSNet, to standardize on using the DNS, but I think that wasn’t specifically tied to phone numbers.)

  4. Small quibble. In your update, you refer to the DNS as a database. In casual discussion, that’s a fine, generic, non-technical term. In technical discussions, it can create confusion. Typical ‘database’ systems have ‘searching’ and one or another kind of fuzzy string matching. The DNS doesn’t do this. You must give it only and exactly a complete lookup string to use (in classic key/value terms.) Hence, it is safer to refer to the DNS as a lookup service.

  5. Competing TXT records. You cite the challenge of parceling out the type of content being sought, among a collection of TXT records that contain different types of information. This is the long-standing concern about TXT records, since they do not overtly distinguish the ‘type’ of information they contain, the way a typical DNS RR will do. However this is exactly the problem that the _underscore hack mostly solves: The TXT record(s) put under and _underscored name are specific to the ‘scope’ of that _underscored name. I say “mostly” because, of course DNS wildcard names can propagate TXT records down its the subtree, including into _underscored nodes.

  6. CNAME. Hmmm. You seem to indicate that CNAME use aids in the competing-TXT records problem. That does not match my sense of its use. Rather, I understand CNAMEs to be use for administrative convenience, rather than in aiding the work of the side doing lookups.

  7. ‘Intentional’ names. This is a challenging topic, because it requires parceling out – and juggling – a number of issues. A core point is that domain names, per se, are typeless and semantics free. A name is only and exactly a series of strings that have no semantics to the core DNS functions, other than for traversing the tree. Traversal does not depend on type or semantics. This was true in the original DNS and remains true. Really!

Semantics and typing are higher-level constructs. That is, they are layers built on top of this core, but do not change that core. The eventual use of www.* or imap.* and the like, for distinguishing access to a service, is an operational convention. It actually has nothing to do with the DNS, itself, but with the way some/many sites choose to administer their own use of the DNS.

I think I understand your phrasing of “the ability to perform a lookup on two keys”, given the example you use – _ldap._tcp.foo.com – but really, these are not ‘keys’ in the sense the term is used for database queries. And certainly the DNS itself knows nothing about the conventions being applied in the use of those. And I continue to be uncomfortable with calling any of this ‘overloading’ since it implies competing or confusing system semantics, and this has none of that.