Click the comments link on any story to see comments or add your own.
Subscribe to this blog
08 Aug 2017
The Domain Name System has always been intended to be extensible. The original spec in the 1980s had about a dozen resource record types (RRTYPEs), and since then people have invented many more so now there are about 65 different RRTYPEs. But if you look at most DNS zones, you'll only see a handful of types, NS, A, AAAA, MX, TXT, and maybe SRV. Why? A lot of the other types are arcane or obsolete, but there are plenty that are useful. Moreover, new designs like DKIM, DMARC, and notorously SPF have reused TXT records rather than defining new types of their own. Why? It's the provisioning crudware.
While DNS server software is regularly updated to handle new RRTYPEs, the web based packages that most people have to use to manage their DNS is almost never updated, and usually handles only a small set of RRTYPEs. This struck me as unfortunate, so I defined a DNS extension language that provisioning sytems can use to look up the syntax of new RRTYPEs, so when a new type is created, only the syntax tables have to be updated, not the software. Paul Vixie had the clever idea to store the tables in the DNS itself (in TXT records of course), so after a one-time upgrade to your configuration software, new RRTYPEs work automagically when their description is added to the DNS.
The Internet draft that describes this has been kicking around for six years, but with support from ICANN (thanks!) I wrote some libraries and a sample application that implement it.
Adding new RRTYPEs is relatively straightforward, because the syntax is quite simple. Each record starts with an optional name (the default being the same as the previous record) optional class and time to live, the mnemonic for the record type such as A or MX or NAPTR, and then a sequence of fields, each of which is a possibly quoted string of characters. Different RRTYPEs interpret the fields differently, but it turns out that a fairly small set of fields types suffice for most RRTYPEs.
Here's a typical rrype description, for a SRV record. In each line, the stuff after the space is descriptive text.
SRV:33:I Server Selection I2:priority Priority I2:weight Weight I2:port Port N:target Target host name
The first line says the mnemonic is SRV, the type number is 33, it's only defined in the IN class (the "I".) There are three two-byte integer fields, priority, weight, and port, and a DNS name target. The first word on each field line is the field name, the rest of the line is a comment for humans.
When stored in the DNS, each of those lines is a string in DNS TXT records, like this:
SRV.RRNAME.ARPA. IN TXT ("SRV:33:I Server Selection" "I2:priority Priority" "I2:weight Weight" "I2:port Port" "N:target Target host name") 33.RRTYPE.ARPA. IN TXT ("SRV:33:I Server Selection" "I2:priority Priority" "I2:weight Weight" "I2:port Port" "N:target Target host name")
In the DNS, there are two copies, one at the text name of the RRTYPE, and one at its numeric code. (Until the records are there, the software packages let you change the location. I've put descriptions at name.RRNAME.SERVICES.NET and number.RRNAME.SERVICES.NET.) See the Internet Draft for the full set of field types and syntax details.
The first software package I wrote is an extension to the popular perl Net::DNS module called Net::DNS::Extlang. With the extension, if Net::DNS sees a text master record with an unknown RRTYPE name, or a binary record with an unknown RRTYPE number, it tries to look up the record description in the DNS, and if successful, passes the description to Net::DNS::Extlang which compiles it into a perl routine to encode and decode the RRTYPE which Net::DNS installs. The authors of Net::DNS worked with me so recent versions of Net::DNS have the necessary hooks to do this all automatically. For example, if Net::DNS didn't already handle SRV records, the first reference to a SRV or type 33 record would fetch the description above and create Net::DNS::RR::SRV, with the standard RR parse and deparse methods along with methods called priority(), weight(), port(), and target() to access the individual fields.
The overal effect of this is that if you use Net::DNS::Extlang and put the description of a new RRTYPE in the DNS, Net::DNS will use it automatically, with no per-RRTYPE software upgrade needed. You can find Net::DNS::Extlang in CPAN. Try it out and tell me how you like it.
The second and third packages are a python DNS record syntax checker, and a small django application which uses the syntax checker in a web DNS configuration server. We'll discuss them next.
My other sites
© 2005-2020 John R. Levine.
CAN SPAM address harvesting notice: the operator of this website will not give, sell, or otherwise transfer addresses maintained by this website to any other party for the purposes of initiating, or enabling others to initiate, electronic mail messages.