Chapter 4. Setting Up BIND

“It seems very pretty,” she said when she had finished it, “but it’s rather hard to understand!” (You see she didn’t like to confess, even to herself, that she couldn’t make it out at all.) “Somehow it seems to fill my head with ideas—only I don’t exactly know what they are!”

If you have been diligently reading each chapter of this book, you’re probably anxious to get a nameserver running. This chapter is for you. Let’s set up a couple of nameservers. Others of you may have read the table of contents and skipped directly to this chapter. (Shame on you!) If you are one of those people, be aware that we may use concepts from earlier chapters and expect you to understand them already.

There are several factors that influence how you should set up your nameservers. The biggest is what sort of access you have to the Internet: complete access (e.g., you can FTP to ftp://ftp.rs.internic.net), limited access (restricted by a security firewall), or no access at all. This chapter assumes you have complete access. We’ll discuss the other cases in Chapter 11.

In this chapter, we set up two nameservers for a few fictitious zones as an example for you to follow in setting up your own zones. We cover the topics in this chapter in enough detail to get your first two nameservers running. Subsequent chapters fill in the holes and go into greater depth. If you already have your nameservers running, skim through this chapter to familiarize yourself with the terms we use or just to verify that you didn’t miss something when you set up your servers.

Our Zone

Our fictitious zone serves a college. Movie University studies all aspects of the film industry and researches novel ways to (legally) distribute films. One of our most promising projects involves research into using IP as a film distribution medium. After visiting our registrar’s web site, we have decided on the domain name movie.edu. A recent grant has enabled us to connect to the Internet.

Movie U. currently has two Ethernets, and we have plans to add another network or two. The Ethernets have network numbers 192.249.249/24 and 192.253.253/24. A portion of our host table contains the following entries:

127.0.0.1      localhost

# These are our main machines

192.249.249.2  shrek.movie.edu shrek
192.249.249.3  toystory.movie.edu toystory toys
192.249.249.4  monsters-inc.movie.edu monsters-inc mi

# These machines are in horror(ible) shape and will be replaced
# soon.

192.253.253.2  misery.movie.edu misery
192.253.253.3  shining.movie.edu shining
192.253.253.4  carrie.movie.edu carrie

# A wormhole is a fictitious phenomenon that instantly transports
# space travelers over long distances and is not known to be
# stable.  The only difference between wormholes and routers is
# that routers don't transport packets as instantly—especially
# ours.

192.249.249.1  wormhole.movie.edu wormhole wh wh249
192.253.253.1  wormhole.movie.edu wormhole wh wh253

And the network is pictured in Figure 4-1.

The Movie University network
Figure 4-1. The Movie University network

Setting Up Zone Data

Our first step in setting up the Movie U. nameservers is to translate the host table into equivalent DNS zone data. The DNS version of the data has multiple files. One file maps all the hostnames to addresses. Other files map the addresses back to hostnames. The name-to-address lookup is sometimes called forward mapping, and the address-to-name lookup, reverse mapping. Each network has its own file for reverse-mapping data.

As a convention in this book, a file that maps hostnames to addresses is called db.DOMAIN. For movie.edu, this file is called db.movie.edu. The files mapping addresses to hostnames are called db.ADDR, where ADDR is the network number without trailing zeros or the specification of a netmask. In our example, the files are called db.192.249.249 and db.192.253.253; there’s one for each network. (The db is short for database.) We’ll refer to the collection of db.DOMAIN and db.ADDR files as zone datafiles. There are a few other zone datafiles: db.cache and db.127.0.0. These files are overhead. Each nameserver must have them, and they are more or less the same for each server.

To tie all the zone datafiles together, a nameserver needs a configuration file; for BIND versions 8 and 9, it is usually called named.conf. The format of the zone datafiles is common to all DNS implementations: it’s called the master file format. The format of the configuration files, on the other hand, is specific to the nameserver implementation—in this case, BIND.

The Zone Datafiles

Most entries in zone datafiles are called DNS resource records. DNS lookups are case-insensitive, so you can enter names in your zone datafiles in uppercase, lowercase, or mixed case. We tend to use all lowercase. However, even though lookups are case-insensitive, case is preserved. That way, if you add records for titanic.movie.edu to your zone data, people looking up titanic.movie.edu will find the records, but with a capital “T” in the domain name.

Resource records must start in the first column of a line. The resource records in the example files in this book do start in the first column, but they may look indented because of the way the book is formatted. In the DNS RFCs, the examples present the resource records in a certain order. Most people have chosen to follow that order, as we have here, but the order is not a requirement. The order of resource records in the zone datafiles is as follows:

SOA record

Indicates authority for this zone

NS record

Lists a nameserver for this zone

Other records

Data about hosts in this zone

Of the other records, this chapter covers:

A

Name-to-address mapping

PTR

Address-to-name mapping

CNAME

Canonical name (for aliases)

Those of you who have some experience with the master file format will no doubt look at our data and say to yourselves, “It would have been shorter to specify it this other way . . . .” We’re not using abbreviations or shortcuts in our zone data, at least not initially, so that you’ll understand the full syntax of each resource record. Once you understand the long version, we’ll go back and “tighten up” the files.

Comments

The zone datafiles are easier to read if they contain comments and blank lines. Comments start with a semicolon and finish at the end of the line. As you might guess, the nameserver ignores comments and blank lines.

Setting the Zone’s Default TTL

Before we start writing our zone datafile, we have to find out what version of BIND we’re running. (To find out your version, use named -v. If yours doesn’t recognize -v, it’s probably older than BIND 8.2.) The version makes a difference because how you set the default time to live for a zone changed in BIND 8.2. Prior to BIND 8.2, the last field in the SOA record set the default TTL for a zone. But just before BIND 8.2 came out, RFC 2308 was published, which changed the meaning of the final field in the SOA record to the negative caching TTL. This is how long a remote nameserver can cache negative responses about the zone, answers that say that a particular domain name or the type of data sought for a particular domain name doesn’t exist.

So how do you set a default TTL for a zone in BIND 8.2 and later? With the new $TTL control statement. $TTL specifies the time to live for all records in the file that follow the statement (but precede any other $TTL statements) and don’t have an explicit TTL.

The nameserver supplies this TTL in query responses, allowing other servers to cache the data for the TTL interval. If your data doesn’t change much, you might consider using a default TTL of several days. One week is about the longest value that makes sense. You can use a value as short as a few minutes, but we don’t recommend a TTL of zero because of the amount of DNS traffic it causes.

Since we’re running a new version of BIND, we need to set a default TTL for our zones with a $TTL statement. Three hours seems about right to us, so we start our zone datafiles with:

$TTL 3h

If you’re running a nameserver older than BIND 8.2, don’t try adding a $TTL statement: the nameserver won’t understand it and will treat it as a syntax error.

SOA Records

The next entry in each of these files is the start of authority resource record. The SOA record indicates that this nameserver is the best source of information for the data within this zone. Our nameserver is authoritative for the zone movie.edu because of the SOA record. An SOA record is required in each db.DOMAIN and db.ADDR file. There can be one, and only one, SOA record in a zone datafile.

We added the following SOA record to the db.movie.edu file:

movie.edu. IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

The name movie.edu. must start in the first column of the file. Make sure the name ends with a trailing dot, as ours does here, or you’ll be surprised at the result! (We’ll explain later in this chapter.)

The IN stands for Internet. This is one class of data; other classes exist, but none of them is currently in widespread use. Our examples use only the IN class. The class field is optional. If the class is omitted, the nameserver determines the class from the statement in the configuration file that instructs it to read this file. We’ll cover this later in the chapter, too.

The first name after SOA (toystory.movie.edu .) is the name of the primary nameserver for the movie.edu zone. The second name (al.movie.edu.) is the mail address of the person in charge of the zone if you replace the first “.” with an “@”. Often you’ll see root, postmaster, or hostmaster as the email address. Nameservers won’t use this address; it’s meant for human consumption. If you have a problem with a zone, you can send a message to the listed email address. BIND provides another resource record type, RP (responsible person), for this purpose, too. The RP record is discussed in Chapter 7.

The parentheses allow the SOA record to span more than one line. Most of the fields within the parentheses of the SOA record are for use by slave nameservers and are discussed when we introduce slave nameservers later in this chapter. For now, assume these are reasonable values.

We add similar SOA records to the beginning of the db.192.249.249 and db.192.253.253 files. In these files, we change the first name in the SOA record from movie.edu. to the name of the appropriate in-addr.arpa zone: 249.249.192.in-addr.arpa. and 253.253.192.in-addr.arpa., respectively.

NS Records

The next entries we add to each file are NS (nameserver) resource records. We add one NS record for each nameserver authoritative for our zone. Here are the NS records from the db.movie.edu file:

movie.edu.  IN NS  toystory.movie.edu.
movie.edu.  IN NS  wormhole.movie.edu.

These records indicate that there are two nameservers for the zone movie.edu. The nameservers are on the hosts toystory.movie.edu and wormhole.movie.edu . Multi-homed hosts, such as wormhole.movie.edu , are excellent choices for nameservers because they are well-connected; in other words, they are directly accessible by hosts on more than one network and are closely monitored. We’ll cover more on where to place your nameservers in Chapter 8.

As with the SOA record, we add NS records to the db.192.249.249 and db.192.253.253 files, too.

Address and Alias Records

Next, we create the name-to-address mappings. We add the following resource records to the db.movie.edu file:

;
; Host addresses
;
localhost.movie.edu.      IN A     127.0.0.1
shrek.movie.edu.          IN A     192.249.249.2
toystory.movie.edu.       IN A     192.249.249.3
monsters-inc.movie.edu.   IN A     192.249.249.4
misery.movie.edu.         IN A     192.253.253.2
shining.movie.edu.        IN A     192.253.253.3
carrie.movie.edu.         IN A     192.253.253.4
;
; Multi-homed hosts
;
wormhole.movie.edu.       IN A     192.249.249.1
wormhole.movie.edu.       IN A     192.253.253.1
;
; Aliases
;
toys.movie.edu.           IN CNAME 

toystory.movie.edu.
mi.movie.edu.             IN CNAME monsters-inc.movie.edu.
wh.movie.edu.             IN CNAME wormhole.movie.edu.
wh249.movie.edu.          IN A     192.249.249.1
wh253.movie.edu.          IN A     192.253.253.1

The first two blocks are probably not a surprise. The A stands for address, and each resource record maps a name to an address. wormhole.movie.edu is a multihomed host. It has two addresses associated with its name and therefore two address records. Unlike host-table lookups, a DNS lookup can return more than one address for a name; a lookup of wormhole.movie.edu returns two. If the requestor and nameserver are on the same network, some nameservers place the “closest” address first in the response for better performance. This feature is called address sorting and is covered in Chapter 10. If address sorting does not apply, the addresses are rotated between queries so subsequent responses list them in a different order. This feature is called round robin and is also covered in more detail in Chapter 10.

The third block has the host-table aliases. For the first three aliases, we created CNAME (canonical name) resource records. However, we created address records for the other two aliases (more on this in a moment). A CNAME record maps an alias to its canonical name. The nameserver handles CNAME records differently from the way aliases are handled in the host table. When a nameserver looks up a name and finds a CNAME record, it replaces the name with the canonical name and looks up the new name. For example, when the nameserver looks up wh.movie.edu, it finds a CNAME record pointing to wormhole.movie.edu . It then looks up wormhole.movie.edu and returns both addresses.

There is one thing to remember about aliases like toys.movie.edu: they should never appear on the right side of a resource record. Stated differently, you should always use the canonical name (e.g., toystory.movie.edu ) in the data portion of the resource record. Notice that the NS records we just created use the canonical name.

The final two entries solve a special problem. Suppose you have a multihomed host, such as wormhole.movie.edu , and you want to check one of the interfaces. One common troubleshooting technique is to ping the interface to verify that it is responding. If you ping the name wormhole.movie.edu , the nameserver returns both addresses for the name. ping uses the first address in the list. But which address is first?

With the host table, we choose the address we want by using either wh249.movie.edu or wh253.movie.edu; each name refers to one of the host’s addresses. To provide an equivalent capability with DNS, we don’t make wh249.movie.edu and wh253.movie.edu into aliases (CNAME records). That results in both addresses for wormhole.movie.edu being returned when the alias is looked up. Instead, we use address records. Now, to check the operation of the 192.253.253.1 interface on wormhole.movie.edu , we ping wh253.movie.edu because it refers to only one address. The same applies to wh249.movie.edu.

To state this as a general rule: if a host is multihomed (has more than one network interface), create an address (A) record for each alias unique to one address and then create a CNAME record for each alias common to all the addresses.

Now, don’t tell your users about names like wh249.movie.edu and wh253.movie.edu. Those names are meant for system-administration purposes only. If users learn to use names such as wh249.movie.edu, they’ll be confused when the name doesn’t work for them in such places as .rhosts files. That’s because these places need the name that results from looking up the address: the canonical name, wormhole.movie.edu .

Since we use A (address) records for the wh249.movie.edu and wh253.movie.edu aliases, you might ask, “Is it okay to use address records instead of CNAME records in all cases?” Well, using address records instead of CNAME records doesn’t cause problems with most applications because most applications care only about finding IP addresses. There is one application—sendmail—whose behavior changes, though. sendmail usually replaces aliases in mail headers with their canonical names; this canonicalization happens only if the names in the mail header have CNAME data associated with them. If you don’t use CNAME records for aliases, your sendmail will have to understand all the possible aliases your host might be known by, which will require extra sendmail configuration on your part.

In addition to the problem with sendmail, users might be confused when they try to figure out the canonical name to enter in their .rhosts file. Looking up a name that has CNAME data leads them to the canonical name, whereas address data won’t. In this case, users should instead be looking up the IP address to get the canonical name, as rlogind does, but users like these never seem to be on systems we administer.

PTR Records

Next, we create the address-to-name mappings. The file db.192.249.249 maps addresses to hostnames for the 192.249.249/24 network. The DNS resource records used for this mapping are PTR (pointer) records. There is one record for each network interface on this network. (Recall that addresses are looked up as names in DNS. The address is reversed and in-addr.arpa is appended.)

Here are the PTR records we added for network 192.249.249/24:

1.249.249.192.in-addr.arpa.  IN PTR wormhole.movie.edu.
2.249.249.192.in-addr.arpa.  IN PTR shrek.movie.edu.
3.249.249.192.in-addr.arpa.  IN PTR toystory.movie.edu.
4.249.249.192.in-addr.arpa.  IN PTR monsters-inc.movie.edu.

There are a couple of things you should notice about this data. First, addresses should point to only a single name: the canonical name. Thus, 192.249.249.1 maps to wormhole.movie.edu , not to wh249.movie.edu. You can create two PTR records, one for wormhole.movie.edu and one for wh249.movie.edu, but most software is not prepared to see more than one name for an address. Second, even though wormhole.movie.edu has two addresses, you see only one of them here. That’s because this file shows only addresses on the network 192.249.249/24, and wormhole.movie.edu has only one address on that network.

We created similar data for the 192.253.253/24 network.

The Completed Zone Datafiles

Now that we’ve explained the various resource records in the zone datafiles, we’ll show you what they look like with all the data in one place. Again, the actual order of these resource records does not matter.

Here are the contents of the file db.movie.edu:

$TTL 3h
movie.edu. IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

;
; Name servers
;
movie.edu.  IN NS  toystory.movie.edu.
movie.edu.  IN NS  wormhole.movie.edu.

;
; Addresses for the canonical names
;
localhost.movie.edu.      IN A     127.0.0.1
shrek.movie.edu.          IN A     192.249.249.2
toystory.movie.edu.       IN A     192.249.249.3
monsters-inc.movie.edu.   IN A     192.249.249.4
misery.movie.edu.         IN A     192.253.253.2
shining.movie.edu.        IN A     192.253.253.3
carrie.movie.edu.         IN A     192.253.253.4
wormhole.movie.edu.       IN A     192.249.249.1
wormhole.movie.edu.       IN A     192.253.253.1

;
; Aliases
;
toys.movie.edu.       IN CNAME toystory.movie.edu.
mi.movie.edu.         IN CNAME monsters-inc.movie.edu.
wh.movie.edu.         IN CNAME wormhole.movie.edu.

;
; Interface specific names
;
wh249.movie.edu.      IN A     192.249.249.1
wh253.movie.edu.      IN A     192.253.253.1

Here are the contents of the file db.192.249.249:

$TTL 3h
249.249.192.in-addr.arpa. IN SOA toystory.movie.edu. al.movie.edu.(
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

;
; Name servers
;
249.249.192.in-addr.arpa.  IN NS  toystory.movie.edu.
249.249.192.in-addr.arpa.  IN NS  wormhole.movie.edu.

;
; Addresses point to canonical name
;
1.249.249.192.in-addr.arpa.  IN PTR wormhole.movie.edu.
2.249.249.192.in-addr.arpa.  IN PTR shrek.movie.edu.
3.249.249.192.in-addr.arpa.  IN PTR toystory.movie.edu.
4.249.249.192.in-addr.arpa.  IN PTR monsters-inc.movie.edu.

And here are the contents of the file db.192.253.253:

$TTL 3h
253.253.192.in-addr.arpa. IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour
;
; Name servers
;
253.253.192.in-addr.arpa.  IN NS  toystory.movie.edu.
253.253.192.in-addr.arpa.  IN NS  wormhole.movie.edu.

;
; Addresses point to canonical name
;
1.253.253.192.in-addr.arpa.  IN PTR wormhole.movie.edu.
2.253.253.192.in-addr.arpa.  IN PTR misery.movie.edu.
3.253.253.192.in-addr.arpa.  IN PTR shining.movie.edu.
4.253.253.192.in-addr.arpa.  IN PTR carrie.movie.edu.

The Loopback Address

A nameserver needs one additional db.ADDR file to cover the loopback network: the special address that hosts use to direct traffic to themselves. This network is (almost) always 127.0.0/24, and the host number is (almost) always 127.0.0.1. Therefore, the name of this file is db.127.0.0. No surprise here; it looks like the other db.ADDR files.

Here are the contents of the file db.127.0.0:

$TTL 3h
0.0.127.in-addr.arpa. IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

0.0.127.in-addr.arpa.  IN NS  toystory.movie.edu.
0.0.127.in-addr.arpa.  IN NS  wormhole.movie.edu.

1.0.0.127.in-addr.arpa.  IN PTR localhost.

Why do nameservers need this silly little file? Think about it for a second. No one was given responsibility for network 127.0.0/24, yet systems use it for a loopback address. Since no one has direct responsibility, everyone who uses it is responsible for it individually. You could omit this file, and your nameserver would operate. However, a lookup of 127.0.0.1 might fail because the root nameserver contacted wasn’t itself configured to map 127.0.0.1 to a name. To prevent surprises, you should provide the mapping yourself.

The Root Hints Data

Besides your local information, the nameserver also needs to know where the nameservers for the root zone are. You must retrieve this information from the Internet host ftp://ftp.rs.internic.net (198.41.0.6). Use anonymous FTP to retrieve the file db.cache from the domain subdirectory.

;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/db.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:    Jan 29, 2004
;       related version of root zone:   2004012900
;
;
; formerly NS.INTERNIC.NET
;
.                        3600000  IN  NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
;
; formerly NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     192.228.79.201
;
; formerly C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
;
; formerly TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     128.8.10.90
;
; formerly NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
;
; formerly NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
;
; formerly NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
;
; formerly AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     128.63.2.53
;
; formerly NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
;
; operated by VeriSign, Inc.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
;
; operated by RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
;
; operated by ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     198.32.64.12
;
; operated by WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
; End of File

The domain name “.” refers to the root zone. Since the root zone’s nameservers change over time, don’t assume this list is current. Download a new version of db.cache.

How is this file kept up to date? As the network administrator, that’s your responsibility. Some old versions of BIND did update this file periodically. That feature was disabled, though; apparently, it didn’t work as well as the authors had hoped. Sometimes the changed db.cache file is mailed to the bind-users or namedroppers mailing list, which we introduced in Chapter 3. If you are on one of these lists, you are likely to hear about changes.

Can you put data other than root nameserver data in this file? You can, but it won’t be used. Originally, the nameserver installed this data in its cache. However, the use of the file has changed (subtly) though the name “cache file” stuck. The nameserver stores the data it reads from this file in a special place in memory as the root hints. It does not discard the hints if their TTLs drop to zero, as it would with cached data. The nameserver uses the hint data to query the root nameservers for the current list of root nameservers, which it caches. When the cached list of root nameservers times out, the nameserver again uses the hints to get a new list.

Why does the nameserver bother querying a nameserver in the root hints file—probably itself a root nameserver—for a list of root nameservers when it already has a list? Because that nameserver almost certainly knows the current list of root nameservers, while the file may be out of date.

What are the 3600000s for? That’s an explicit time to live for the records in the file. In older versions of this file, this number was 99999999. Since the contents of this file were originally cached, the nameserver needed to know how long to keep those records active. 99999999 seconds was just a very long time; the root nameserver data was to be kept in cache for as long as the server ran. Since the nameserver now stores this data in a special place and doesn’t discard it if it times out, the TTL is unnecessary. But it’s not harmful to have the 3600000s, and it makes for interesting BIND folklore when you pass responsibility to the next nameserver administrator.

Setting Up a BIND Configuration File

Now that we’ve created the zone datafiles, a nameserver must be instructed to read each file. For BIND, the mechanism for pointing the server to its zone datafiles is the configuration file. Up to this point, we’ve been discussing files whose data and format are described in the DNS specifications. The syntax of the configuration file, though, is specific to BIND and is not defined in the DNS RFCs.

The BIND configuration file syntax changed significantly between version 4 and version 8. Mercifully, it didn’t change at all between BIND 8 and BIND 9. BIND 4 came out so long ago that we are not going to cover its configuration here. You’ll have to find an earlier edition of our book (you should be able to find a cheap used copy) if you are still running one of those ancient beasts. In the configuration file, you can use any of three styles of comments: C-style, C++-style, or shell-style:

/* This is a C-style comment */
// This is a C++-style comment
# This is a shell-style comment

Usually, configuration files contain a line indicating the directory in which the zone datafiles are located. The nameserver changes its directory to this location before reading the zone datafiles. This allows the filenames to be specified relative to the current directory instead of as full pathnames. Here’s how a directory line looks in an options statement:

options {
        directory "/var/named";
        // Place additional options here.
};

Tip

Only one options statement is allowed in the configuration file, so any additional options mentioned later in this book must be added along with the directory option.

On a primary server, the configuration file contains one zone statement for each zone datafile to be read. Each line starts with the keyword zone followed by the zone’s domain name and the class (in stands for Internet). The type master indicates this server is a primary nameserver. The last line contains the filename:

zone "movie.edu" in {
      type master;
      file "db.movie.edu";
};

Earlier in this chapter, we mentioned that if you omit the class field from a resource record, the nameserver determines the right class to use from the configuration file. The in in the zone statement sets that class to the Internet class. The in is the default class for a zone statement, so you can leave out the field entirely for Internet class zones.

Here is the configuration file line to read the root hints file:

zone "." in {
        type hint;
        file "db.cache";
};

As mentioned earlier, this file is not for general cache data. It contains only the root nameserver hints.[*]

By default, BIND expects the configuration file to be named /etc/named.conf. The zone datafiles for our example are in the directory /var/named. Which directory you use doesn’t really matter. Just avoid putting the directory in the root filesystem if the root filesystem is short on space, and make sure that the filesystem the directory is in is mounted before the nameserver starts. Here is the complete /etc/named.conf file:

// BIND configuration file

options {
        directory "/var/named";
        // Place additional options here.
};

zone "movie.edu" in {
        type master;
        file "db.movie.edu";
};

zone "249.249.192.in-addr.arpa" in {
        type master;
        file "db.192.249.249";
};

zone "253.253.192.in-addr.arpa" in {
        type master;
        file "db.192.253.253";
};

zone "0.0.127.in-addr.arpa" in {
        type master;
        file "db.127.0.0";
};

zone "." in {
        type hint;
        file "db.cache";

};

Abbreviations

At this point, we have created all the files necessary for a primary nameserver. Let’s go back and revisit the zone datafiles; there are shortcuts we didn’t use. Unless you see and understand the long form first, though, the short form can look very cryptic. Now that you know the long form and have seen the BIND configuration file, we’ll show you the shortcuts.

Appending Domain Names

The second field of a zone statement specifies a domain name. This domain name is the key to the most useful shortcut. This domain name is the origin of all the data in the zone datafile. The origin is appended to all names in the zone datafile that don’t end in a dot and will be different for each zone datafile because each file describes a different zone.

Since the origin is appended to names, instead of entering shrek.movie.edu’s address in db.movie.edu like this:

shrek.movie.edu.    IN A     192.249.249.2

we could have entered it like this:

shrek    IN A     192.249.249.2

In the db.192.24.249 file, we entered this:

2.249.249.192.in-addr.arpa.  IN PTR shrek.movie.edu.

Because 249.249.192.in-addr.arpa is the origin, we could have entered:

2  IN PTR shrek.movie.edu.

Remember our earlier warning not to omit the trailing dot when using the fully qualified domain names? Suppose you forget the trailing dot. An entry like:

shrek.movie.edu    IN A     192.249.249.2

turns into an entry for shrek.movie.edu.movie.edu, not what you intended at all.

The @ Notation

If a domain name is the same as the origin, the name can be specified as “@”. This is most often seen in the SOA record in the zone datafiles. The SOA records could have been entered this way:

@ IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

Repeat Last Name

If a resource record name (that starts in the first column) is a space or tab, then the name from the last resource record is used. You use this if there are multiple resource records for a name. Here’s an example in which there are two address records for one name:

wormhole   IN A     192.249.249.1
           IN A     192.253.253.1

In the second address record, the name wormhole is implied. You can use this shortcut even if the resource records are of different types.

The Shortened Zone Datafiles

Now that we have shown you the abbreviations, we’ll repeat the zone datafiles, making use of these shortcuts.

Here are the contents of the file db.movie.edu:

$TTL 3h
;
; Origin added to names not ending
; in a dot: movie.edu
;

@ IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

;
; Name servers (The name '@' is implied)
;
           IN NS  toystory.movie.edu.
           IN NS  wormhole.movie.edu.

;
; Addresses for the canonical names
;
localhost      IN A     127.0.0.1
shrek          IN A     192.249.249.2
toystory       IN A     192.249.249.3
monsters-inc   IN A     192.249.249.4
misery         IN A     192.253.253.2
shining        IN A     192.253.253.3
carrie         IN A     192.253.253.4

wormhole       IN A     192.249.249.1
               IN A     192.253.253.1

;
; Aliases
;
toys       IN CNAME toystory
mi         IN CNAME monsters-inc
wh         IN CNAME wormhole

;
; Interface specific names
;
wh249      IN A     192.249.249.1
wh253      IN A     192.253.253.1

Here are the contents of the file db.192.249.249:

$TTL 3h
;
; Origin added to names not ending
; in a dot: 249.249.192.in-addr.arpa
;

@ IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

;
; Name servers (The name '@' is implied)
;
   IN NS  toystory.movie.edu.
   IN NS  wormhole.movie.edu.

;
; Addresses point to canonical names
;
1  IN PTR wormhole.movie.edu.
2  IN PTR shrek.movie.edu.
3  IN PTR toystory.movie.edu.
4  IN PTR monsters-inc.movie.edu.

Here are the contents of the file db.192.253.253:

$TTL 3h
;
; Origin added to names not ending
; in a dot: 253.253.192.in-addr.arpa
;

@ IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

;
; Name servers (The name '@' is implied)
;
   IN NS  toystory.movie.edu.
   IN NS  wormhole.movie.edu.

;
; Addresses point to canonical names
;
1  IN PTR wormhole.movie.edu.
2  IN PTR misery.movie.edu.
3  IN PTR shining.movie.edu.
4  IN PTR carrie.movie.edu.

Here are the contents of the file db.127.0.0:

$TTL 3h
@ IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

   IN NS  toystory.movie.edu.
   IN NS  wormhole.movie.edu.

1  IN PTR localhost.

While looking at the new db.movie.edu file, you may notice that we could have removed movie.edu from the hostnames of the SOA and NS records like this:

@ IN SOA toystory al (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 day

  IN NS  toystory
  IN NS  wormhole

You can’t do this in the other zone datafiles because their origins are different. In db.movie.edu, we leave these names as fully qualified domain names so that the NS and SOA records are exactly the same for all the zone datafiles.

Hostname Checking

If your nameserver is BIND 4.9.4 or newer (and most are), you have to pay extra attention to how your hosts are named. Starting with Version 4.9.4, BIND checks hostnames for conformance to RFC 952. If a hostname does not conform, BIND considers it a syntax error.

Before you panic, you need to know that this checking applies only to names that are considered hostnames. Remember, resource records have a name field and a data field—for example:

<name>      <class>  <type>  <data>
toystory    IN       A       192.249.249.3

Hostnames are in the name fields of A (address) and MX (covered in Chapter 5) records. Hostnames are also in the data fields of SOA and NS records. CNAMEs do not have to conform to the host-naming rules because they can point to names that are not hostnames.

Let’s look at the host-naming rules. Hostnames are allowed to contain alphabetic characters and numeric characters in each label. The following are valid hostnames:

ID4            IN A 192.249.249.10
postmanring2x  IN A 192.249.249.11

A hyphen is allowed if it is in the middle of a label:

fx-gateway     IN A 192.249.249.12

Warning

Underscores are not allowed in hostnames.

Names that are not hostnames can consist of any printable ASCII character.

If a resource record data field calls for a mail address (as in SOA records), the first label, since it is not a hostname, can contain any printable character, but the rest of the labels must follow the hostname syntax just described. For example, a mail address has the following syntax:

<ASCII-characters>.<hostname-characters>

For example, if your mail address is , you can use it in an SOA record even with the underscore. Remember, in a mail address you replace the “@” with a “.”, like this:

movie.edu. IN SOA toystory.movie.edu. key_grip.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

This extra level of checking can cause dramatic problems at sites that upgrade from a liberal version of BIND to a conservative one, especially sites that have standardized on hostnames containing an underscore. If you need to postpone changing names until later (you will still change them, right?), this feature can be toned down to produce warning messages instead of errors or to simply ignore that the names are illegal. The following configuration file statement turns the errors into warning messages:

options {
        check-names master warn;
};

The warning messages are logged with syslog, which we’ll explain shortly. The following configuration file statement ignores the errors entirely:

options {
        check-names master ignore;
};

If the nonconforming names came from a zone that you back up (and have no control over), then add a similar statement that specifies slave instead of master:

options {
        check-names slave ignore;
};

And if the names come in responses to queries and not in zone transfers, specify response instead:

options {
        check-names response ignore;
};

Here are BIND’s defaults:

options {
        check-names master fail;
        check-names slave warn;
        check-names response ignore;
};

Name checking can also be specified on a per-zone basis, in which case it overrides name-checking behavior specified in the options statement for this particular zone:

zone "movie.edu" in {
        type master;
        file "db.movie.edu";
        check-names fail;
};

Tip

The options line contains three fields (check-names master fail), whereas the zone line check contains only two fields (check-names fail). This is because the zone line already specifies the context (the zone named in the zone statement).

Tools

Wouldn’t it be handy to have a tool to translate your host table into master file format? There is such a beast, written in Perl: h2n, a host-table-to-master-file converter. You can use h2n to create your zone datafiles the first time and then maintain your data manually. Or you can use h2n over and over again. As you’ve seen, the host table’s format is much simpler to understand and modify correctly than the master file format. So, you could maintain /etc/hosts and rerun h2n to update your zone datafiles after each modification.

If you plan to use h2n, you might as well start with it, because it uses /etc/hosts—not your hand-crafted zone data—to generate the new zone datafiles. We could have saved ourselves a lot of work by generating the sample zone datafiles in this chapter with the following:

%h2n -d movie.edu -s toystory -s shrek \
-n 192.249.249 -n 192.253.253 \
-u al.movie.edu

(To generate a BIND 4 configuration file, add -v 4 to the option list.)

The -d and -n options specify the domain name of your forward-mapping zone and your network numbers. You’ll notice that the names of the zone datafiles are derived from these options. The -s options list the authoritative nameservers for the zones to use in the NS records. The -u (user) is the email address in the SOA record. We cover h2n in more detail in Chapter 7, after we’ve covered how DNS affects email.

BIND 9 Tools

If you are running BIND 9, you have handy new tools to help maintain your nameserver files: named-checkconf and named-checkzone. These tools reside in /usr/local/sbin. As you might guess, named-checkconf checks the configuration file for syntax errors, and named-checkzone checks a zone file for syntax errors.

First, run named-checkconf, which checks /etc/named.conf by default:

%named-checkconf

If you have an error, named-checkconf displays an error message, such as this one:

/etc/named.conf:14: zone '.': missing 'file' entry

If there are no errors, you won’t see any output.

Next, run named-checkzone for each of your zone files:

%named-checkzone movie.edu db.movie.edu
zone movie.edu/IN: loaded serial 4
OK

As you can see, everything is okay, and the current serial number is 4.

Running a Primary Nameserver

Now that you’ve created your zone datafiles, you are ready to start a couple of nameservers. You’ll need to set up two nameservers: a primary nameserver and a slave nameserver. Before you start a nameserver, though, make sure that the syslog daemon is running. If the nameserver reads the configuration file and zone datafiles and sees an error, it logs a message to the syslog daemon. If the error is bad enough, the nameserver exits. If you’ve run the BIND 9 named-checkconf and named-checkzone, you should be all set, but check for syslog errors anyway, just to be safe.

Starting Up the Nameserver

At this point, we assume the machine you are running on has the BIND nameserver and the support tool nslookup installed. Check the named manual page to find the directory the nameserver executable is in and verify that the executable is on your system. On BSD systems, the nameserver started its life in /etc, but may have migrated to /usr/sbin. Other places to look for named are /usr/etc/in.named and /usr/sbin/in.named. The following descriptions assume that the nameserver is in /usr/sbin.

To start up the nameserver, you must become root. The nameserver listens for queries on a reserved port, so it requires root privileges. The first time you run it, start the nameserver from the command line to test that it is operating correctly. Later, we’ll show you how to start up the nameserver automatically when your system boots.

The following command starts the nameserver. We ran it on the host toystory.movie.edu .

#/usr/sbin/named

This command assumes that your configuration file is called /etc/named.conf. You can put your configuration file elsewhere, but then you have to tell the nameserver where it is using the -c command-line option:

#/usr/sbin/named -c conf-file

Check for Syslog Errors

The first thing to do after starting your nameserver is to check the syslog file for error messages. If you are not familiar with syslog, look at the syslog.conf manual page for a description of the syslog configuration file or the syslogd manual page for a description of the syslog daemon. The nameserver logs messages with facility daemon under the name named. You might be able to find where syslog messages are logged by looking for the daemon facility in /etc/syslog.conf:

%grep daemon /etc/syslog.conf
*.err;kern.debug;daemon,auth.notice /var/adm/messages

On this host, the nameserver syslog messages are logged to /var/adm/messages, and syslog saves only those that are at severity LOG_NOTICE or higher. Some useful messages are sent at severity LOG_INFO; you might like to see some of these. You can decide if you want to change the log level after reading Chapter 7, where we cover syslog messages in more detail.

When the nameserver starts, it logs a starting message:

%grep named /var/adm/messages
Jan 10 20:48:32 toystory named[3221]: starting BIND 9.3.2 -c named.boot

The starting message is not an error message, but there might be other messages with it that are error messages. The most common errors are syntax errors in the zone datafiles or configuration file. For example, if you forget the resource record type in an address record:

shrek  IN  192.249.249.2

you’ll see the following syslog error message:

Jan 10 20:48:32 toystory named[3221]: db.movie.edu:24: Unknown RR type:
                192.249.249.2

Or, if you misspell the word “zone” in /etc/named.conf:

zne "movie.edu" in {

you’ll see the following syslog error message:

Mar 22 20:14:21 toystory named[1477]: /etc/named.conf:10:
                unknown option 'zne'

If BIND finds a name that doesn’t conform to RFC 952, you’ll see the following syslog error message:

Jul 24 20:56:26 toystory named[1496]: db.movie.edu:33: a_b.movie.edu: bad
                            owner name

If you have a syntax error, check the line numbers mentioned in the syslog error message to see if you can figure out the problem. You’ve seen what the zone datafiles are supposed to look like; that should be enough to figure out most simple syntax errors. Otherwise, you’ll have to go through Appendix A to see the gory syntactic details of all the resource records. If you can fix the syntax error, do so and then reload the nameserver with ndc (BIND 8) or rndc (BIND 9), the name daemon controller:

#ndc reload

so that it rereads the zone datafiles.[*] You’ll see more information in Chapter 7 on using ndc and rndc to control the nameserver.

Testing Your Setup with nslookup

If you have set up your local zones correctly, and your connection to the Internet is up, you should be able to look up a local and a remote domain name. We’ll now step you through the lookups with nslookup. There is a whole chapter in this book on nslookup (Chapter 12), but we cover it in enough detail here to do basic nameserver testing.

Set the local domain name

Before running nslookup, you need to set the host’s local domain name. With this configured, you can look up a name like carrie instead of having to spell out carrie.movie.edu ; the system adds the domain name movie.edu for you.

There are two ways to set the local domain name: hostname(1) or /etc/resolv.conf. Some people say that, in practice, more sites set the local domain in /etc/resolv.conf. You can use either. Throughout the book, we assume the local domain name comes from hostname(1).

Create a file called /etc/resolv.conf with the following line starting in the first column (substitute your local domain name for movie.edu):

domain movie.edu

Or, set hostname(1) to a domain name. On the host toystory, we set hostname(1) to toystory.movie.edu . Don’t add a trailing dot to the name.

Look up a local domain name

nslookup can be used to look up any type of resource record, and it can be directed to query any nameserver. By default, it looks up A (address) records using the first nameserver specified in resolv.conf. (Without a nameserver specified in resolv.conf, the resolver defaults to querying the local nameserver.) To look up a host’s address with nslookup, run nslookup with the host’s domain name as the only argument. A lookup of a local domain name should return almost instantly.

We ran nslookup to look up carrie :

%nslookup carrie
Server: toystory.movie.edu
Address: 192.249.249.3

Name:    carrie.movie.edu
Address: 192.253.253.4

If looking up a local domain name works, your local nameserver has been configured properly for your forward-mapping zone. If the lookup fails, you’ll see something like this:

*** toystory.movie.edu can't find carrie: Non-existent domain

This means that carrie is not in your zone data. Check your zone datafile; you didn’t set your local domain name in hostname(1), or some nameserver error occurred (though you should have caught the error when you checked the syslog messages).

Look up a local address

When nslookup is given an address to look up, it knows to make a PTR query instead of an address query. We ran nslookup to look up carrie’s address:

%nslookup 192.253.253.4
Server: toystory.movie.edu
Address: 192.249.249.3

Name:    carrie.movie.edu
Address: 192.253.253.4

If looking up an address works, your local nameserver has been configured properly for your in-addr.arpa (reverse-mapping) zones. If the lookup fails, you’ll see the same error messages as when you looked up a domain name.

Look up a remote domain name

The next step is to try using the local nameserver to look up a remote domain name, such as ftp://ftp.rs.internic.net or another system you know of on the Internet. This command may not return as quickly as the last one. If nslookup fails to get a response from your nameserver, it waits a little longer than a minute before giving up:

%nslookup ftp.rs.internic.net
Server: toystory.movie.edu
Address: 192.249.249.3

Name:      ftp.rs.internic.net
Addresses: 198.41.0.6

If this works, your nameserver knows where the root nameservers are and how to contact them to find information about domain names in zones other than your own. If it fails, either you forgot to configure the root hints file (and a syslog message will show up), or the network is broken somewhere and you can’t reach the nameservers for the remote zone. Try a different remote domain name.

If these first lookups succeeded, congratulations! You have a primary nameserver up and running. At this point, you are ready to start configuring your slave nameserver.

One more test

While you’re testing, though, run one more test. Check whether your parent zone’s nameservers have properly delegated to your domain. If your parent required you to have your two nameservers running before delegating your zones, skip ahead to the next section.

This test takes two steps. First, you’ll need to find the IP address of one of your parent’s nameservers. Next, you’ll query your parent’s nameserver to check the NS records (the delegation information) for one of your zones.

Here’s step one: find the IP address of your parent’s nameservers. To do this, ask your nameserver to find the NS records for your parent’s zone. You will use nslookup again, but you will add -type=ns to tell nslookup to query for nameserver records.

Here’s an example. Suppose we are setting up the hp.com zone, and we need to find out the nameservers for com, our parent.

%nslookup -type=ns com.
Server: toystory.movie.edu
Address: 192.249.249.3#53

Non-authoritative answer:
com     nameserver = i.gtld-servers.net
com     nameserver = j.gtld-servers.net
com     nameserver = k.gtld-servers.net
com     nameserver = l.gtld-servers.net
com     nameserver = m.gtld-servers.net
com     nameserver = a.gtld-servers.net
com     nameserver = b.gtld-servers.net
com     nameserver = c.gtld-servers.net
com     nameserver = d.gtld-servers.net
com     nameserver = e.gtld-servers.net
com     nameserver = f.gtld-servers.net
com     nameserver = g.gtld-servers.net
com     nameserver = h.gtld-servers.net

a.gtld-servers.net      internet address = 192.5.6.30
a.gtld-servers.net      AAAA IPv6 address = 2001:503:a83e::2:30
b.gtld-servers.net      internet address = 192.33.14.30
b.gtld-servers.net      AAAA IPv6 address = 2001:503:231d::2:30
c.gtld-servers.net      internet address = 192.26.92.30
d.gtld-servers.net      internet address = 192.31.80.30
e.gtld-servers.net      internet address = 192.12.94.30
f.gtld-servers.net      internet address = 192.35.51.30
g.gtld-servers.net      internet address = 192.42.93.30
h.gtld-servers.net      internet address = 192.54.112.30
i.gtld-servers.net      internet address = 192.43.172.30
j.gtld-servers.net      internet address = 192.48.79.30
k.gtld-servers.net      internet address = 192.52.178.30
l.gtld-servers.net      internet address = 192.41.162.30
m.gtld-servers.net      internet address = 192.55.83.30

Next, you need to query one of your parent’s nameservers for the NS records for your zone. Again, you’ll use nslookup with -type=ns, but this time you’ll also add -norecurse to tell nslookup not to ask the nameserver to recursively look up the data for you. Also, you need to query your parent’s nameserver directly, instead of sending the query to your own nameserver. (Your nameserver has NS records for your zone, but that’s not what you need to check.) To query your parent’s nameserver instead of your own, add the name of one of your parent’s nameservers to the end of the nslookup statement. Here’s an example where we queried the com nameserver b.gtld-servers.netfor the NS records for hp.com:

%nslookup -type=ns -norecurse hp.com. b.gtld-servers.net.
Server:  b.gtld-servers.net
Address:  192.33.14.30#53

Non-authoritative answer:
hp.com  nameserver = am1.hp.com
hp.com  nameserver = am3.hp.com
hp.com  nameserver = ap1.hp.com
hp.com  nameserver = eu1.hp.com
hp.com  nameserver = eu2.hp.com
hp.com  nameserver = eu3.hp.com

am1.hp.com      internet address = 15.227.128.
am3.hp.com      internet address = 15.243.160.
ap1.hp.com      internet address = 15.211.128.
eu1.hp.com      internet address = 16.14.64.50
eu2.hp.com      internet address = 16.6.64.50
eu3.hp.com      internet address = 16.8.64.50

Everything has been set up correctly for hp.com, as you might expect.

If your nameserver successfully looked up ftp.rs.internic.net, and it looked up the servers for your parent’s domain, your server is set up correctly, and you can contact the rest of the Internet. If your parent zone’s nameserver does not contain NS records for your zone, your zone is not registered with your parent nameservers. That’s not a problem, at first, because systems within your zones can look up the domain names of other systems both within and outside of your zones. You’ll be able to access the Web and FTP to local and remote systems. But not being registered will shortly become a problem. Hosts outside your zones can’t look up domain names in your zones; you may not be able to send email to friends in remote zones, and you certainly won’t get any responses. To fix this problem, contact the administrators of your parent zones, and have them check the delegation of your zones.

Editing the Startup Files

Once you have confirmed that your nameserver is running properly and can be used from here on, you’ll need to configure it to start automatically and set hostname(1) to a domain name in your system’s startup files (or set up your domain name in /etc/resolv.conf). Check to see if your vendor has already set up the nameserver to start on bootup. You may have to remove comment characters from the startup lines, or the startup file may test to see if /etc/named.conf exists. To look for automatic startup lines, use:

%grep named /etc/*rc*

or, if you have System V-style rc files, use:

%grep named /etc/rc.d/*/S*

If you don’t find anything, add lines like the following to the appropriate startup file somewhere after your network interfaces are initialized by ifconfig:

if test -x /usr/sbin/named -a -f /etc/named.conf
then
        echo "Starting named"
        /usr/sbin/named
fi

You may want to wait to start the nameserver until after the default route is installed or your routing daemon (routed or gated) is started, depending on whether these services need the nameserver or can get by with /etc/hosts.

Find which startup file initializes the hostname and change hostname(1) to a domain name. For example, we changed:

hostname toystory

to:

hostname toystory.movie.edu

Running a Slave Nameserver

You need to set up another nameserver for robustness. You can (and probably will eventually) set up more than two authoritative nameservers for your zones. Two nameservers are the minimum; if you have only one nameserver, and it goes down, no one can look up domain names. A second nameserver splits the load with the first server or handles the whole load if the first server is down. You could set up another primary nameserver, but we don’t recommend it. Instead, set up a slave nameserver. You can always change a slave nameserver to a primary nameserver if you decide to expend the extra effort it takes to run multiple primary nameservers.

How does a server know if it’s the primary or a slave for a zone? The named.conf file tells the nameserver whether it is the primary or a slave on a per-zone basis. The NS records don’t tell us which server is the primary for a zone and which servers are slaves; they only say who the servers are. (Globally, DNS doesn’t care; as far as the actual name resolution goes, slave servers are as good as primary servers.)

What’s the difference between a primary nameserver and a slave nameserver? The crucial difference is where the server gets its data. A primary nameserver reads its data from zone datafiles. A slave nameserver loads its data over the network from another nameserver. This process is called a zone transfer.

A slave nameserver is not limited to loading zones from a primary nameserver; it can also load from another slave server.

The big advantage of slave nameservers is that you maintain only one set of zone datafiles for a zone, the ones on the primary nameserver. You don’t have to worry about synchronizing the files among nameservers; the slaves do that for you. The caveat is that a slave does not resynchronize instantly: it polls to see if its zone data is current. The polling interval is one of those numbers in the SOA record that we haven’t explained yet. (BIND versions 8 and 9 support mechanisms to speed up the distribution of zone data, which we’ll describe later.)

A slave nameserver doesn’t need to retrieve all its zone data over the network; the overhead files, db.cache and db.127.0.0, are the same as on a primary, so keep a local copy on the slave. That means that a slave nameserver is a primary for 0.0.127.in-addr.arpa. Well, you could make it a slave for 0.0.127.in-addr.arpa, but that zone’s data never changes; it may as well be a primary.

Setup

To set up your slave nameserver, create a directory for the zone datafiles on the slave nameserver host (e.g., /var/named) and copy over the files /etc/named.conf, db.cache, and db.127.0.0:

#rcp /etc/named.conf host:/etc
# rcp db.cache db.127.0.0 host:db-file-directory

You must modify /etc/named.conf on the slave nameserver. Change every occurrence of master to slave except for the 0.0.127.in-addr.arpa zone, and add a masters line with the IP address of the primary nameserver, which will act as the slave’s master for these zones.

If the original configuration file line was:

zone "movie.edu" in {
      type master;
      file "db.movie.edu";
};

then the modified line looks like this:

zone "movie.edu" in {
      type slave;
      file "bak.movie.edu";
      masters { 192.249.249.3; };
};

This tells the nameserver that it is a slave for the zone movie.edu and that it should track the version of this zone kept on the nameserver at 192.249.249.3. The slave nameserver keeps a backup copy of this zone in the local file bak.movie.edu.

For Movie U., we set up our slave nameserver on wormhole.movie.edu . Recall that the configuration file on toystory.movie.edu (the primary) looks like this:

options {
        directory "/var/named";
};

zone "movie.edu" in {
        type master;
        file "db.movie.edu";
};

zone "249.249.192.in-addr.arpa" in {
        type master;
        file "db.192.249.249";
};

zone "253.253.192.in-addr.arpa" in {
        type master;
        file "db.192.253.253";
};

zone "0.0.127.in-addr.arpa" in {
        type master;
        file "db.127.0.0";
};

zone "." in {
        type hint;
        file "db.cache";

};

We copy /etc/named.conf, db.cache, and db.127.0.0 to wormhole.movie.edu , and edit the configuration file as previously described. The configuration file on wormhole.movie.edu now looks like this:

options {
        directory "/var/named";
};

zone "movie.edu" in {
        type slave;
        file "bak.movie.edu";
        masters { 192.249.249.3; };
};

zone "249.249.192.in-addr.arpa" in {
        type slave;
        file "bak.192.249.249";
        masters { 192.249.249.3; };
};

zone "253.253.192.in-addr.arpa" in {
        type slave;
        file "bak.192.253.253";
        masters { 192.249.249.3; };
};

zone "0.0.127.in-addr.arpa" in {
        type master;
        file "db.127.0.0";
};

zone "." in {
        type hint;
        file "db.cache";
};

This causes the nameserver on wormhole.movie.edu to load movie.edu, 249.249.192.in-addr.arpa, and 253.253.192.in-addr.arpa over the network from the nameserver at 192.249.249.3 (toystory.movie.edu ). It also saves a backup copy of these files in /var/named. You may find it handy to isolate the backup zone datafiles in a subdirectory. We name them with a unique prefix such as bak, since, on rare occasions, we may have to delete all the backup files manually. It’s also helpful to be able to tell at a glance that they’re backup zone datafiles so that we’re not tempted to edit them. We’ll cover more on backup files later.

Now start up the slave nameserver. Check for error messages in the syslog file as you did for the primary server. As on the primary, the command to start up a nameserver is:

#/usr/sbin/named

One extra check to make on the slave that you didn’t have to make on the primary is to see that the nameserver created the backup files. Shortly after we started our slave nameserver on wormhole.movie.edu , we saw bak.movie.edu, bak.192.249.249, and bak.192.253.253 appear in the /var/named directory. This means the slave has successfully loaded these zones from the primary and saved a backup copy.

To complete setting up your slave nameserver, try looking up the same domain names you looked up after you started the primary server. This time, you must run nslookup on the host running the slave nameserver so that the slave server is queried. If your slave is working fine, add the proper lines to your system startup files so that the slave nameserver is started when your system boots up, and hostname(1) is set to a domain name.

Backup Files

Slave nameservers are not required to save a backup copy of the zone data. If there is a backup copy, the slave server reads it on startup and later checks with the master server to see if the master server has a newer copy instead of loading a new copy of the zone immediately. If the master server has a newer copy, the slave pulls it over and saves it in the backup file.

Why save a backup copy? Suppose the master nameserver is down when the slave starts up. The slave will be unable to transfer the zone and therefore won’t function as a nameserver for that zone until the master server is up. With a backup copy, the slave has zone data, although it might be slightly out of date. Since the slave does not have to rely on the master server always being up, it’s a more robust setup.

To run without a backup copy, remove the file line in the configuration file. However, we recommend configuring all your slave nameservers to save backup copies. There is very little extra cost to saving a backup zone datafile, but it will cost you dearly if you get caught without a backup file when you need it most.

SOA Values

Remember this SOA record?

movie.edu. IN SOA toystory.movie.edu. al.movie.edu. (
                          1        ; Serial
                          3h       ; Refresh after 3 hours
                          1h       ; Retry after 1 hour
                          1w       ; Expire after 1 week
                          1h )     ; Negative caching TTL of 1 hour

We never explained what the values between the parentheses were for.

The serial number applies to all the data within the zone. We chose to start our serial number at 1, a logical place to start. But many people find it more useful to use the date in the serial number instead, like 2005012301. This format is YYYYMMDDNN, where YYYY is the year, MM is the month, DD is the day, and NN is a count of how many times the zone data was modified that day. These fields won’t work in any other order because no other order gives a value that always increases as the date changes. This is critical: whatever format you choose, it’s important that the serial number always increase when you update your zone data.

When a slave nameserver contacts a master server for zone data, it first asks for the serial number on the data. If the slave’s serial number for the zone is lower than the master server’s, the slave’s zone data is out of date. In this case, the slave pulls a new copy of the zone. If a slave starts up, and there is no backup file to read, it will always load the zone. As you might guess, when you modify the zone datafiles on the primary, you must increment the serial number. Updating your zone datafiles is covered in Chapter 7.

The next four fields specify various time intervals, in seconds by default:

refresh

The refresh interval tells a slave for the zone how often to check that the data for this zone is up to date. To give you an idea of the system load this feature causes, a slave makes one SOA query per zone per refresh interval. The value we chose, three hours, is reasonably aggressive. Most users will tolerate a delay of half a working day for things like zone data to propagate when they are waiting for their new workstation to become operational. If you provide one-day service for your site, you could consider raising this value to eight hours. If your zone data doesn’t change very often or if all of your slaves are spread over long distances (as the root nameservers are), consider a value that is even longer, say 24 hours.

retry

If the slave fails to reach the master nameserver after the refresh interval (the host could be down), it starts trying to connect every retry seconds. Normally, the retry interval is shorter than the refresh interval, but it doesn’t have to be.

expire

If the slave fails to contact the master nameserver for expire seconds, the slave expires the zone. Expiring the zone means that the slave stops giving out answers about the zone because the zone data is too old to be useful. Essentially, this field says that at some point, the data is so old that giving out no data is better than giving out stale data. Expire times on the order of a week are common—longer (up to a month) if you frequently have problems reaching your updating source. The expiration time should always be much larger than the retry and refresh intervals; if the expire time is smaller than the refresh interval, your slaves will expire the zone before trying to load new data.

negative caching TTL

TTL stands for time to live. This value applies to all negative responses from the nameservers authoritative for the zone.

Tip

On versions of BIND before BIND 8.2, the last field in the SOA record is both the default time to live and the negative caching time to live for the zone.

Those of you who have read earlier versions of this book may have noticed the change in the format we used for the SOA record’s numeric fields. Once upon a time, BIND understood units of seconds only for the four fields we just described. (Consequently, a whole generation of administrators know that there are 604,800 seconds in a week.) Now, with all but the oldest BIND nameservers (4.8.3), you can specify units besides seconds for these fields and as arguments to the TTL control statement, as was shown earlier in this chapter. For example, you can specify a three-hour refresh interval with 3h, 180m, or even 2h60m. You can also use d for days and w for weeks.

The right values for your SOA record depend on the needs of your site. In general, longer times cause less load on your nameservers and can delay the propagation of changes; shorter times increase the load on your nameservers and speed up the propagation of changes. The values we use in this book should work well for most sites. RFC 1537 recommends the following values for top-level nameservers:

Refresh        24 hours
Retry           2 hours
Expire         30 days
Default TTL     4 days

There is one implementation feature you should be aware of. Older versions (pre-4.8.3) of BIND slaves stop answering queries during a zone load. As a result, BIND was modified to spread out the zone loads, reducing the periods of unavailability. So, even if you set a low refresh interval, your slaves may not check as often as you request. BIND attempts a certain number of zone loads and then waits 15 minutes before trying another batch.

Now that we’ve told you all about how slave nameservers poll to keep their data up to date, BIND 8 and 9 change how zone data propagates! The polling feature is still there, but BIND 8 and 9 add a notification when zone data changes. If both your primary server and your slaves run BIND 8 or 9, the primary notifies the slave that a zone has changed within 15 minutes of loading a new copy of that zone. The notification causes the slave server to shorten the refresh interval and attempt to load the zone immediately. We’ll discuss this more in Chapter 10.

Multiple Master Servers

Are there other ways to make your slave nameserver’s configuration more robust? Yes—you can specify up to 10 IP addresses of master servers. In the configuration file, add them after the first IP address and separate them with semicolons:

zone "movie.edu" in {
        type slave;
        file "bak.movie.edu";
        masters { 192.249.249.3; 192.249.249.4; };
};

Or with BIND 9.3 and later, you can give a name to the list of IP addresses for your masters, and then refer to the name. This saves repeating the IP addresses for each zone. Here’s an example:

masters "movie-masters" {
        192.249.249.3; 192.249.249.4;
};

zone "movie.edu" in {
        type slave;
        file "bak.movie.edu";
        masters { movie-masters; };
};

The slave queries the master server at each IP address in the order listed until it gets a response. Through BIND 8.1.2, the slave always transferred the zone from the first master nameserver to respond if that master had a higher serial number. The slave tried successive master servers only if the previous master didn’t respond. From BIND 8.2 on, however, the slave actually queries all the master nameservers listed and transfers the zone from the one with the highest serial number. If multiple master servers tie for the highest serial number, the slave transfers the zone from the first of those masters in the list.

The original intent of this feature was to allow you to list all the IP addresses of the host running the primary nameserver for the zone if that host were multihomed. However, since there is no check to determine whether the contacted server is a primary or a slave, you can list the IP addresses of hosts running slave servers for the zone if that makes sense for your setup. That way, if the first master server is down or unreachable, your slave can transfer the zone from another master nameserver.

Adding More Zones

Now that you have your nameservers running, you might want to support more zones. What needs to be done? Nothing special, really. All you need to do is add more zone statements to your configuration file. You can even make your primary a slave server for some zones and make your slave server primary for some zones. (You may have already noticed that your slave server is primary for 0.0.127.in-addr.arpa.)

At this point, it’s useful to repeat something we said earlier in this book. Calling a given nameserver a primary nameserver or a slave nameserver is a little silly. Nameservers can be—and usually are—authoritative for more than one zone. A nameserver can be a primary for one zone and a slave for another. Most nameservers, however, are either primary for most of the zones they load or slave for most of the zones they load. So if we call a particular nameserver a primary or a slave, we mean that it’s the primary or a slave for most of the zones it loads.

What’s Next?

In this chapter, we showed you how to create nameserver zone datafiles by translating /etc/hosts to equivalent nameserver data, and how to set up a primary and a slave nameserver. There is more work to do to complete setting up your local zones, however: you need to modify your zone data for email and configure the other hosts in your zone to use your nameservers. You may also need to start up more nameservers. These topics are covered in the next few chapters.



[*] Actually, BIND 9 has a built-in hints zone, so you don’t need to include a zone statement for the hints zone in named.conf. However, including one doesn’t hurt, and it gives us the willies not to see one in the configuration file, so we include one anyway.

[*] For a BIND 9 nameserver, you’d need to use rndc, but we haven’t shown you how to configure that yet. Skip ahead to Chapter 7 if you’d like to see how that’s done. ndc works without much configuration, though.

Get DNS and BIND, 5th Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.