Rate this page

Flattr this

DNS zone file tutorial

Introduction

A zone is a contiguous region within the domain name hierarchy which is administered as a single unit:

It is common practice for domains and their subdomains to be assigned to separate zones, however this is not obligatory: zone boundaries can be placed wherever is most convenient for their administration. For example, a zone starting at example.com would typically delegate the subdomain foo.example.com and its content to another zone, however it would be equally acceptable for example.com and all domain names descended from it to be defined within the same zone.

A zone file is a standard text-based representation for the content of a zone. DNS servers are not required to use zone files, but they are often supported as an interchange format even if the data is stored internally by some other means.

Example

The following example illustrates some of the main features of a zone file:

$ORIGIN	example.com.
$TTL	86400
@	IN	SOA	theoden.example.com. hostmaster.example.com. (
			2015030100 ; serial
			28800      ; refresh
			7200       ; retry
			604800     ; expire
			86400)     ; minimum

		NS	theoden.example.com.
		NS	eomer.example.com.

		MX	10	eowyn.example.com.

theoden		A	192.0.2.1
eowyn		A	192.0.2.6
eomer		A	192.0.2.7
wormtongue	A	203.0.113.95

The first two lines are directives which do not directly contribute to the queryable content of the zone, but which allow the remainder of the zone file to be expressed more concisely than would otherwise be possible. $ORIGIN specifies a domain name to be automatically appended to any relative domain names which appear subsequently (making it possible, for example, to write theoden in place of theoden.example.com.). $TTL specifies a default value for the time-to-live field of subsequent resource records which do not already have one.

The remainder of the zone file is composed of resource records. The first of these, the SOA (Start of Authority) record, contains information about the zone as a whole. It has seven fields, in this instance split over six lines, which specify the hostname of the primary nameserver, the e-mail address of the hostmaster, and a serial number and timing parameters which control how the zone contents are cached by other nameservers.

The next two resource records are NS records, and they list the hostnames of the authoritative nameservers for example.com. Following them is an MX record, which lists the hostname of an e-mail server (mail exchanger) to which mail addressed to example.com can be sent. Finally, four A records give the IPv4 addresses of the specified hostnames in example.com.

File Structure

Overview

The substantive content of a zone file is composed of a sequence of entries. There are two types of entry:

The order in which resource records are listed is not generally significant, however there must be exactly one SOA record and it must be the first record. The SOA record can be, and often is, preceeded by one or more directives.

Directives may affect how subsequent resource records are interpreted, and for this reason their position in the zone file is often significant.

Whitespace

The components of a resource record or directive are separated by whitespace. The amount of whitespace is not significant, and it can be composed from any combination of tabs and/or spaces. However, the presence or absence of leading whitespace at the start of a line is normally significant. For example, in the line:

		NS	theoden.example.com.

an initial character of whitespace is needed in order to ensure that NS is interpreted as a resource record type as opposed to a domain name. However the quanity of whitespace is unimportant, and it makes no difference whether it is composed of tabs, spaces or a combination.

Blank lines, or lines containing only a comment, are permitted anywhere within the zone file.

Comments

Comments are allowed at the end of any line in the zone file. They begin with a semicolon, and continue to the end of the line in question.

Splitting entries across lines

Most resource records and directives occupy a single line of the zone file, however it is possible to split content across multiple lines by enclosing it within a pair of parentheses. For example, the SOA record in the example above was split over six lines:

@	IN	SOA	theoden.example.com. hostmaster.example.com. (
			2015030100 ; serial
			28800      ; refresh
			7200       ; retry
			604800     ; expire
			86400)     ; minimum

It could have been expressed with equal validity as a single line:

@	IN	SOA	theoden.example.com. hostmaster.example.com. 2015030100 28800 7200 604800 86400

Other types of resource record can be split in the same way, but most are short enough that there is no benefit in doing so.

Note that parentheses do not cause comments to span multiple lines, therefore it is possible to place comments in the interior of a multi-line resource record (as in the example above).

Absolute and relative domain names

Domain names in zone files can be expressed in either absolute or relative form. Absolute names are distinguished by ending them with a period, so in the example above theoden.example.com. is an absolute domain name, whereas theoden by itself is a relative name.

When relative domain names are encountered, they are resolved into absolute names by appending the current origin. Some DNS servers provide a sensible default origin, however it is safer not to rely on this and to always set one explicitly at the start of the zone file by means of an $ORIGIN directive (see below). If required, it is permissible to have several such directives setting different origins for different parts of the zone file.

Be aware that incorrect omission of trailing periods is one of the most common errors made when writing zone files. Furthermore, such errors do not normally make the zone file invalid, but will result in unintended behaviour once it has been loaded. For example, consider an NS record written to refer to what would have been the correct absolute hostname, but with the trailing period omitted:

		NS	theoden.example.com

If the origin is set to example.com. at this point in the zone file, then the hostname (which is now being interpreted as a relative hostname) would expand to theoden.example.com.example.com..

Resource Records

Format

When written in full, each resource record is composed of:

For example, in the record:

www	86400	IN	A	192.168.0.1

the domain is www, the TTL is 86400 seconds (24 hours), the class is IN, the type is A, and there is one further field (an IP address in this instance).

To avoid repetition, the domain, TTL and class fields are optional in zone files. If omitted they default to the most recent value that was explicitly specified. For example, since most resource records have a class of IN, it is common practice to specify this in the first record only and rely on that value propogating to subsequent records. In the case of the TTL field, the default value can be changed by means of the $TTL directive. The record above could therefore potentially be reduced to:

www	A	192.168.0.1

When the domain field is present it must be located at the start of a new line. When absent there must instead be at least one character of whitespace where the domain would have been. The TTL and class fields can be omitted with nothing in their place. This does not result in any ambiguity, because they have a representation which allows the zone file parser to distinguish them from resource types and from each other.

Domains can generally have any number of resource records, of either the same or different types. For example, a host can have both A and AAAA records to indicate that it has both IPv4 and IPv6 addresses. It can similarly have multiple A records, to indicate that it has multiple IPv4 addresses. Other combinations may or may not be meaningful, depending on the semantics of the record types, and some (such as SOA and CNAME) have specific rules which further constrain their usage.

Types

Each resource record has a type which indicates what information it contains and how it should be interpreted and processed. The original DNS specification defined 16 types of resource record, however many more types have been added subsequently, and at the time of writing there were several dozen registered with IANA. In practice most of these are either obsolete or used rarely. The following are sufficient for most unsigned zone files:

SOA the start of a zone of authority
NS a hostname for an authoritative nameserver
CNAME the canonical name for an alias
A an IPv4 host address
AAAA an IPv6 host address
PTR a pointer to a domain name
MX a hostname for a mail exchanger
SRV a hostname for a given network service
TXT a text string

DNSSEC introduces several further record types, including DNSKEY, RRSIG and NSEC/NSEC3, however specialised software is needed to generate and interpret them.

Start of authority (SOA) records

The SOA record contains general information about the zone as a whole. There should be exactly one per zone, and when listed in a zone file it should be the first record. It has seven fields:

MNAME the domain name of the primary name server for this zone
RNAME the hostmaster e-mail address, formatted as a domain name
SERIAL the serial number for this version of the zone
REFRESH the time that a slave nameserver waits following a successful refresh before attempting another
RETRY the time that a slave nameserver waits following a failed refresh before trying again
EXPIRE the time for which a slave nameserver should consider this zone data to remain valid in the absence of a successful refresh
MINIMUM the TTL (time to live) to be used for cached negative results relating to this zone

The MNAME field is used to identify the primary nameserver, that being the one in possession of the master copy of the zone data. This presumes that the nameservers for the zone are organised in the conventional manner: a single primary, and a number of secondaries which obtain copies of the zone data from the primary (or sometimes from other secondaries). For other configurations, it it not always obvious which nameserver should be listed as the primary. When deciding this it is useful to have an understanding as to how the information is (and is not) used:

The main distinguishing characteristic of the primary nameserver is therefore the ability to effect changes to the zone data which will replicate to all of the other nameservers. If either none or all of the nameservers can do this then one must still be designated as the primary, however it is unlikely to make any practical difference as to which one is chosen.

Note that the specified primary nameserver need not be one of those listed in the NS records for the zone. This would be appropriate if you did not want any queries to be directed to the primary nameserver (an ‘unpublished primary’).

The RNAME field is formed by replacing the at-sign in the e-mail address with a dot (thus making the username the first component of the domain name). RFC 1912 recommends creating an e-mail alias named hostmaster for this purpose. Should you decide to use an e-mail address which already contains dots in the username then these must be escaped with a backslash.

The SERIAL field is used by secondary nameservers to decide when a zone transfer is needed to obtain an updated copy of the zone content. For this reason it is very important that it be replaced with a higher value whenever the zone content is changed.

Serial numbers are unsigned 32-bit integers, represented in decimal format within the zone file. There are three schemes in common use for constructing the serial number:

It is possible to safely reduce the serial number of a zone to a lower value if the correct procedure is followed. See the microHOWTO Reset the serial number of a DNS zone for instructions regarding how to do this.

See below for a discussion of timing parameters (REFRESH, RETRY, EXPIRE and MINIMUM).

IPv4 host address (A) records

An A record is used to map a domain name to an IPv4 host address. For example, if the domain name elendil.example.com should resolve to the IP address 192.0.2.67 then that can be achieved by adding the following A record to the zone file covering example.com:

elendil         A       192.0.2.67

It is permissible for multiple A records to resolve to the same IP address, however you may prefer to use CNAME records to achieve a similar effect. See below for a discussion of the relative merits of these two approaches.

It is similarly permissible for a single domain name to have multiple A records with different IP addresses, however you should ensure that you understand the semantics of this configuration as it may not have the behaviour you expect:

The address referred to by an A record must be specified in dotted-quad notation, as in the example above.

IPv6 host address (AAAA) records

A different record type, AAAA, is used for mapping domain names to IPv6 addresses. This is to distinguish them from IPv4 addresses and to allow for their increased length (128 bits as opposed to 32 bits).

It is common for A and AAAA records to exist alongside each other, indicating that the host is accessible using either IPv4 or IPv6. If the client supports only one of these protocols then it can query the appropriate record type. If the client supports both then it can choose between a policy of IPv6-first or IPv4-first.

The address must be specified using one of the standard textual formats defined in RFC 3513. For example, 2001:db8:0:0:0:0:0:0 and 2001:db8:: are equally valid representations for the same address. Host addresses are transported by the DNS in binary form, therefore the chosen textual format will not necessarily be preserved.

Zone indices, as used in IPv6 link-local addresses, are not supported. (They would, in any event, not be meaningful to other machines.)

Pointer (PTR) records

The most common use of PTR records is to map IP addresses to domain names as part of the reverse DNS service. To make this possible, IP addresses must first be converted into a form which looks like a domain name. Two special-purpose top-level domain are reserved for this purpose: in-addr.arpa for IPv4 and ip6.arpa for IPv6. The conversion procedure for IPv4 is as follows:

  1. Begin with the address in dotted-quad format (for example, 192.168.0.1).
  2. Reverse the order of the components (for example, 1.0.168.192).
  3. Append the suffix in-addr.arpa. (for example, 1.0.168.192.in-addr.arpa.).

The procedure for IPv6 differs in that each component of the domain name corresponds to 4 bits rather than 8 bits, and is represented by a hex digit:

  1. Begin with the address in uncompressed hexadecimal format, including all leading zeros (for example, 2001:0db8:0000:0000:0000:0000:0000:0000).
  2. Reverse the order of the digits, placing a period between each (for example, 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2).
  3. Append the suffix ip6.arpa. (for example, 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.).

In both cases the PTR record should refer to a domain with a matching A or AAAA record. If there are several such domains, it is permissible (but not necessarily desirable) to reflect this by associating multiple PTR records with the relevant IP address. This issue is discussed in more detail below. PTR records should not refer to CNAME aliases.

Reverse DNS was originally the only defined use for PTR records, however they can be given meaning in the context of other special-purpose domains. An example is the DNS-SD protocol (RFC 6763), which uses them to identify servers capable of providing a given type of network service.

Mail exchanger (MX) records

MX records are used to specify how mail addressed to a given domain should be routed. Each contains the domain name of a mailserver capable of handling the mail, together with an integer used to rank the mailservers in order of preference. For example, the following pair of MX records:

@       MX      10      mail.example.com.
@       MX      20      backup.example.net.

would direct mail to mail.example.com by preference, but allow fallback to backup.example.net if the primary mailserver is unavailable. Note that:

It is possible to receive mail without an MX record, since the default behaviour is to look for an A or AAAA record instead, however it is considered good practice to provide one even if it merely points to the corresponding host. There are a couple of reasons for this:

Text (TXT) records

TXT records were originally intended for storing descriptive text associated with a domain name. They are still used for this purpose, but have also gained widespread use as a method for storing new types of data in the DNS without having to define new types of resource record. Protocols which have done this include:

Another common use is domain control validation when obtaining SSL certificates, or accessing web analytics data from search engines.

This practice has attracted some criticism, and RFC 5507 recommends that creation of a new resource record type should be the preferred approach wherever possible. However, protocol designers have found that migrating away from TXT records can be difficult once their use becomes established, even if it was originally made clear that they were intended as a temporary measure.

The content of each TXT record is a sequence of one or more strings. Each string has a maximum length of 255 characters, and is usually delimited by a pair of double-quote characters, for example:

example.com. IN TXT "v=spf1 a:mail.example.com -all"

(This is an SPF record indicating that the only server entitled to send mail from the domain example.com is mail.example.com.)

It is technically permissible for the double-quote characters to be omitted when the string contains no spaces, however mistakes are less likely if they are included regardless. Double-quote characters can be included within the string by escaping them with a backslash character. If there are multiple strings in the record then it will often be convenient to split them across multiple lines using parentheses, for example:

example.com. IN TXT ("v=spf1 "
                     "a:mail.example.com "
                     "-all")

Note that string boundaries are preserved by the DNS protocol, so three separate strings would be seen when this record was queried. In the specific context of an SPF record, multiple strings are defined to be equivalent to a single string containing the concatenated content, but that will not necessarily be the case when TXT records are used for other purposes.

Pointer (SRV) records

The purpose of SRV records is to facilitate the discovery of network services. Each one lists a hostname and port number that can be used to access a given service within the context of a given domain. For example:

_imap._tcp.example.com. IN SRV 0 0 110 mail.example.com.

indicates that there is a mailserver at mail.example.com for the domain example.com capable of providing access to emails by means of the IMAP protocol. This information could be used by a mail client to reduce the amount of information that the user must supply when adding a new account: once the email address (and hence the domain) is known, the mail server address can be determined automatically.

Domain names for SRV records have three parts:

  1. The name of the service in question, preceded by an underscore;
  2. The name of the protocol by which the service is delivered (usually tcp or udp), preceded by an underscore; and
  3. The domain to which the service is directed.

Each record has four data fields:

  1. The priority, which is an unsigned 16-bit integer used to control the order in which servers are tried. Servers with a lower priority are used in preference to those with a higher priority.
  2. The weight, which is an unsigned 16-bit integer used to distribute load between servers with the same priority. The probability of selecting a given server is proportional to the weight assigned to it. In the special case where all of the weights are zero, the servers are selected with equal probability.
  3. The port number on which the service is provided.
  4. The domain name of the host which provides the server, which must have at least one address record, and must not be a CNAME alias.

It is possible to explicitly indicate that a service is not available by creating an SRV record pointing to the root domain. A common use of this is to direct users to the encrypted variant of a service instead of the unencrypted one:

_imap._tcp.example.com IN SRV 0 0 0 .
_imaps._tcp.example.com IN SRV 0 0 993 mail.example.com.

Canonical name (CNAME) records

CNAME records are used to indicate that a given domain name is an alias for a given canonical name. For example, suppose that the zone file for example.com contained the following resource records:

thranduil	A	192.168.0.2
celebrimbor     A       192.168.0.5
celebrimbor	MX	10	thranduil
www		CNAME	celebrimbor

If a name resolver were asked to find the host address for www.example.com it would first issue an A-record query for that domain. Since there are no A records this would normally result in a NODATA response, however DNS servers have special rules for processing domains with CNAME records. If the requested record type is not found, and if the request is for a type other than CNAME, then:

The name resolver would therefore see the result set:

celebrimbor     A       192.168.0.5
www		CNAME	celebrimbor

from which it would conclude that the host address for www.example.com is 192.168.0.5. Similarly, mail addressed to that domain would be delivered to 192.168.0.2 by following first the CNAME record and then the MX record.

RFC 1034 recommends that CNAME aliases should not be used on the right-hand side of other resource records. It follows that:

This is not to say that CNAME aliases will fail to work if used improperly. RFC 1034 recommends application of the robustness principle, and aliases are usually followed in practice provided that the chains are not too long. However, it is safer and more efficient to refer directly to the canonical name.

There are two further restrictions on the use of CNAME records:

DNS resolvers can and do rely on these rules to avoid unnecessary queries when cached records available. There is therefore a high risk of erratic behaviour if a CNAME record conflicts with other records.

Directives

Format

There is no generic syntax for zone file directives, however they conventionally begin with a keyword starting with a dollar sign which identifies the directive type. At the time of writing there were three standard (or proposed standard) directive types:

$ORIGIN Set the origin for subsequent relative domain names
$INCLUDE Include the content of the specified file as part of the current zone file
$TTL Set the time-to-live for subsequent resource records which do not explicitly specify one

Some nameservers support additional non-standard directives, such as the $GENERATE directive provided by BIND.

The $ORIGIN directive

As noted above, domain name in zone files are interpreted as being relative to the current origin unless they are written ending with a dot. The current origin can be changed using the $ORIGIN directive:

$ORIGIN example.com.

It is good practice to place an $ORIGIN directive at the start of each zone file, in order to avoid relying on a default origin which may or may not have been defined by the nameserver software. Further $ORIGIN directives can be added freely as required.

Note that the $ORIGIN directive is no exception to the rule that absolute domain names must end with a dot.

The $INCLUDE directive

The data for each zone is usually kept in a single file, however there are circumstances where it is beneficial to split it between multiple files. This can be arranged using the $INCLUDE directive, which causes the content of a given file to be included as part of the zone data:

$INCLUDE db.example

By adding a second argument it is possible to specify a new origin for the included zone data:

$INCLUDE db.example example.com.

A common use for this is to manage the content of zones which have multiple subdomains. By using the $INCLUDE directive, it is possible to split the data for each subdomain into a separate file without having to split it into a separate zone (which would require delegation, and potentially result in higher load and lower performance). The two-argument form of the directive is ideally suited to this use case:

$INCLUDE db.subdomain1 subdomain1.example.com.
$INCLUDE db.subdomain2 subdomain2.example.com.
$INCLUDE db.subdomain3 subdomain3.example.com.

Note that however the origin is changed (whether by the $INCLUDE directive itself or by $ORIGIN directives within the included file), it is always reset to its original value before processing of the parent file resumes.

The $TTL directive

Every resource record has an associated time-to-live (TTL) field which determines how long it should remain valid for when cached. The zone file syntax allows, but does not require, an explicit TTL to be specified for individual resource records. In the absence of an explicit TTL, a default value is used.

The default TTL was historically supposed to be taken from the MINIMUM field of the SOA record. That meaning was deprecated by RFC 2308, which introduced the $TTL directive as a replacement. For example:

$TTL 86400

specifies that subsequent resource records without an explicit TTL should default to a value of 86400 seconds (1 day).

It is good practice to place a $TTL at the start of each zone file, otherwise the TTL would not have a well-defined value in records which did not set it explicitly. Nameservers vary in their response to this condition. For example, BIND versions 9.0 and 9.1 refuse to load the zone file, whereas later versions default to the SOA MINIMUM value after issuing a warning.

Timing Parameters

Because of its distributed nature, the DNS relies on a number of timing parameters for its efficient and reliable operation. These govern:

Replication is controled by the REFRESH, RETRY and EXPIRE fields of the SOA record:

Caching is controlled by the MINIMUM field of the SOA record, the $TTL directive, and the TTL fields of individual resource records:

The optimum settings for a given zone will represent a balance between ensuring that changes propagate in a timely manner, and avoiding excessive load on nameservers and network infrastructure. If you make use of nameservers operated by third parties, they may additionally place policy constraints on what values are allowed. However, provided that extreme values are avoided, a usable configuration can be obtained for most zones without the need for any fine tuning.

To give an indication of what can be considered low, typical and high values for each of the parameters, the following table shows the ranges that are typically found on the public Internet:

Parameter Low Typical High
REFRESH 300 10800 86400
RETRY 180 3600 7200
EXPIRE 3600 604800 3600000
MINIMUM 60 3600 86400
$TTL 60 3600 86400

This is based on a sample of approximately one million public-facing zones, and shows commonly-used values for each parameter in the vicinity of the 1st, 50th and 99th percentile. Not all of these choices will have been good ones, but the middle column would make a reasonable set of defaults if you have no other preference, and you may want to look closely at any values you find yourself using which are entirely outside the ranges listed.

Note that:

Notes

Use of CNAME records versus multiple address records

It is often necessary to make a choice between using CNAME records, and having multiple address records referring to the same IP address. This is an issue when:

For example, a webserver accessed via CNAME aliases might have zone data of the form:

websites-r-us.example.com.  A 203.0.113.42
www.weyland-yutanti.com.    CNAME websites-r-us.example.com.
www.cyberdyne-systems.com.  CNAME websites-r-us.example.com.
www.tyrell-corporation.com. CNAME websites-r-us.example.com.

whereas with separate address records this would become:

websites-r-us.example.com.  A 203.0.113.42
www.weyland-yutanti.com.    A 203.0.113.42
www.cyberdyne-systems.com.  A 203.0.113.42
www.tyrell-corporation.com. A 203.0.113.42

Both methods are equally valid so far as the DNS specification is concerned. It is true that RFC 1034 contains a description of how CNAME records can be used to represent the condition where a host has a single canonical name together with one or more aliases. However, as RFC 2181 makes clear, this does not imply that hosts are constrained to have a single canonical name. The choice is therefore a matter of style and/or expediency rather than correctness.

Advantages of using CNAME records include the following:

These should be set against the following drawbacks:

Neither solution is capable of full adherance to the “Don’t Repeat Yourself” principle, however use of CNAME records comes significantly closer to doing so, and would be the author’s preference where there is a free choice. MX and NS records can be handled by having them point to the single canonical name for the host as opposed to the alias. There is no reason why aliases cannot still be provided for use by end-users of the DNS, for example:

gelmir.example.com. A     198.51.100.12
mail.example.com.   CNAME gelmir.example.com.
example.com.        MX    10 gelmir.example.com.

Use of multiple PTR records in reverse zones

Even with maximal use of CNAME aliases, it is not always feasible to avoid having address records that refer to the same IP address. That raises the question of how the corresponding reverse zone should be configured. The choice is between:

The position taken by the DNS specification turns on similar points of interpretation to those which govern address records referring to the same IP address. RFC 1035 states that PTR records in reverse zones should refer back to the primary domain names of the corresponding hosts, however RFC 2181 directly addresses the question of whether multiple PTR records are permissible, and states very clearly that they are.

Whilst this leaves little scope for challenging the validity of multiple PTR records, it has not prevented subsequent authors from questioning whether it is ever desirable to make use of that freedom. Several negative consequences have been identified:

It could perhaps be argued that the first issue is a deficiency of the software rather than the zone data, however when both of the standard POSIX functions for performing reverse lookups (getnamebyaddr and getnameinfo) are constrained by their interface from returning more than a single result, it is hardly surprising that the behaviour is widespread.

The second issue can be dealt simply by configuring the nameserver to return the records in fixed order. The third issue is not a problem for small numbers of PTR records, but illustrates very clearly why a general policy which allows them to multiply is not going to be scalable. A server could conceivably have thousands of address records that refer to it, and it is difficult to see how a policy of matching these with pointer records could in any way be a good idea.

For these reasons the author would normally recommend against having multiple PTR records for the same domain name, however if they are found to be necessary then negative consequences can be minimised by ensuring that they are returned in a fixed order.

Further reading