DNS database source files

A DNS database source file is a human-editable form of the DNS database. It is compiled into the machine readable form by the DNS database compiler.

Overview

DNS database source files are simple text files. Conceptually they are a stream of lexical tokens forming a grammar. The tokenization process treats whitespace characters, including the newlines at the ends of lines, as token delimiters, and removes any part of a line following an unescaped hash ('#') character, which is a comment character. Tokens are either quoted strings (delimited by quotation marks, and capable of using C++-style escape sequences for embedding non-ASCII characters, quotation marks, and newlines in the strings), or unquoted strings, which comprise a sequence of non-whitespace characters.

The grammar describes a simple sequence of records. Each record begins with an unquoted token, which is taken to be a keyword. An unrecognized keyword is a syntax error. The keyword denotes the syntax of following tokens that comprise the whole record. Records can span multiple lines, for clarity and legibility. The end of a record is defined by the grammar, not by newlines in the file.

Record types

There are fifteen record types, introduced by the following keywords:

names or nameserver
a record describing the DNS content servers for a domain name
mail or mailhub
a record describing the SMTP Relay servers for a domain name
host
a record describing a bidirectional mapping from a domain name to an IP address
alias
a server-side alias
chain
a client-side alias
service
a general-purpose service mapping for a domain name
host
a bidirectional host mapping for a host name
hostfwd
a name→address host mapping for a host name
hostrev
a address→name host mapping for a host name
empty
the TTL of empty resource record sets for a "zone" apex
negative
the TTL of non-existent domain names
ddnsup
special-purpose Dynamic DNS Update information for a "zone"
person
special-purpose (and obsolete) information for a "zone"
znxfr
special-purpose (and irrelevant) "zone transfer" information for a "zone"
data
A mechanism for constructing (in raw form) DNS data of arbitrary type, not covered by one of the above types

Scheduled changes and Time To Live

Every record type, except for server-side aliases, incorporates a Time To Live. This is the TTL that is to be employed by caching proxy DNS servers. Additionally, this TTL can be augmented by an inception date and an expiry date. Content DNS servers won't publish data until their inception dates have passed, and won't publish data whose expiry dates have passed. (The content DNS servers will also automatically adjust TTL values to ensure that cached copies of data on proxy DNS servers expire at the same time.)

This information is expressed as a single token, a ttl:inception:expiry token. This token contains just one numeric sub-field for a record with no inception or expiry dates. Otherwise it contains three numeric sub-fields, separated by colons. The inception and expiry date sub-fields can be blank (in which case they represent records whose inception has already occurred, or that do not expire, respectively) or can contain numbers that represent each date as the count of SI seconds since 1970-01-01 00:00:10 TAI.

Location dependence

Every record type, except for server-side aliases, incorporates a location. If the location field is not blank, the content DNS servers will only publish the data in the record to clients whose locations match the value in the location field. Locations allow for clients in different IP address ranges to have different views of the DNS database. (One common use of locations is to give servers in service records different server priorities or weightings for different client views.)

Aliases

Alias records come in two forms: client-side and server-side. Server-side aliases, the preferred form, are handled internally within the database compiler and the content DNS servers. Client-side aliases, are handled, as the name suggests, by DNS clients. (There are various widely-documented difficulties with client-side aliases, from restrictions on their uses for locating SMTP Relay and content DNS servers to problems when they aren't properly maintained. They are not the preferred form.)

Alias records have the following syntax:

alias domain target
chain domain ttl:inception:expiry location target

Service mappings

Service mapping records conceptually map a domain name, and a type of service, onto zero or more tuples comprising an IP address, a port number, a priority, and a weight.

This simple schema is complicated by two factors:

Service mapping records have the following syntax:

nameserver domain ttl:inception:expiry location
  priority weight port "" address(es),
  priority weight port "" address(es),
  …
  priority weight port intermediate-name address(es);
mailhub domain ttl:inception:expiry location
  priority weight port "" address(es),
  priority weight port "" address(es),
  …
  priority weight port intermediate-name address(es);
service domain ttl:inception:expiry location
  priority weight port "" address(es),
  priority weight port "" address(es),
  …
  priority weight port intermediate-name address(es);

Notice that the syntax allows for blank intermediate names (expressed as zero-length quoted string tokens). In this case, the database compiler will invent intermediate names, by taking the domain name and prefixing single-letter labels to it (adding an ns. or mx. label for the case of nameserver and mailhub records), picking the letters to ensure that intermediate names are unique. (This naming scheme is designed to compress well in the DNS protocol, as well as to not overlap first level subdomains. It also results in "glue" resource records that are always in-bailiwick.)

Note: Do not use "rôle hostnames" as intermediate domain names, unless you make sure that the IP addresses published are the same in the service record as they are in any host record. If these IP address lists differ, then people performing DNS lookups will see odd results.

For examples, see best practice.

Hosts

Host records conceptually map a host name to and from an IP address. Host records are less useful than service records, since host records either rely upon the notion of "well known port numbers", which is far from satisfactory for the number of services that a domain can provide, or rely upon the notion of "rôle hostnames" such as "www" and "ftp", which is both inefficient (requiring lots of duplication) and ambiguous (Does an "ftp" rôle name support HTTP service?).

Host mappings are either forward mappings, from host name to IP address, reverse, from IP address to host name, or bidirectional.

Host mapping records have the following syntax:

host domain ttl:inception:expiry location address(es);
hostfwd domain ttl:inception:expiry location address(es);
hostrev domain ttl:inception:expiry location address(es);

Notice that the syntax allows multiple IP addresses in records. This creates a 1-to-many forward mapping or a many-to-1 reverse mapping, or both.

Some examples:

host hobbes.nmsu.edu. 40 "" 128.123.34.6 ;
hostfwd in.parliament.uk. 172800 "" 194.60.38.10 ;

Best practice

Here are various tips for best practice.

Prefer service records over host records. Don't use "rôle hostnames" unless existing naming schemes require you to. Instead leave host records for things that don't provide services, such as machines on a LAN.

Note: It is not necessary to treat "glue names" as if they were "rôle hostnames". Your content DNS server may have been known as ns1.example.org. and your SMTP Relay server may have been known as mx1.example.org., but the world properly only ever looked up those names as "glue" names — the second halves of two-stage NS and MX lookups. It is not necessary to think of such "glue names" as if they should be preserved like rôle hostnames. The world may have known about the rôle hostname www.example.org., but it never knew to explicitly ask for mx1.example.org. except as a result of your telling it to via what you published in other DNS data. Such names are intermediate domain names, not rôle hostnames.

Some examples:

# This is a nameserver record in the preferred style.
nameserver british-library.uk. 172800 ""
  0 0 53 "" 194.66.226.9 194.66.233.106 ; # See below.
# These are intermediate names, not rôle hostnames, and so
# need not be preserved.
#host dns1.bl.uk. 172800 "" 194.66.226.9 ;
#host dns2.bl.uk. 172800 "" 194.66.233.106 ;

Do not supply an explicit intermediate name in a service record, and list all IP addresses that have the same priorites, weights, and port numbers in a single sub-record. For examples:

service _http._tcp.pantz.org. 40 ""
  40 0 80 "" 68.49.78.36 ;
service _smtp._tcp.calomel.org. 60 ""
  0 0 25 "" 71.179.97.249 ;
service _pop3._tcp.fudo.org. 60 ""
  0 0 119 "" 204.16.144.199 2002:CC10:90C7::0001 ;
nameserver mod.uk. 172800 ""
  0 0 53 "" 195.66.240.130 2a01:0040:1001:0035:0000:0000:0000:0002 192.5.29.50 ;

Sometimes one might find that the intermediate domain names are required, because they map to other people's machines whose IP addresses may change arbitrarily, without one being informed. For examples:

mailhub os2bbs.com. 3600 ""
  10 0 25 m2.spamarrest.com. ,
  20 0 25 r1.spamarrest.com. ;

Note that you are giving other people control over where your domain's published services are when you do this. This is not a thing to do lightly. It is strongly recommended that you list services by their IP addresses, with blank intermediate names, and only use this form as a rare exception.

As Jim Nelson notes, in an ideal world, everyone would be using service DNS lookups for all server protocols, and both rôle hostnames and the NS and MX resource record types would be obsolete. In such an ideal world, one's database source file would look like this:

# In this example, services are normally provided on IP addresses
# e.f.g.h and i.j.k.l with a 60/40 load balancing split.
# In the event of network outage, fallback is to address m.n.o.p
# which shouldn't be used in normal operation (because it serves up
# placeholder WWW pages announcing a server outage, for starters).

# Record for HTTP clients:
service _http._tcp.some.corp. 604800 ""
  10 60 80 "" e.f.g.h ,
  10 40 80 "" i.j.k.l ,
  20 0 80 "" m.n.o.p ;

# Record for SMTP Relay clients:
service _smtp._tcp.some.corp. 604800 ""
  10 60 25 "" e.f.g.h ,
  10 40 25 "" i.j.k.l ,
  20 0 25 "" m.n.o.p ;

# Record for POP3 clients:
service _pop3._tcp.some.corp. 604800 ""
  10 60 110 "" e.f.g.h ,
  10 40 110 "" i.j.k.l ,
  20 0 110 "" m.n.o.p ;

# Record for NNTP clients:
service _nntp._tcp.some.corp. 604800 ""
  10 60 119 "" e.f.g.h ,
  10 40 119 "" i.j.k.l ,
  20 0 119 "" m.n.o.p ;

# Record for DNS clients:
service _domain._udp.some.corp. 604800 ""
  10 60 53 "" e.f.g.h ,
  10 40 53 "" i.j.k.l ,
  20 0 53 "" m.n.o.p ;

The world at large has not reached this ideal. Whilst many protocols do employ service DNS record lookups — and there are a lot more of those than people think —, some HTTP clients, some SMTP Relay clients, and some DNS clients still do not use service lookups. (The clients in the Internet Utilities are all service-record aware, and can all be configured to use service lookups. So, too, is the proxy HTTP server, although the resolving proxy DNS server does not use service lookups to find content DNS servers.) Coping with such clients currently requires a few more records in a DNS database source file:

# Old SMTP Relay clients are almost there, but won't do load balancing:
mailhub some.corp. 604800 ""
  10 60 25 "" e.f.g.h ,
  10 40 25 "" i.j.k.l ,
  20 0 25 "" m.n.o.p ;

# Notice the omission of m.n.o.p in the following.  Old-style clients
# do not know, and cannot be told via the DNS, not to use it in normal
# operation.  (This lack is one of the disadvantages of old-style data
# compared to service records.)

# Old HTTP clients need a rôle hostname:
hostfwd www.some.corp. 604800 "" e.f.g.h i.j.k.l ;

# Old Content DNS clients at least don't need rôle hostnames,
# but won't do load balancing or fallback:
nameserver some.corp. 604800 ""
  10 60 53 "" e.f.g.h ,
  10 40 53 "" i.j.k.l ;

The mailhub and nameserver records are intentionally designed to be easily convertable to service records (and vice versa, of course), to aid in the progress towards the ideal. Hence the inclusion in their syntax of information that is not actually, because of the way that the DNS protocol works, publishable to the world.


The Internet Utilities are © Copyright Jonathan de Boyne Pollard. "Moral" rights are asserted.