Chapter 10. Advanced Features

“What’s the use of their having names,” the Gnat said, “if they won’t answer to them?”

The latest BIND nameservers, versions 8.4.7 and 9.3.2, have lots of new features. Some of the most prominent introductions are support for dynamic updates, asynchronous zone change notification (called “NOTIFY” for short), and incremental zone transfer. Of the rest, the most important are related to security: they let you tell your nameserver whom to answer queries from, whom to serve zone transfers to, and whom to permit dynamic updates from. Many of the security features aren’t necessary inside a corporate network, but the other mechanisms will help out administrators of any nameservers.

In this chapter, we’ll cover these features and suggest how they might come in handy in your DNS infrastructure. (We do save some of the hardcore firewall material ‘til the next chapter, though.)

Address Match Lists and ACLs

Before we introduce the new features, however, we’d better cover address match lists. BIND 8 and 9 use address match lists for nearly every security feature and for some features that aren’t security-related at all.

An address match list is a list (what else?) of terms that specifies one or more IP addresses. The elements in the list can be individual IP addresses, IP prefixes, or a named address match list (more on those shortly).[*] An IP prefix has the format:

network in dotted-octet format/bits in netmask

For example, the network 15.0.0.0 with the network mask 255.0.0.0 (eight contiguous ones) is written 15/8. Traditionally, this would have been thought of as the “class A” network 15. The network consisting of IP addresses 192.168.1.192 through 192.168.1.255, on the other hand, would be written 192.168.1.192/26 (network 192.168.1.192 with the netmask 255.255.255.192, which has 26 contiguous ones). Here’s an address match list comprising those two networks:

15/8; 192.168.1.192/26;

A named address match list is just that: an address match list with a name. To be used within another address match list, a named address match list must have been previously defined in named.conf with an acl statement. The acl statement has a simple syntax:

acl name { address_match_list; };

This just makes the name equivalent to that address match list from now on. Although the name of the statement, acl, suggests “access control list,” you can use the named address match list anywhere an address match list is accepted, including some places that don’t have anything to do with access control.

Whenever you use one or more of the same terms in a few access control lists, it’s a good idea to use an acl statement to associate them with a name. You can then refer to the name in the address match list. For example, let’s call 15/8 what it is: “HP-NET.” And we’ll call 192.168.1.192/26 “internal”:

acl "HP-NET" { 15/8; };

acl "internal" { 192.168.1.192/26; };

Now we can refer to these address match lists by name in other address match lists. This not only cuts down on typing and simplifies managing your address match lists, it makes the resulting named.conf file more readable.

We prudently enclosed the names of our ACLs in quotes to avoid collisions with words BIND reserves for its own use. If you’re sure your ACL names don’t conflict with reserved words, you don’t need the quotes.

There are four predefined named address match lists:

none

No IP addresses

any

All IP addresses

localhost

Any of the IP addresses of the local host (i.e., the one running the nameserver)

localnets

Any of the networks the local host has a network interface on (found by using each network interface’s IP address and using the netmask to mask off the host bits in the address)

DNS Dynamic Update

The world of the Internet—and of TCP/IP networking in general—has become a much more dynamic place. Most large corporations use DHCP to control IP address assignment. Nearly all ISPs assign addresses to dial-up and cable modem customers using DHCP. To keep up, DNS needed to support the dynamic addition and deletion of records. RFC 2136 introduced this mechanism, called DNS Dynamic Update.

BIND 8 and 9 support the dynamic update facility described in RFC 2136. This permits authorized updaters to add and delete resource records from a zone for which a nameserver is authoritative. An updater can find the authoritative nameservers for a zone by retrieving the zone’s NS records. If the nameserver receiving an authorized update message is not the primary master for the zone, it forwards the update “upstream” to its master server, a process referred to as update forwarding. If this next server, in turn, is a slave for the zone, it also forwards the update upstream. Only the primary nameserver for a zone, after all, has a writable copy of the zone data; all the slaves get their copies of the zone data from the primary, either directly or indirectly (through other slaves). Once the primary has processed the dynamic update and modified the zone, the slaves can get a new copy of it via zone transfers.

Dynamic update permits more than the simple addition and deletion of records. Updaters can add or delete individual resource records, delete RRsets (a set of resource records with the same domain name, class, and type, such as all the addresses of www.movie.edu), or even delete all records associated with a given domain name. An update can also stipulate that certain records exist or not exist in the zone as a prerequisite to the update’s taking effect. For example, an update can add the address record:

armageddon.fx.movie.edu.  300  IN  A  192.253.253.15

only if the domain name armageddon.fx.movie.edu isn’t currently being used or only if armageddon.fx.movie.edu currently has no address records.

Tip

A note on update forwarding: BIND nameservers didn’t implement update forwarding before 9.1.0, so it’s particularly important when using BIND nameservers older than 9.1.0 that you make sure the update is sent directly to the primary nameserver for the zone you’re trying to update. You can do this by ensuring that the primary nameserver for the zone is listed in the MNAME field of the zone’s SOA record. Most dynamic update routines use the MNAME field as a hint to tell them which authoritative nameserver to send the update to.

For the most part, dynamic update functionality is used by programs such as DHCP servers that assign IP addresses automatically to computers and then need to register the resulting name-to-address and address-to-name mappings. Some of these programs use the new ns_update() resolver routine to create update messages and send them to an authoritative server for the zone that contains the domain name.

It’s also possible to create updates manually with the command-line program nsupdate, which is part of the standard BIND distribution. nsupdate reads one-line commands and translates them into an update message. Commands can be specified on standard input (the default) or in a file, whose name must be given as an argument to nsupdate. Commands not separated by a blank line are incorporated into the same update message, as long as there’s room.

nsupdate understands the following commands:

prereq yxrrset domain name type [rdata]

Makes the existence of an RRset of type type owned by domain name a prerequisite for performing the update specified in successive update commands. If rdata is specified, it must also match.

prereq nxrrset domain name type

Makes the nonexistence of an RRset of type type owned by domain name a prerequisite for performing the update specified.

prereq yxdomain domain name

Makes the existence of the specified domain name a prerequisite for performing the update.

prereq nxdomain domain name

Makes the nonexistence of the specified domain name a prerequisite for performing the update.

update delete domain name [type] [rdata]

Deletes the domain name specified or, if type is also specified, deletes the RRset specified or, if rdata is also specified, deletes the record matching domainname, type, and rdata.

update add domain name ttl [class] type rdata

Adds the record specified to the zone. Note that the TTL, in addition to the type and resource record-specific data, must be included, but the class is optional and defaults to IN.

So, for example, the command:

%nsupdate
> prereq nxdomain mib.fx.movie.edu.
> update add mib.fx.movie.edu. 300 A 192.253.253.16
> send

tells the server to add an address for mib.fx.movie.edu only if the domain name does not already exist. Note that BIND 8 versions of nsupdate before 8.4.5 use a blank line as a cue to send the update instead of the send command. Subtle, eh?

The following command checks to see whether mib.fx.movie.edu already has MX records and, if it does, deletes them and adds two in their place:

%nsupdate
> prereq yxrrset mib.fx.movie.edu. MX
> update delete mib.fx.movie.edu. MX
> update add mib.fx.movie.edu. 600 MX 10 mib.fx.movie.edu.
> update add mib.fx.movie.edu. 600 MX 50 postmanrings2x.movie.edu.
> send

As with queries, the nameservers that process dynamic updates answer them with DNS messages that indicate whether the update was successful and, if not, what went wrong. Updates may fail for many reasons: for example, because the nameserver wasn’t actually authoritative for the zone being updated, because a prerequisite wasn’t satisfied, or because the updater wasn’t allowed.

There are some limitations to what you can do with dynamic update: you can’t delete a zone entirely (though you can delete everything in it except the SOA record and one NS record), and you can’t add new zones.

Dynamic Update and Serial Numbers

When a nameserver processes a dynamic update, it’s changing a zone and must increment that zone’s serial number to signal the change to the zone’s slaves. This is done automatically. However, the nameserver doesn’t necessarily increment the serial number for each dynamic update.

BIND 8 nameservers defer updating a zone’s serial number for as long as 5 minutes or 100 updates, whichever comes first. The deferral is intended to deal with a mismatch between a nameserver’s ability to process dynamic updates and its ability to transfer zones: the latter may take significantly longer for large zones. When the nameserver does finally increment the zone’s serial number, it sends a NOTIFY announcement (described later in this chapter) to tell the zone’s slaves that the serial number has changed.

BIND 9 nameservers update the serial number once for each dynamic update that is processed.

Dynamic Update and Zone Datafiles

Since a dynamic update makes a permanent change to a zone, a record of it needs to be kept on disk. But rewriting a zone datafile each time a record is added to or deleted from the zone can be prohibitively onerous for a nameserver. Writing a zone datafile takes time, and the nameserver could conceivably receive tens or hundreds of dynamic updates each second.

Instead, when they receive dynamic updates, both BIND 8 and 9 nameservers simply append a short record of the update to a logfile.[*] The change takes effect immediately in the copy of the zone the nameservers maintain in memory, of course. But the nameservers can wait and write the entire zone to disk only at a designated interval (hourly, usually). BIND 8 nameservers then delete the logfile because it’s no longer needed. (At that point, the copy of the zone in memory is the same as that on disk.) BIND 9 nameservers, however, leave the logfile because they also use it for incremental zone transfers, which we’ll cover later in this chapter. (BIND 8 nameservers keep incremental zone transfer information in another file.)

On BIND 8 nameservers, the name of the logfile is constructed by appending .log to the name of the zone datafile. On BIND 9 nameservers, the name of the logfile—also called a journal file—is the name of the zone datafile concatenated with .jnl. So when you start using dynamic update, don’t be surprised to see these files appear alongside your zone datafiles: it’s totally normal.

On a BIND 8 nameserver, the logfiles should disappear hourly (though they may reappear very quickly if your nameserver receives lots of updates) as well as when the nameserver exits gracefully. On a BIND 9 nameserver, the logfiles won’t disappear at all. Both nameservers incorporate the record of the changes in the logfile into the zone if the logfile exists when the nameserver starts.

In case you’re interested, BIND 8’s logfiles are human-readable and contain entries like this:

;BIND LOG V8
[DYNAMIC_UPDATE] id 8761 from [192.249.249.3].1148 at 971389102 (named pid 17602):
zone:   origin movie.edu class IN serial 2000010957
update: {add} almostfamous.movie.edu. 600 IN A 192.249.249.215

BIND 9’s logfiles, unfortunately, aren’t human-readable. Well, not to these humans, anyway.

Update Access Control Lists

Given the fearsome control that dynamic updates obviously give an updater over a zone, you clearly need to restrict them, if you use them at all. By default, neither BIND 8 nor BIND 9 nameservers allow dynamic updates to authoritative zones. In order to use dynamic updates, you add an allow-update or update-policy substatement to the zone statement of the zone that you’d like to allow updates to.

allow-update takes an address match list as an argument. The address or addresses matched by the list are the only addresses allowed to update the zone. It’s prudent to make this access control list as restrictive as possible:

zone "fx.movie.edu" {
    type master;
    file "db.fx.movie.edu";
    allow-update { 192.253.253.100; }; // just our DHCP server
};

An updater authorized using allow-update can make any change to the zone: delete any record (except the SOA record) or add any records.

TSIG-Signed Updates

Given that BIND 9.1.0 and later slave nameservers can forward updates, what’s the use of an IP address-based access control list? If the primary nameserver allows updates from its slaves’ addresses, then any forwarded update is allowed, regardless of the original sender. That’s not good.[*]

Well, first, you can control which updates are forwarded. The allow-update-forwarding substatement takes an address match list as an argument. Only updates from IP addresses that match the address match list will be forwarded. So the following zone statement forwards only those updates from the Special Effects Department’s subnet:

zone "fx.movie.edu" {
    type slave;
    file "bak.fx.movie.edu";
    allow-update-forwarding { 192.253.254/24; };
};

Still, when you use update forwarding, you should also use transaction signatures (TSIG)-signed dynamic updates. We won’t cover TSIG in depth until Chapter 11, but all you need to know for now is that TSIG-signed dynamic updates bear the cryptographic signature of the signer. If they’re forwarded, the signature is forwarded with them. The signature, when verified, tells you the name of the key used to sign the update. The name of the key looks like a domain name, and it’s often just the domain name of the host the key is installed on.

With BIND 8.2 and later nameservers, an address match list can include the name of one or more TSIG keys:

zone "fx.movie.edu" {
    type master;
    file "db.fx.movie.edu";
    allow-update { key dhcp-server.fx.movie.edu.; }; // allow only updates
                                                     // signed by the DHCP
                                                     // server's TSIG key
};

This allows an updater who signs an update with the TSIG key dhcp-server.fx.movie.edu to make any change to the fx.movie.edu zone. Unfortunately, there’s no way to further restrict the updater with that TSIG key to a list of source IP addresses.

BIND 9 supports a finer-grained access control mechanism than allow-update, also based on TSIG signatures. This mechanism uses the new update-policy zone substatement. update-policy lets you specify which keys are allowed to update which records in the zone. It’s meaningful only for primary nameservers because the slaves are expected to forward the updates.

The update is specified by the name of the key used to sign it and by the domain name and type of records it attempts to update. update-policy’s syntax looks like the following:

(grant | deny) identity nametype string [types]

grant and deny have the obvious meanings: allow or disallow the specified dynamic update. identity refers to the name of the TSIG key used to sign the update. nametype is one of:

name

Matches when the domain name being updated is the same as the string specified in the string field.

subdomain

Matches when the domain name being updated is a subdomain of (i.e., ends in) the string specified in the string field. (The domain name must still be in the zone, of course.)

wildcard

Matches when the domain name being updated matches the wildcard expression specified in the string field.

self

Matches when the domain name being updated is the same as the name in the identity (not string!) field—that is, when the domain name being updated is the same as the name of the key used to sign the update. If nametype is self, the string field is ignored. And even though it looks redundant (as we’ll see in the example in a moment), you still have to include the string field when using a nametype of self.

string, naturally, is a domain name appropriate to the nametype specified. For example, if you specify wildcard as the nametype, the string field should contain a wildcard label.

The types field is optional and can contain any valid record type (or multiple types, separated by spaces) except NSEC. (ANY is a convenient shorthand for “all types but NSEC.”) If you leave types out, it matches all record types except SOA, NS, RRSIG, and NSEC.

Tip

A note on the precedence of update-policy rules: the first match (not the closest match) in an update-policy substatement is the one that applies to a dynamic update.

So, if the host mummy.fx.movie.edu uses a key called mummy.fx.movie.edu to sign its dynamic updates, we can restrict mummy.fx.movie.edu to updating its own records with the following:

zone "fx.movie.edu" {
    type master;
    file "db.fx.movie.edu";
    update-policy { grant mummy.fx.movie.edu. self mummy.fx.movie.edu.; };
};

or just its own address records with this:

zone "fx.movie.edu" {
    type master;
    file "db.fx.movie.edu";
    update-policy { grant mummy.fx.movie.edu. self mummy.fx.movie.edu. A; };
};

More generally, we can restrict all our clients to updating only their own address records using:

zone "fx.movie.edu" {
    type master;
    file "db.fx.movie.edu";
    update-policy { grant *.fx.movie.edu. self fx.movie.edu. A; };
};

We can allow our DHCP server to use the key dhcp-server.fx.movie.edu to update any A, TXT, and PTR records attached to domain names in fx.movie.edu with:

zone "fx.movie.edu" {
    type master;
    file "db.fx.movie.edu";
    update-policy {
        grant dhcp-server.fx.movie.edu. wildcard *.fx.movie.edu. A TXT PTR;
    };
};

In case you’re wondering, the difference between:

grant dhcp-server.fx.movie.edu. subdomain fx.movie.edu.

and:

grant dhcp-server.fx.movie.edu. wildcard *.fx.movie.edu.

is that the former allows the key dhcp-server.fx.movie.edu to modify records attached to fx.movie.edu (for example, the zone’s NS records) while the latter doesn’t. Since the DHCP server has no business modifying any records attached to the domain name of the zone, the second is the more secure option.

Here’s a more complicated example: to enable all clients to change any records, except SRV records, that are owned by the same domain name as their key name, but to allow matrix.fx.movie.edu to update SRV, A, and CNAME records associated with Active Directory (in the _udp.fx.movie.edu, _tcp.fx.movie.edu, _sites.fx.movie.edu, and _msdcs.fx.movie.edu subdomains), you can use:

zone "fx.movie.edu" {
    type master;
    file "db.fx.movie.edu";
    update-policy {
        grant matrix.fx.movie.edu. subdomain _udp.fx.movie.edu. SRV CNAME A;
        grant matrix.fx.movie.edu. subdomain _tcp.fx.movie.edu. SRV CNAME A;
        grant matrix.fx.movie.edu. subdomain _sites.fx.movie.edu. SRV CNAME A;
        grant matrix.fx.movie.edu. subdomain _msdcs.fx.movie.edu. SRV CNAME A;
        deny *.fx.movie.edu. self *.fx.movie.edu. SRV;
        grant *.fx.movie.edu. self *.fx.movie.edu. ANY;
    };
};

Since the rules in the update-policy substatement are evaluated in the order in which they appear, clients can’t update their SRV records, though they can update any other record types they own.

If you’d like to take advantage of TSIG-signed dynamic updates but don’t have any software that can send them, you can use newer versions of nsupdate; see Chapter 11 for that.

DNS NOTIFY (Zone Change Notification)

Traditionally, BIND slaves have used a polling scheme to determine when they need a zone transfer. The polling interval is called the refresh interval. Other parameters in the zone’s SOA record govern other aspects of the polling mechanism.

But with this polling scheme, it can take up to the refresh interval before a slave detects and transfers new zone data from its master nameserver. That kind of latency can wreak havoc in a dynamically updated environment. Wouldn’t it be nice if the primary nameserver could tell its slave servers when the information in the zone changed? After all, the primary nameserver knows the data has changed; someone reloaded the data or it received and processed a dynamic update. The primary could send notification right after processing the reload or update instead of waiting for the refresh interval to pass.[*]

RFC 1996 proposed a mechanism that would allow primary nameservers to notify their slaves of changes to a zone’s data. BIND 8 and 9 implement this scheme, which is called DNS NOTIFY.

DNS NOTIFY works like this: when a primary nameserver notices that the serial number of a zone has changed, it sends a special announcement to all the slave nameservers for that zone. The primary nameserver determines which servers are the slaves for the zone by looking at the list of NS records in the zone and taking out the record that points to the nameserver listed in the MNAME field of the zone’s SOA record as well as the domain name of the local host.

When does the nameserver notice a change? Restarting a primary nameserver causes it to notify all its slaves as to the current serial number of all of its zones because the primary has no way of knowing whether its zone datafiles were edited before it started. Reloading one or more zones with new serial numbers causes a nameserver to notify the slaves of those zones. And a dynamic update that causes a zone’s serial number to increment also causes notification.

The special NOTIFY announcement is identified by its opcode in the DNS header. The opcode for most queries is QUERY. NOTIFY messages, including announcements and responses, have a special opcode, NOTIFY (duh). Other than that, NOTIFY messages look very much like a response to a query for a zone’s SOA record: they include the SOA record of the zone whose serial number has changed, and the authoritative answer bit is set.

When a slave receives a NOTIFY announcement for a zone from one of its configured master nameservers, it responds with a NOTIFY response. The response tells the master that the slave received the NOTIFY announcement so that the master can stop sending it NOTIFY announcements for the zone. The slave then proceeds just as if the refresh timer for that zone had expired: it queries the master nameserver for the SOA record for the zone that the master claims has changed. If the serial number is higher, the slave transfers the zone.

Why doesn’t the slave simply take the master’s word that the zone has changed? It’s possible that a miscreant could forge NOTIFY announcements to slaves, causing lots of unnecessary zone transfers and amounting to a denial-of-service attack against a master nameserver.

If the slave actually transfers the zone, RFC 1996 says that it should issue its own NOTIFY announcements to the other authoritative nameservers for the zone. The idea is that the primary master may not be able to notify all the slave nameservers for the zone itself because it’s possible some slaves can’t communicate directly with the primary (they use another slave as their master). However, while BIND 8.2.3 and later and all BIND 9 nameservers implement this, earlier versions of BIND 8 don’t. Older BIND 8 slaves don’t send NOTIFY messages unless explicitly configured to do so.

Here’s how that works in practice. On our network, toystory.movie.edu is the primary nameserver for movie.edu, and wormhole.movie.edu and zardoz.movie.edu are slaves, as shown in Figure 10-1.

movie.edu zone transfers
Figure 10-1. movie.edu zone transfers

When we edit and reload or dynamically update movie.edu on toystory.movie.edu , toystory.movie.edu sends NOTIFY announcements to wormhole.movie.edu and zardoz.movie.edu . Both slaves respond to toystory.movie.edu , telling it that they’ve received the notification. They then check to see whether movie.edu’s serial number has incremented and, when they find it has, perform a zone transfer. If wormhole.movie.edu and zardoz.movie.edu are running BIND 8.2.3 or later or BIND 9, after they transfer the new version of the zone, they also send NOTIFY announcements to tell each other about the change. But since wormhole.movie.edu isn’t zardoz.movie.edu ’s master nameserver for movie.edu, and the converse isn’t true either, both slaves just ignore each other’s NOTIFY announcements.

BIND nameservers log information about NOTIFY messages to syslog. Here’s what BIND 8 running on toystory.movie.edu logged after we reloaded movie.edu:

Oct 14 22:56:34 toystory named[18764]: Sent NOTIFY for "movie.edu IN
SOA 2000010958" (movie.edu); 2 NS, 2 A
Oct 14 22:56:34 toystory named[18764]: Received NOTIFY answer (AA) from
192.249.249.1 for "movie.edu IN SOA"
Oct 14 22:56:34 toystory named[18764]: Received NOTIFY answer (AA) from
192.249.249.9 for "movie.edu IN SOA"

The first message shows us the NOTIFY announcement that toystory.movie.edu sent, informing the two slaves (2 NS) that the serial number of movie.edu is now 2000010958. The next two lines show the slave nameservers confirming their receipt of the notification.

A BIND 9 nameserver would have logged just:

Oct 14 22:56:34 toystory named[18764]: zone movie.edu/IN: sending notifies
(serial 2000010958)

Let’s also look at a more complicated zone transfer scheme. In Figure 10-2, a is the primary nameserver for the zone and b’s master server, but b is c’s master server. Moreover, b has two network interfaces.

Complex zone transfer example
Figure 10-2. Complex zone transfer example

In this scenario, a notifies both b and c after the zone is updated. Then b checks to see whether the zone’s serial number has incremented and initiates a zone transfer. However, c ignores a’s NOTIFY announcement because a is not c’s configured master nameserver (b is). If b is running BIND 8.2.3 or later, or BIND 9, or is explicitly configured to notify c, then after b’s zone transfer completes, it sends a NOTIFY announcement to c, which prompts c to check the serial number b holds for the zone. If c is also running BIND 8.2.3 or later or BIND 9, it sends b a NOTIFY announcement after its zone transfer finishes, which b, naturally, ignores.

Note also that if there’s any possibility that c will receive a NOTIFY announcement from b’s other network interface, c must be configured with both network interfaces’ addresses in the zone’s masters substatement, or else c will ignore NOTIFY announcements from the unknown interface.

BIND 4 slave nameservers and other nameservers that don’t support NOTIFY will respond with a Not Implemented (NOTIMP) error. Note that the Microsoft DNS Server does support DNS NOTIFY.

In both BIND 8 and 9, DNS NOTIFY is on by default, but you can turn off NOTIFY globally with the substatement:

options {
    notify no;
};

You can also turn on or off NOTIFY for a particular zone. For example, say we know that all the slave nameservers for our fx.movie.edu zone are running BIND 4 and therefore don’t understand NOTIFY announcements. The zone statement:

zone "fx.movie.edu" {
    type master;
    file "db.fx.movie.edu";
    notify no;
};

avoids sending useless NOTIFY announcements to the slaves for fx.movie.edu. A zone-specific NOTIFY setting overrides any global setting for that zone. Unfortunately, neither BIND 8 nor BIND 9 allows you to turn off NOTIFY announcements on a server-by-server basis.

BIND 8 and 9 even have a provision for adding servers besides those in your zone’s NS records to your “NOTIFY list.” For example, you may have one or more unregistered slave nameservers (described in Chapter 8), and you’d like them to pick up changes to the zone quickly. Or you may have an older BIND 8 slave for the zone that is the master server for another slave and needs to send NOTIFY messages to the slave.

To add a server to your NOTIFY list, use the also-notify substatement of the zone statement:

zone "fx.movie.edu" {
    type slave;
    file "bak.fx.movie.edu";
    notify yes;
    also-notify { 15.255.152.4; }; // This is a BIND 8 slave, which
                                   // must be explicitly configured
                                   // to notify its slave
};

In BIND 8.2.2 and later nameservers, you can specify also-notify as an options substatement as well. This applies to all zones for which NOTIFY is on (and which don’t have their own also-notify substatements).

Beginning in BIND 8.3.2 and 9.1.0, you can specify explicit as an argument to the notify substatement; this suppresses NOTIFY messages to all nameservers except those in the also-notify list. For example, these two substatements tell the nameserver to send NOTIFY messages only to the slave at 192.249.249.20:

options {
    also-notify { 192.249.249.20; };
    notify explicit;
};

You can also use the allow-notify substatement to tell your nameserver to accept NOTIFY messages from nameservers other than just the configured master nameservers for a zone:

options {
    allow-notify { 192.249.249.17; }; // let 192.249.249.17 send NOTIFY msgs
};

As an options substatement, allow-notify affects all slave zones. When specified as a zone substatement, allow-notify overrides any global allow-notify for just that zone.

Incremental Zone Transfer (IXFR)

With dynamic update and NOTIFY, our zones are updated according to the changing state of the network, and those changes quickly propagate to all the authoritative nameservers for those zones. The picture’s complete, right?

Not quite. Imagine you run a large zone that’s dynamically updated with frightening frequency. That’s easy to envision: you might have a big zone to begin with, including thousands of clients, when all of a sudden management decides to implement Active Directory and DHCP. Now each of your clients updates its own address record in the zone, and the Domain Controllers update the records that tell clients which services they run. (There’s much more to come on Active Directory in Chapter 17.)

Each time your primary nameserver receives an update that increments the zone’s serial number, it sends a NOTIFY announcement to its slaves. And each time they receive NOTIFY announcements, the slaves check the serial number of the zone on their master server and, possibly, transfer the zone. If that zone is large, the transfer will take some time; another update could arrive in the interim. Your slaves could be transferring zones in perpetuity! At the very least, your nameservers will spend a lot of time transferring the whole zone when the change to the zone is probably very small (e.g., the addition of a client’s address record).

Incremental zone transfer, or IXFR for short, solves this problem by allowing slave nameservers to tell their master servers which version of a zone they currently hold and to request just the changes to the zone between that version and the current one. This can dramatically reduce the size and duration of a zone transfer.

An incremental zone transfer request has a query type of IXFR instead of AXFR (the type of query that initiates a full zone transfer), and it contains the slave’s current SOA record from the zone in the authority section of the message. When the master nameserver receives an incremental zone transfer request, it looks for the record of the changes to the zone between the slave’s version of the zone and the version the master holds. If that record is missing, the master sends a full zone transfer. Otherwise, it sends just the differences between the versions of the zone.

IXFR Limitations

Sound good? It is! But IXFR has a few limitations that you should know about. First, IXFR didn’t work well until BIND 8.2.3. All BIND 9 nameservers have IXFR implementations that work well and interoperate with BIND 8.2.3.

Next, IXFR traditionally has worked only when you’re modifying your zone data with dynamic updates, not by making manual changes. Dynamic updates leave a record of the changes made to the zone and the serial number changes they correspond to—exactly what a master nameserver needs to send to a slave that requests IXFR. But a nameserver that reloads an entire zone datafile would have to compute the differences between that zone and the previous zone, like doing a diff between the versions. This meant that, to take maximum advantage of IXFR, you needed to modify your zone only by using dynamic update, and never edit the zone datafile by hand.

IXFR from Differences

BIND 9.3.0 introduced support for calculating IXFR responses by comparing a zone datafile with the version of the zone it has in memory. This means that you can now (or again) edit zone datafiles manually. You do have to take precautions, however, to make sure the file you’re editing contains the latest version of the zone and dynamic updates are refused while you’re working on the file. (Dynamic updates could change the in-memory version of the zone so that the file no longer reflected its state.)

To turn on this feature, use the ixfr-from-differences substatement. You can use it within an options or zone statement. Here’s how you would turn on the feature for all zones:

options {
    directory "/var/named";
    ixfr-from-differences yes;
};

To force the nameserver to write a new version of a zone’s datafile and suspend processing of dynamic updates to the zone, use rndc’s new freeze command:

% rndc freeze zone [class [view]]

To tell the nameserver to reread the zone datafile and resume processing of dynamic updates for the zone, use rndc thaw:

% rndc thaw zone [class [view]]

You probably shouldn’t keep a zone frozen for too long, especially if you might be missing important updates.

IXFR Files

BIND 8 nameservers maintain an IXFR log of changes to the zone separate from the dynamic update logfile. Like the dynamic update logfile, the IXFR logfile is updated every time the nameserver receives an update. Unlike the dynamic update logfile, the IXFR logfile is never deleted, though the nameserver can be configured to trim it when it exceeds a particular size. The name of the BIND 8 IXFR logfile, by default, is the name of the zone datafile with .ixfr appended to it.

BIND 9 nameservers use the dynamic update logfile, or journal file, to assemble IXFR responses and to maintain the integrity of the zone. Since a primary nameserver never knows when it may need the record of a particular change to the zone, it doesn’t delete the journal file. A BIND 9 slave saves the journal file even if it receives an AXFR of the zone because it may serve as a master nameserver to one or more slaves, too.

BIND 8 IXFR Configuration

Configuring IXFR in BIND 8 is fairly straightforward. First, you need an options substatement called maintain-ixfr-base on your master nameserver that tells it to maintain IXFR logfiles for all zones—even those the nameserver is a slave for because those in turn may have slaves that want IXFRs:

options {
    directory "/var/named";
    maintain-ixfr-base yes;
};

You then need to tell your slaves to request IXFRs from that master nameserver. You do that with a new server substatement, support-ixfr:

server 192.249.249.3 {
    support-ixfr yes;
};

That’s about it, unless you want to rename the IXFR logfile on the master. That’s done with a new zone statement, ixfr-base:

zone "movie.edu" {
    type master;
    file "db.movie.edu";
    ixfr-base "ixfr.movie.edu";
};

Oh, and you can configure the nameserver to trim the IXFR logfile after it exceeds a particular size:[*]

options {
    directory "/var/named";
    maintain-ixfr-base yes;
    max-ixfr-log-size 1M;     // trim IXFR log to 1 megabyte
};

Once the IXFR logfile exceeds the specified limit by 100 KB, the nameserver trims it back to that size. The 100 KB of “slush” prevents the logfile from reaching the limit and then being trimmed back after each successive update.

Using the many-answers zone transfer format can make zone transfers even more efficient. We’ll cover many-answers zone transfers later in this chapter.

BIND 9 IXFR Configuration

It’s even easier to configure IXFR in a BIND 9 master nameserver because you don’t have to do a thing: it’s on by default. If you need to turn it off for a particular slave server (and you probably won’t because a slave must request an incremental zone transfer), use the provide-ixfr server substatement, which defaults to yes:

server 192.249.249.1 {
    provide-ixfr no;
};

You can also use provide-ixfr as an options substatement, in which case it applies to all slaves that don’t have an explicit provide-ixfr substatement of their own in a server statement.

Since BIND 9 master nameservers send many-answers zone transfers by default, you don’t need any special transfer-format configuration.

More useful is the request-ixfr substatement, which can be used in either an options or a server statement. If you have a mix of IXFR-capable and IXFR-impaired masters, you can tailor your slave’s zone transfer requests to match the capabilities of its masters:

options {
    directory "/var/named";
    request-ixfr no;
};

server 192.249.249.3 {
    request-ixfr yes;     // of our masters, only toystory supports IXFR
};

From BIND 9.3.0 on, BIND 9 nameservers support configuring the maximum size of a journal file with the max-journal-size options substatement.

Forwarding

Certain network connections discourage sending large volumes of traffic off-site, perhaps because it’s a slow link with high delay; a remote office’s satellite connection to the company’s network is an example. In these situations, you’ll want to limit the off-site DNS traffic to the bare minimum. BIND provides a mechanism to do this: forwarders.

Forwarders are also useful if you need to shunt name resolution to a particular nameserver. For example, if only one of the hosts on your network has Internet connectivity, and you run a nameserver on that host, you can configure your other nameservers to use it as a forwarder so that they can look up Internet domain names. (More on this use of forwarders when we discuss firewalls in Chapter 11.)

If you designate one or more servers at your site as forwarders, your nameservers will send all their off-site queries to the forwarders first. The idea is that the forwarders handle all the off-site queries generated at the site, building up a rich cache of information. For any given query in a remote zone, there is a high probability that the forwarder can answer the query from its cache, avoiding the need for the other servers to send queries off-site. You don’t do anything to a nameserver to make it a forwarder; you modify all the other servers at your site to direct their queries through the forwarders.

A primary or slave nameserver’s mode of operation changes slightly when it is configured to use a forwarder. If a resolver requests records that are already in the nameserver’s authoritative data or cached data, the nameserver answers with that information; this part of its operation hasn’t changed. However, if the records aren’t in its database, the nameserver sends the query to a forwarder and waits a short period for an answer before resuming normal operation and starting the iterative name resolution process. This mode of operation is called forward first. What the nameserver is doing differently here is sending a recursive query to the forwarder, expecting it to find the answer. At all other times, the nameserver sends out only nonrecursive queries to other nameservers.

For example, here is the BIND 8 and 9 forwarders substatement for nameservers in movie.edu. Both wormhole.movie.edu and toystory.movie.edu are the site’s forwarders. We add this forwarders substatement to every nameserver’s configuration file except the ones for the forwarders themselves:

options {
    forwarders { 192.249.249.1; 192.249.249.3; };
};

When you use forwarders, try to keep your site configuration simple. You could end up with configurations that are really twisted.

Warning

Avoid chaining your forwarders. Don’t configure nameserver A to forward to server B, and server B to forward to server C (or, worse yet, back to server A). This can cause long resolution delays and creates a brittle configuration, in which the failure of any forwarder in the chain impairs or breaks name resolution.

A More Restricted Nameserver

You may want to restrict your nameservers even further—stopping them from even trying to contact an off-site server if their forwarder is down or doesn’t respond. You can do this by configuring your nameservers to use forward-only mode. A nameserver in forward-only mode is a variation on a nameserver that uses forwarders. It still answers queries from its authoritative data and cached data. However, it relies completely on its forwarders; it doesn’t try to contact other nameservers to find information if the forwarders don’t give it an answer. Here is an example of what the configuration file of a nameserver in forward-only mode would contain:

options {
    forwarders { 192.249.249.1; 192.249.249.3; };
    forward only;
};

If you use forward-only mode, you must have forwarders configured. Otherwise, it doesn’t make sense to have forward-only mode set. If you configure a nameserver in forward-only mode and run a version of BIND older than 8.2.3, you might want to consider including the forwarders’ IP addresses more than once. That would look like:

options {
    forwarders { 192.249.249.1; 192.249.249.3;
        192.249.249.1; 192.249.249.3; };
    forward only;
};

This nameserver contacts each forwarder only once, and it waits a short time for the forwarder to respond. Listing the forwarders multiple times directs the nameserver to retransmit queries to the forwarders and increases the overall length of time that the forward-only nameserver will wait for an answer from forwarders.

Tip

In our experience, forward-only mode actually provides more predictable name resolution than forward-first mode (which is the default). It takes so long for the queries to forwarders to time out that by the time the nameserver starts iterative name resolution, the resolver that sent the original query has often given up already or is on the verge of giving up. The result is that resolvers get inconsistent resolution results: Some queries, which resolve quickly, are answered, but others time out.

Forward Zones

Traditionally, using forwarders has been an all-or-nothing proposition: either you use forwarders to resolve every query your nameserver can’t answer itself, or you don’t use forwarders at all. However, there are some situations in which it would be nice to have more control over forwarding. For example, maybe you’d like to resolve certain domain names using a particular forwarder but resolve other domain names iteratively.

BIND 8.2 introduced a new feature, forward zones, that allows you to configure your nameserver to use forwarders only when looking up certain domain names. (BIND 9’s support for forward zones was added in 9.1.0.) For example, you can configure your nameserver to shunt all queries for domain names ending in pixar.com to a pair of Pixar’s nameservers:

zone "pixar.com" {
    type forward;
    forwarders { 138.72.10.20; 138.72.30.28; };
};

Why would you ever configure this explicitly rather than letting your nameserver follow delegation from the com nameservers to the pixar.com nameservers? Well, imagine that you have a private connection to Pixar, and you’re told to use a special set of nameservers, reachable only from your network, to resolve all pixar.com domain names.

Even though forwarding rules are specified in the zone statement, they apply to all domain names that end in the domain name specified. That is, regardless of whether the domain name you’re looking up, foo.bar.pixar.com , is in the pixar.com zone, the rule applies to it because it ends in pixar.com (or is in the pixar.com domain, if you prefer).

There’s another variety of forward zone, in a way the opposite of the kind we just showed you. These allow you to specify which queries don’t get forwarded. Therefore, it applies only to nameservers with forwarders specified in the options statement, which would normally apply to all queries.

These forward zones are configured using a zone statement, but not of type forward. Instead, these are normal zones—master, slave, or stub—with a forwarders substatement. To “undo” the forwarding configured in the options statement, we specify an empty list of forwarders:

options {
    directory "/var/named";
    forwarders { 192.249.249.3; 192.249.249.1; };
};

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

Wait a minute—why would you need to disable forwarding in a zone you’re authoritative for? Wouldn’t you just answer the query and not use a forwarder?

Remember, the forwarding rules apply to queries for all domain names that end in the domain name of the zone. So this forwarding rule really applies only to queries for domain names in delegated subdomains of movie.edu, such as fx.movie.edu. Without the forwarding rule, this nameserver would have forwarded a query for matrix.fx.movie.edu to the nameservers at 192.249.249.3 and 192.249.249.1. With the forwarding rule, it instead uses the subdomain’s NS records from the movie.edu zone and queries the fx.movie.edu nameservers directly.

Forward zones are enormously helpful in dealing with Internet firewalls, as we’ll see in Chapter 11.

Views

BIND 9 introduced views, another mechanism that’s very useful in firewalled environments. Views allow you to present one nameserver configuration to one community of hosts and a different configuration to another community. This is particularly handy if you’re running a nameserver on a host that receives queries from both your internal hosts and hosts on the Internet (we’ll cover this in the next chapter).

If you don’t configure any views, BIND 9 automatically creates a single, implicit view that it shows to all hosts that query it. To explicitly create a view, you use the view statement, which takes the name of the view as an argument:

view "internal" {
};

Although the name of the view can be just about anything, using a descriptive name is always a good idea. And while quoting the name of the view isn’t necessary, it’s helpful to do so to avoid conflict with words BIND reserves for its own use (“internal,” for example). The view statement must come after any options statement, though not necessarily right after it.

You can select which hosts “see” a particular view using the match-clients view substatement, which takes an address match list as an argument. If you don’t specify a community of hosts with match-clients, the view applies to all hosts.

Let’s say we’re setting up a special view of the fx.movie.edu zone on our nameservers that we want only the Special Effects department to see. We could create a view visible only to hosts on our subnet:

view "internal" {
    match-clients { 192.253.254/24; };
};

If you want to make that a little more readable, you can use an acl statement:

acl "fx-subnet" { 192.253.254/24; };

view "internal" {
    match-clients { "fx-subnet"; };
};

Just be sure you define the ACL outside the view because you can’t use acl statements inside views.

You can also specify who sees a view using the match-destinations view substatement, which, like match-clients, takes an address match list as an argument. match-destinations applies to nameservers with multiple IP addresses: clients querying one of a server’s IP address, might see one view, while those querying another address see a different view. match-clients and match-destinations can be used in combination, too, to select queries from a particular client and those sent to a particular address. There’s even a match-recursive-only Boolean substatement that will let you select only recursive or nonrecursive queries.

What can you put inside a view statement? Almost anything (well, except for acl statements). You can define zones with zone statements, describe remote nameservers with server statements, and configure TSIG keys with key statements. You can use most options substatements within a view, but if you do, don’t enclose them in an options statement; just use them “raw” in the view statement:

acl "fx-subnet" { 192.253.254/24; };

view "internal" {
    match-clients { "fx-subnet"; };
    recursion yes;  // turn recursion on for this view
                    // (it's off globally, in the options statement)
};

Any configuration option you specify within a view overrides the like-named global option (e.g., one in the options statement) for hosts that match match-clients.

For a complete list of what’s supported inside the view statement on the version of BIND 9 you run (because it changes from release to release), see the file doc/misc/options in the BIND distribution.

To give you an idea of the power of views, here’s the Special Effects lab’s full named.conf file:

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

acl "fx-subnet" { 192.253.254/24; };

view "internal" {  // internal view 
 of our zones

    match-clients { "fx-subnet"; };

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

    zone "254.253.192.in-addr.arpa" {
        type master;
        file "db.192.253.254";
    };
};

view "external" {  // view of our zones for the rest of the world

    match-clients { any; };  // implicit
    recursion no;            // outside of our subnet, they shouldn't be
                             // requesting recursion
    zone "fx.movie.edu" {
        type master;
        file "db.fx.movie.edu.external";  // external zone datafile
    };

    zone "254.253.192.in-addr.arpa" {
        type master;
        file "db.192.253.254.external";   // external zone datafile
    };
};

Notice that each view has an fx.movie.edu and a 254.253.192.in-addr.arpa zone, but the zone datafiles are different in the internal and external views. This allows us to show the outside world a different “face” than we see internally.

The order of the view statements is important because the first view that a host’s IP address matches is the one that dictates what it sees. If the external view were listed first in the configuration file, it would occlude the internal view because the external view matches all addresses.

One last note on views (before we use them in the next chapter, anyway): if you configure even one view statement, all your zone statements must appear within explicit views.

Round-Robin Load Distribution

Nameservers released since BIND 4.9 have formalized some load distribution functionality that has existed in patches to BIND for some time. Bryan Beecher wrote patches to BIND 4.8.3 to implement what he called “shuffle address records.” These were address records of a special type that the nameserver rotated between responses. For example, if the domain name foo.bar.baz had three “shuffled” IP addresses, 192.168.1.1, 192.168.1.2, and 192.168.1.3, an appropriately patched nameserver would give them out first in the order:

192.168.1.1 192.168.1.2 192.168.1.3

then in the order:

192.168.1.2 192.168.1.3 192.168.1.1

and then in the order:

192.168.1.3 192.168.1.1 192.168.1.2

before starting all over with the first order and repeating the rotation ad infinitum.

This functionality is enormously useful if you have a number of equivalent network resources, such as mirrored FTP servers, web servers, or terminal servers, and you’d like to spread the load among them. You establish one domain name that refers to the group of resources and configure clients to access that domain name, and the nameserver distributes requests among the IP addresses you list.

BIND 8 and 9 do away with the shuffle address record as a separate record type, subject to special handling. Instead, a modern nameserver rotates addresses for any domain name that has more than one A record. (In fact, the nameserver will rotate any type of record as long as a given domain name has more than one of them.)[*] So the records:

foo.bar.baz.    60    IN    A    192.168.1.1
foo.bar.baz.    60    IN    A    192.168.1.2
foo.bar.baz.    60    IN    A    192.168.1.3

accomplish on a BIND 8 or 9 nameserver just what the shuffle address records did on a patched 4.8.3 server. The BIND documentation calls this process round-robin.

It’s a good idea to reduce the records’ time to live, too, as we did in this example. This ensures that if the addresses are cached on an intermediate nameserver that doesn’t support round-robin, they’ll time out of the cache quickly. If the intermediate nameserver looks up the name again, your authoritative nameserver can round-robin the addresses again.

Note that this is really load distribution, not load balancing, because the nameserver gives out the addresses in a completely deterministic way without regard to the actual load or capacity of the servers servicing the requests. In our example, the server at address 192.168.1.3 could be a 486DX33 running Linux and the other two servers HP9000 Superdomes, and the Linux box would still get a third of the queries. Listing a higher-capacity server’s address multiple times won’t help because BIND eliminates duplicate records.

Multiple CNAMEs

Back in the heyday of BIND 4 nameservers, some folks set up round-robin using multiple CNAME records instead of multiple address records:

foo1.bar.baz.   60   IN   A   192.168.1.1
foo2.bar.baz.   60   IN   A   192.168.1.2
foo3.bar.baz.   60   IN   A   192.168.1.3
foo.bar.baz.    60   IN   CNAME   foo1.bar.baz.
foo.bar.baz.    60   IN   CNAME   foo2.bar.baz.
foo.bar.baz.    60   IN   CNAME   foo3.bar.baz.

This probably looks odd to those of you who are used to our harping on the evils of mixing anything with a CNAME record. But BIND 4 nameservers didn’t recognize this as the configuration error it is and simply returned the CNAME records for foo.bar.baz in round-robin order.[*]

BIND 8 nameservers, on the other hand, are more vigilant and catch this error. You can, however, explicitly configure them to allow multiple CNAME records for a single domain name with:

options {
    multiple-cnames yes;
};

Not that we think you should, however.

BIND 9 nameservers don’t notice the multiple CNAME problem until version 9.1.0. BIND versions from 9.1.0 on detect the problem but don’t give you the option of allowing multiple CNAME records with the multiple-cnames statement. We think that’s the right approach: attaching multiple CNAME records to a single domain name is a violation of the DNS standards (in particular RFC 2181). Don’t do it.

The rrset-order Substatement

There are certain times when you’d rather the nameserver didn’t use round-robin. For example, maybe you’d like to designate one web server as a backup to another. To do this, the nameserver should always return the backup’s address after the primary web server’s address. But you can’t do that with round-robin; it’ll just rotate the order of the addresses in successive responses.

BIND 8.2 and later nameservers and BIND 9.3.0 and later nameservers allow you to turn off round-robin for certain domain names and types of records. For example, if we want to ensure that the address records for www.movie.edu are always returned in the same order, we’d use this rrset-order substatement:

options {
    rrset-order {
        class IN type A name "www.movie.edu" order fixed;
    };
};

We should probably lower the TTL on www.movie.edu’s address records, too, so a nameserver that cached the records wouldn’t round-robin them for long.

The class, type, and name settings determine which records the specified order applies to. The class defaults to IN, type to ANY, and name to *—in other words, any records. So the statement:

options {
    rrset-order {
        order random;
    };
};

applies a random order to all records returned by the nameserver. The name setting may contain a wildcard as its leftmost label, as in:

options {
    rrset-order {
        type A name "*.movie.edu" order cyclic;
    };
};

Only one rrset-order substatement is permitted, but it can contain multiple order specifications. The first order specification to match a set of records in a response applies.

rrset-order supports three (count ‘em, three!) different orders:

fixed

Always returns matching records in the same order

random

Returns matching records in random order

cyclic

Returns matching records in cyclic (round-robin) order

Unfortunately, BIND 9.3.2 doesn’t yet support the fixed order completely.[*]

The default behavior is:

options {
    rrset-order {
        class IN type ANY name "*" order cyclic;
    };
};

Configuring rrset-order is far from a complete solution, unfortunately, because resolver and nameserver caching can interfere with its operation. A better long-term solution is the SRV record, which we’ll discuss in Chapter 17.

Nameserver Address Sorting

Sometimes, neither round-robin nor any other configurable order is what you want. When you are contacting a host that has multiple network interfaces and hence multiple IP addresses, choosing a particular interface based on your host’s address may give you better performance. No rrset-order substatement can do that for you.

If the multihomed host is local and shares a network or subnet with your host, one of the multihomed host’s addresses is “closer.” If the multihomed host is remote, you may see better performance using one interface instead of another, but often it doesn’t matter much which address is used. In days long past, net 10 (the former ARPAnet “backbone”) was always closer than any other remote address. The Internet has improved drastically since those days, so you won’t often see a marked performance improvement when using one network over another for remote multihomed hosts, but we’ll cover that case anyway.

Before we get into address sorting by a nameserver, you should first look at whether address sorting by the resolver better suits your needs. (See the section "The sortlist Directive" in Chapter 6.) Since your resolver and nameserver may be on different networks, it often makes more sense for the resolver to sort addresses optimally for its host. Address sorting at the nameserver works fairly well, but it can be hard to optimize for every resolver it services.

In an uncommon turn of events, the nameserver’s address-sorting feature was removed in early versions of BIND 8, primarily because of the developers’ insistence that it had no place in the nameserver. The feature was restored—and in fact enhanced—in BIND 8.2. BIND 9.1.0 was the first BIND 9 release to support address sorting.

The key to address sorting is an options substatement called sortlist. The sortlist substatement takes an address match list as an argument. Unlike address match lists used as access control lists, though, sortlist’s has a very specialized interpretation. Each entry in the address match list is itself an address match list with either one or two elements.

If an entry has only one element, it’s used to check the IP address of a querier. If the querier’s address matches, then the nameserver sorts addresses in a response to that querier so that any addresses that match the element are first. Confusing? Here’s an example:

options {
    sortlist {
        { 192.249.249/24; };
    };
};

The only entry in this sort list has just one element. This sort list sorts addresses on the network 192.249.249/24 to the beginning of responses to queriers that are also on that network. So if the client at 192.249.249.101 looks up a domain name that owns two addresses, 192.249.249.87 and 192.253.253.87, the nameserver will sort 192.249.249.87 to the beginning of the response.

If an entry has two elements, the first element is used to match the IP address of a querier. If the querier’s address matches, the nameserver sorts addresses in a response to that querier so that any addresses that match the second element come first. The second element can actually be a whole address match list of several elements, in which case the first address added to the response is the one that matches first in the list. Here’s a simple example:

options {
    sortlist {
        { 192.249.249/24; { 192.249.249/24; 192.253.253/24; }; };
    };
};

This sort list applies to queriers on 192.249.249/24 and sends them addresses on their own network first, followed by addresses on 192.253.253/24.

The elements in the sort list specification can just as easily be subnets or even individual hosts:

options {
    sortlist {
        { 15.1.200/21;       // if the querier is on 15.1.200/21
            { 15.1.200/21;   // then prefer addresses on that subnet
            15/8; };         // or at least on 15/8
        };
    };
};

Preferring Nameservers on Certain Networks

BIND 8’s topology feature is somewhat similar to sortlist, but it applies only to the process of choosing nameservers. (BIND 9 doesn’t support topology as of 9.3.2.) Earlier in the book, we described how BIND chooses between a number of nameservers that are authoritative for the same zone by selecting the nameserver with the lowest round-trip time. But we lied—a little. BIND 8 actually places remote nameservers in 64-millisecond bands when comparing RTT. The first band is actually only 32 milliseconds wide (there! we did it again), from 0 to 32 milliseconds. The next extends from 33 to 96 milliseconds, and so on. The bands are designed so that nameservers on different continents are always in different bands.

The idea is to favor nameservers in lower bands but to treat servers in the same band as equivalent. If a nameserver compares two remote servers’ RTTs, and one is in a lower band, the nameserver chooses to query the nameserver in the lower band. But if the remote servers are in the same band, the nameserver checks to see whether one of the remote servers is topologically closer.

So topology lets you introduce an element of fudge into the process of choosing a nameserver to query. It lets you favor nameservers on certain networks over others. Topology takes as an argument an address match list, where the entries are networks, listed in the order in which the local nameserver should prefer them (highest to lowest). Therefore:

topology {
    15/8;
    172.88/16;
};

tells the local nameserver to prefer nameservers on the network 15/8 over other nameservers, and nameservers on the network 172.88/16 over nameservers on networks other than 15/8. So if the nameserver has a choice between a nameserver on network 15/8, a nameserver on 172.88/16, and a nameserver on 192.168.1/24, assuming all three have RTT values in the same band, it will choose to query the nameserver on 15/8.

You can also negate entries in the topology address match list to penalize nameservers on certain networks. The earlier in the address match list the negated entry matches, the greater the penalty. You might use this to keep your nameserver from querying remote nameservers on a network that’s particularly flaky, for example.

A Nonrecursive Nameserver

By default, BIND resolvers send recursive queries, and, by default, BIND nameservers do the work required to answer them. (If you don’t remember how recursion works, see Chapter 2.) In the process of finding the answers to recursive queries, the nameserver builds up a cache of nonauthoritative information from other zones.

In some situations, it’s undesirable for nameservers to do the extra work required to answer a recursive query or to build up a cache of data. The root nameservers are an example of one of these situations. The root nameservers are so busy that they can’t expend the extra effort necessary to find the answers to recursive queries. Instead, they send a response based only on the authoritative data they have. The response may contain the answer, but it more likely contains a referral to other nameservers. And since the root servers do not support recursive queries, they don’t build up a cache of nonauthoritative data, which is good because their caches would be huge.[*]

You can induce a BIND nameserver to run in nonrecursive mode with the following configuration (config) file statement:

options {
    recursion no;
};

Now the server will respond to recursive queries as if they were nonrecursive.

In conjunction with recursion no, there is one more configuration option necessary if you want to prevent your nameserver from building a cache:

options {
    fetch-glue no;
};

This stops the server from fetching missing glue when constructing the additional data section of a response. BIND 9 nameservers don’t fetch glue, so the fetch-glue substatement is obsolete in BIND 9.

If you choose to make one of your servers nonrecursive, don’t list that nameserver in any host’s resolv.conf file. While you can make your nameserver nonrecursive, there is no corresponding option to make your resolver work with a nonrecursive nameserver.[*] If your nameserver needs to continue to serve one or more resolvers, you can use the allow-recursion substatement, available in BIND 8.2.1 and later (including BIND 9). allow-recursion takes an address match list as an argument; any queriers that match can send recursive queries, but everyone else is treated as if recursion were off:

options {
    allow-recursion { 192.253.254/24; };  // Only resolvers on the FX
                                          // subnet should be sending
                                          // recursive queries
};

allow-recursion’s default is to provide recursion to any IP address.

Also, don’t list a nonrecursive nameserver as a forwarder. When a nameserver is using another server as a forwarder, it forwards recursive queries to the forwarder. Use allow-recursion to permit just authorized nameservers to use your forwarder instead.

You can list a nonrecursive nameserver as one of the servers authoritative for your zone data (i.e., you can tell a parent nameserver to refer queries about your zone to this server). This works because nameservers send nonrecursive queries between themselves.

Avoiding a Bogus Nameserver

In your term as nameserver administrator, you might find some remote nameserver that responds with bad information—old, incorrect, badly formatted, or even deliberately deceptive. You can attempt to find an administrator to fix the problem. Or you can save yourself some grief and configure your nameserver not to ask questions of this server, which is possible with BIND 8, and BIND 9.1.0 and later. Here is the configuration file statement:

server 10.0.0.2 {
    bogus yes;
};

Of course, you fill in the correct IP address.

If you tell your nameserver to stop talking to a server that is the only server for a zone, don’t expect to be able to look up names in that zone. Hopefully, there are other servers for that zone that can provide good information.

An even more potent way of shutting out a remote nameserver is to put it on your blackhole list. Your nameserver won’t query nameservers on the list, and it won’t respond to their queries.[*] blackhole is an options substatement that takes an address match list as an argument:

options {

    /* Don't waste your time trying to respond to queries from RFC 1918
       private addresses */

    blackhole {
        10/8;
        172.16/12;
        192.168/16;
    };
};

This prevents your nameserver from trying to respond to any queries it might receive from RFC 1918 private addresses. There are no routes on the Internet to these addresses, so trying to reply to them is a waste of CPU cycles and bandwidth.

The blackhole substatement is supported on BIND 8 versions after 8.2 and on BIND 9 after 9.1.0.

System Tuning

While for many nameservers BIND’s default configuration values work just fine, yours may be one of those that need some further tuning. In this section, we discuss all the various dials and switches available to you to tune your nameserver.

Zone Transfers

Zone transfers can place a heavy load on a nameserver. Consequently, BIND has mechanisms for limiting the zone transfer load that your slave nameservers place on their master servers.

Limiting transfers requested per nameserver

On a slave nameserver, you can limit the number of zones the server requests from a single master nameserver. This will make the administrator of your master nameserver happy because his host won’t be pounded for zone transfers if all the zones change—important if hundreds of zones are involved.

The config file statement is:

options {
    transfers-per-ns 
 2;
};

In BIND 9, you can also set the limit on a server-by-server basis instead of globally. To do this, use the transfers substatement inside a server statement, where the server is the nameserver you’d like to specify the limit for:

server 192.168.1.2 {
    transfers 2;
};

This overrides any global limit set in the options statement. The default limit is two active zone transfers per master nameserver. That limit may seem small, but it works. Here’s what happens: suppose your nameserver needs to load four zones from a master nameserver. Your nameserver starts transferring the first two zones and waits to transfer the third and fourth zones. After one of the first two zone transfers completes, the nameserver begins transferring the third zone. After another transfer completes, the nameserver starts transferring the fourth zone. The net result is the same as before when there were limits—all the zones are transferred—but the work is spread out.

When may you need to increase this limit? You might notice that it is taking too long to synch up with the master nameserver, and you know that the reason is the serializing of transfers—not just that the network between the hosts is slow. This probably matters only if you’re maintaining hundreds or thousands of zones. You also need to make sure that the master nameserver and the networks in between can handle the additional workload of more simultaneous zone transfers.

Limiting the total number of zone transfers requested

The last limit dealt with the zone transfers requested from a single master nameserver. This limit deals with multiple master nameservers. BIND lets you limit the total number of zones your nameserver can request at any one time. The default limit is 10. As we explained previously, your nameserver pulls only two zones from any single master server by default. If your nameserver is transferring two zones from each of five master servers, your server has hit the limit and will postpone any further transfers until one of the current transfers finishes.

The BIND 8 and 9 named.conf file statement is:

options {
    transfers-in 10;
};

If your host or network cannot handle 10 active zone transfers, you should decrease this number. If you run a server that supports hundreds or thousands of zones, and your host and network can support the load, you might want to raise this limit. If you raise this limit, you may also need to raise the limit for the number of transfers per nameserver. (For example, if your nameserver loads from only four remote nameservers, and your nameserver will start only two transfers per remote nameserver, your server will have at most eight active zone transfers. Increasing the limit for the total number of zone transfers won’t have any effect unless you also increase the per-nameserver limit.)

Limiting the total number of zone transfers served

BIND 9 nameservers can also limit the number of zone transfers they’ll serve simultaneously. This is arguably more useful than limiting the number you’ll request because without it you’d have to rely on the kindness of the administrators who run your slave nameservers not to overload your master server. Here’s the BIND 9 statement:

options {
    transfers-out 10;
};

The default limit is 10.

Limiting the duration of a zone transfer

BIND also lets you limit the duration of an inbound zone transfer. By default, zone transfers are limited to 120 minutes, or 2 hours. The idea is that a zone transfer taking longer than 120 minutes is probably hung and won’t complete, and the process is taking up resources unnecessarily. If you’d like a smaller or larger limit, perhaps because you know that your nameserver is a slave for a zone that normally takes more than 120 minutes to transfer, you can use this statement:

options {
    max-transfer-time-in 180;
};

You can even place a limit on transfers of a particular zone by using the max-transfer-time-in substatement inside a zone statement. For example, if you know that the rinkydink.com zone always takes a long time (say three hours) to transfer, either because of its size or because the links to the master nameserver are so slow, but you’d still like a shorter time limit (maybe an hour) on other zone transfers, you could use:

options {
    max-transfer-time-in 60;
};

zone "rinkydink.com" {
    type slave;
    file "bak.rinkydink.com";
    masters { 192.168.1.2; };
    max-transfer-time-in 180;
};

In BIND 9, there’s also a max-transfer-time-out substatement that can be used the same way (either within an options statement or a zone statement). It controls how long an outbound zone transfer (i.e., a transfer to a slave) can run and has the same default value (120 minutes) as max-transfer-time-in.

BIND 9 nameservers even let you limit zone transfer idle time, the length of time since the zone transfer made any progress. The two configuration substatements, max-transfer-idle-in and max-transfer-idle-out, control how long an inbound and an outbound zone transfer can be idle, respectively. Like the transfer time limits, both can be used as either an options substatement or a zone substatement. The default limit on idle time is 60 minutes.

Limiting the frequency of zone transfers

It’s possible to set a zone’s refresh interval so low as to cause undue work for that zone’s slave nameservers. For example, if your nameserver is a slave for thousands of zones, and the administrators of some of those zones set their refresh intervals to very small values, your nameserver may not be able to keep up with all the refreshing it needs to do. (If you run a nameserver that’s a slave for that many zones, be sure to read the later section "Limiting SOA queries“; you may also need to tune the number of SOA queries allowed.) On the other hand, it’s possible for an inexperienced administrator to set her zone’s refresh interval so high as to cause prolonged inconsistencies between the zone’s primary and slave nameservers.

BIND versions 9.1.0 and later let you limit the refresh interval with max-refresh-time and min-refresh-time. These substatements bracket the refresh value for all master, slave, and stub zones if used as an options substatement, or just for a particular zone if used as a zone substatement. Both take a number of seconds as an argument:

options {
    max-refresh-time 86400;    // refresh should never be more than a day
    min-refresh-time 1800;     // or less than 30 minutes
};

BIND 9.1.0 and later nameservers also let you limit the retry interval with the max-retry-time and min-retry-time substatements, which use the same syntax.

More efficient zone transfers

A zone transfer, as we said earlier, comprises many DNS messages sent end-to-end over a TCP connection. Traditional zone transfers put only a single resource record in each DNS message. That’s a waste of space: you need a full header on each DNS message, even though you’re carrying only a single record. It’s like being the only person in a Chevy Suburban. A TCP-based DNS message can carry many more records: its maximum size is a whopping 64 KB!

BIND 8 and 9 nameservers understand a new zone transfer format, called many-answers. The many-answers format puts as many records as possible into a single DNS message. The result is that a many-answers zone transfer takes less bandwidth because there’s less overhead and less CPU time because less time is spent unmarshaling DNS messages.

The transfer-format substatement controls which zone transfer format the nameserver uses for zones for which it is a master. That is, it determines the format of the zones that your nameserver transfers to its slaves. transfer-format is both an options substatement and a server substatement; as an options substatement, transfer-format controls the nameserver’s global zone transfer format. BIND 8’s default is to use the old one-answer zone transfer format for interoperability with BIND 4 nameservers. BIND 9’s default is to use the many-answers format. The statement:

options {
    transfer-format many-answers;
};

configures the nameserver to use the many-answers format for zone transfers to all slave servers, unless a server statement such as the following explicitly says otherwise:

server 192.168.1.2 {
    transfer-format one-answer;
};

If you’d like to take advantage of the new, more efficient zone transfers, do one of the following:

  • Set your nameserver’s global zone transfer format to many-answers (or don’t add one at all if you’re running BIND 9) if most of your slaves run BIND 8, BIND 9, or the Microsoft DNS Server, which also understands the format.[*]

  • Set your nameserver’s global zone transfer format to one-answer if most of your slaves run BIND 4. Then use the transfer-format server substatement to adjust the global setting for exceptional servers.

Remember that if you run BIND 9, you’ll need to add an explicit server statement for all BIND 4 slaves to change their transfer formats to one-answer.

Resource Limits

Sometimes you just want to tell the nameserver to stop being so greedy: don’t use more than this much memory, don’t open more than this many files. With BIND 8 and 9, you can impose many such limits.

Changing the data segment size limit

Some operating systems place a default limit on the amount of memory a process can use. If your OS ever prevents your nameserver from allocating additional memory, the server will panic or exit. Unless your nameserver handles an extremely large amount of data or the limit is very small, you won’t run into this limit. But if you do, BIND 8 as well as BIND 9.1.0 and later nameservers have configuration options to change the system’s default limit on data segment size. You might use these options to set a higher limit for named than the default system limit.

For both BIND 8 and 9, the statement is:

options {
    datasize size
};

size is an integer value, specified in bytes by default. You can specify a unit other than bytes by appending a character: k (kilobyte), m (megabyte), or g (gigabyte). For example, “64m” is 64 megabytes.

Tip

Not all systems support increasing the data segment size for individual processes. If your system doesn’t, the nameserver issues a syslog message at level LOG_WARNING to tell you that this feature is not implemented.

Changing the stack size limit

In addition to allowing you to change the limit on the size of the nameserver’s data segment, BIND 8 and BIND 9.1.0 and later nameservers let you adjust the limit the system places on the amount of memory the named process’s stack can use. Here’s the syntax:

options {
    stacksize size;
};

where size is specified as in datasize. Like datasize, this feature works only on systems that permit a process to modify the stack size limit.

Changing the core size limit

If you don’t appreciate named’s leaving huge core files lying around on your filesystem, you can at least make them smaller using coresize. Conversely, if named hasn’t been able to dump an entire core file because of a tight operating system limit, you may be able to raise that limit with coresize.

coresize’s syntax is:

options {
    coresize size;
};

Again, as with datasize, this feature works only on operating systems that let processes modify the limit on core file size and doesn’t work on versions of BIND 9 before 9.1.0.

Changing the open files limit

If your nameserver is authoritative for a lot of zones, the named process opens lots of files when it starts up—one per authoritative zone, assuming you use backup zone datafiles with the zones you’re a slave for. Likewise, if the host running your nameserver has lots of virtual network interfaces,[*] named requires one file descriptor per interface. Most Unix operating systems place a limit on the number of files any process can open concurrently. If your nameserver tries to open more files than this limit permits, you’ll see this message in your syslog output:

named[pid]: socket(SOCK_RAW): Too many open files

If your operating system also permits changing that limit on a per-process basis, you can increase it using BIND’s files substatement:

options {
    files number;
};

The default is unlimited (which is also a valid value), although this just means that the nameserver doesn’t place a limit on the number of concurrently open files; the operating system may, however. And though we know you’re sick of our saying it, BIND 9 doesn’t support this until 9.1.0.

Limiting the number of clients

BIND 9 lets you restrict the number of clients your nameserver can serve concurrently. You can apply a limit to the number of recursive clients (resolvers plus nameservers using your nameserver as a forwarder) with the recursive-clients substatement:

options {
    recursive-clients 5000;
};

The default limit is 1000. If you find your nameserver refusing recursive queries and logging, as shown by an error message like this one:

Sep 22 02:26:11 toystory named[13979]: client 192.249.249.151#1677: no more
recursive clients: quota reached

you may want to increase the limit. Conversely, if you find your nameserver struggling to keep up with the deluge of recursive queries it receives, you can lower the limit.

You can also apply a limit to the number of concurrent TCP connections your nameserver will process (for zone transfers and TCP-based queries) with the tcp-clients substatement. TCP connections consume considerably more resources than UDP because the host needs to track the state of the TCP connection. The default limit is 100.

Limiting SOA queries

BIND 8.2.2 and later nameservers let you limit the number of outstanding SOA queries your nameserver allows. If your nameserver is a slave for thousands of zones, it may have many queries for the SOA records of those zones pending at any one time. Tracking each query requires a small but finite amount of memory, so, by default, BIND 8 nameservers limit outstanding SOA queries to four. If you find that your nameserver can’t keep up with its duties as a slave, you may need to raise the limit with the serial-queries substatement:

options {
    serial-queries 1000;
};

serial-queries is obsolete in BIND 9. BIND 9 limits the rate at which serial queries are sent (to 20 per second), not the number of outstanding queries. This limit can be adjusted with the serial-query-rate options substatement, which takes an integer (number of queries per second) as an argument.

Maintenance Intervals

BIND nameservers have always done periodic housekeeping, such as refreshing zones for which the server is a slave. With BIND 8 and 9, you can control how often these chores happen or whether they happen at all.

Cleaning interval

All nameservers passively remove stale entries from the cache. Before a nameserver returns a record to a querier, it checks to see whether the TTL on that record has expired. If it has, the nameserver starts the resolution process to find more current data. However, relying entirely on this mechanism can result in an unnecessarily large cache. A nameserver may cache a lot of records in a flurry of name resolution and then just let those records spoil in the cache, taking up valuable memory even though the records are stale.

To deal with this, BIND nameservers actively walk through the cache and remove stale records once per cleaning interval. This helps minimize the amount of memory used by the cache. On the other hand, the cleaning process takes CPU time, and on very slow or very busy nameservers, you may not want it running often.

By default, the cleaning interval is 60 minutes. You can tune the interval with the cleaning-interval substatement to the options statement. For example:

options {
    cleaning-interval 120;
};

sets the cleaning interval to 120 minutes. To turn off cache cleaning entirely, set the cleaning interval to 0.

Interface interval

We’ve said already that BIND, by default, listens on all of a host’s network interfaces. BIND 8 and 9 nameservers are actually smart enough to notice when a network interface on the host they’re running on comes up or goes down. To do this, they periodically scan the host’s network interfaces. This happens once each interface interval, which is 60 minutes by default. If you know that the host your nameserver runs on has no dynamic network interfaces, you can disable scanning for new interfaces to avoid the unnecessary hourly overhead by setting the interface interval to 0:

options {
    interface-interval 0;
};

On the other hand, if your host brings up or tears down network interfaces more often than every hour, you may want to reduce the interval.

Statistics interval

Okay, adjusting the statistics interval —the frequency with which the BIND 8 nameserver dumps statistics to the statistics file—won’t have much effect on performance. But it fits better here, with the other maintenance intervals, than anywhere else in the book.

The syntax of the statistics-interval substatement is exactly analogous to the other maintenance intervals:

options {
    statistics-interval 60;
};

And as with the other maintenance intervals, the default is 60 minutes, and a setting of 0 disables the periodic dumping of statistics. Because BIND 9 doesn’t write statistics to syslog, it doesn’t have a configurable statistics interval.

TTLs

Internally, BIND trims TTL values on cached records to reasonable values. BIND 8 and 9 nameservers make the limits configurable.

In BIND 8.2 or later and all BIND 9 nameservers, you can limit the TTL on cached negative information with the max-ncache-ttl options substatement. This was designed as a safety net for people who upgraded to 8.2 and its new negative caching scheme (RFC 2308 and all that, described in Chapter 4). This new nameserver caches negative information according to the last field of the zone’s SOA record, and many zone admins still use that field for the default TTL for the zone—probably much too long for negative information. So a prudent nameserver administrator can use a substatement such as:

options {
    max-ncache-ttl 3600;  // 3600 seconds is one hour
};

to trim larger negative caching TTLs to one hour. The default is 10,800 seconds (3 hours). Without this precaution, it’s possible that someone looking up a brand-new record could get a negative answer (maybe because the new record hadn’t yet reached the zone’s slaves), and her nameserver would cache that answer for an inordinately long time, rendering the record unresolvable.

BIND 9 nameservers also let you configure the upper limit of the TTL on cached records with the max-cache-ttl substatement. The default is one week. BIND 8 nameservers trim TTLs to one week, too, but they don’t let you configure the limit.

Finally, there’s what’s referred to as the lame TTL, which isn’t really a TTL at all. Instead, it’s the amount of time your nameserver remembers that a given remote nameserver isn’t authoritative for a zone that’s delegated to it. This prevents your nameserver from wasting valuable time and resources asking that nameserver for information about a domain name it knows nothing about. BIND 8 nameservers after 8.2 and BIND 9 nameservers newer than 9.1.0 let you tune the lame TTL with the lame-ttl options substatement. The default lame TTL is 600 seconds (10 minutes), with a maximum of 30 minutes. You can even turn off the caching of lame nameservers with a value of 0, though that strikes us as a Very Bad Thing.

Compatibility

Now, to wrap things up, we’ll cover some configuration substatements related to your nameserver’s compatibility with resolvers and other nameservers.

The rfc2308-type1 substatement controls the format of the negative answers your nameserver sends. By default, BIND 8 and 9 nameservers include only the SOA record in a negative response from a zone. Another legitimate format for that response includes the zone’s NS records, too, but some older nameservers misinterpret such a response as a referral. If for some odd reason (odd because we can’t think of one) you want to send those NS records as well, use:

options {
    rfc2308-type1 yes;
};

rfc2308-type1 is first supported in BIND 8.2; BIND 9 doesn’t support it.

Older nameservers can also cause problems when you send them cached negative responses. Before the days of negative caching, all negative responses were, naturally, authoritative. But some nameserver implementers added a check to their servers: they’d accept only authoritative negative responses. Then, with the advent of negative caching, negative responses could be nonauthoritative. Oops!

The auth-nxdomain options substatement lets your nameserver falsely claim that a negative answer from its cache is actually authoritative, just so one of these older nameservers will believe it. By default, BIND 8 nameservers have auth-nxdomain on (set to yes); BIND 9 nameservers turn it off by default.

When some adventurous souls ported BIND 8.2.2 to Windows NT, they found they needed the nameserver to treat a carriage return and a newline at the end of a line (Windows’ end-of-line sequence) the same way it treated just a newline (Unix’s end-of-line). For that behavior, use:

options {
    treat-cr-as-space yes;
};

BIND 9 ignores this option because it always treats a carriage return and a newline the same way as a newline by itself.

Finally, if you run a BIND nameserver that’s configured as a slave to Microsoft DNS Servers with Active Directory-integrated zones, you may see an error message in syslog informing you that the zones’ serial numbers have decreased. This is a side effect of the replication mechanism Active Directory uses and isn’t cause for alarm. If you want to squelch the message, you can use BIND 9.3.0’s new multi-master zone substatement to tell your slave that the IP addresses in the masters substatement actually belong to multiple nameservers, not to multiple interfaces on a single nameserver:

zone "_msdcs.domain.com" {
    type slave;
    masters { 10.0.0.2; 10.0.0.3; };
    file "bak._msdcs.domain.com";
    multi-master yes;
};

The ABCs of IPv6 Addressing

Before we cover the next two topics, which include how domain names map to IPv6 addresses and vice versa, we’d better describe the representation and structure of IPv6 addresses. As you probably know, IPv6 addresses are 128 bits long. The preferred representation of an IPv6 address is eight groups of as many as four hexadecimal digits, separated by colons; for example:

2001:db80:0123:4567:89ab:cdef:0123:4567

The first group of hex digits (2001, in this example) represents the most significant (or highest-order) 16 bits of the address.

Groups of digits that begin with one or more zeros don’t need to be padded to four places, so you can also write the previous address as:

2001:db80:123:4567:89ab:cdef:123:4567

Each group must contain at least one digit, though, unless you’re using the :: notation. The :: notation allows you to compress sequential groups of zeros. This comes in handy when you’re specifying just an IPv6 prefix. For example:

2001:db80:dead:beef::

specifies the first 64 bits of an IPv6 address as 2001:db80:dead:beef and the remaining 64 as zeros.

You can also use :: at the beginning of an IPv6 address to specify a suffix. For example, the IPv6 loopback address is commonly written as:

::1

or 127 zeros followed by a single one. You can even use :: in the middle of an address as a shorthand for contiguous groups of zeros:

2001:db80:dead:beef::1

You can use the :: shorthand only once in an address, since more than one could be ambiguous.

IPv6 prefixes are specified in a format similar to IPv4’s CIDR notation. As many bits of the prefix as are significant are expressed in the standard IPv6 notation, followed by a slash and a decimal count of exactly how many significant bits there are. So the following three prefix specifications are equivalent (though obviously not equivalently terse):

2001:db80:dead:beef:0000:00f1:0000:0000/96
2001:db80:dead:beef:0:f1:0:0/96
2001:db80:dead:beef:0:f1::/96

The IPv6 equivalent of an IPv4 network number is called a global routing prefix. These are a variable number of high-order bits of the IPv6 address used to identify a particular network. All global unicast addresses have global routing prefixes that begin with the binary value 001. These are assigned by address registries or Internet service providers. The global routing prefix itself may be hierarchical, with an address registry responsible for allocating lower-order bits to various ISPs, and ISPs responsible for allocating the lowest-order bits of the prefix to its customers.

After the global routing prefix, IPv6 addresses may contain another variable number of bits that identify the particular subnet within a network, called the subnet ID. The remaining bits of the address identify a particular network interface and are referred to as the interface ID.

Here’s a diagram from RFC 3513 that shows how these parts fit together:

|         n bits         |   m bits  |       128-n-m bits         |
+------------------------+-----------+----------------------------+
| global routing prefix  | subnet ID |       interface ID         |
+------------------------+-----------+----------------------------+

According to RFC 3177, which recommends how IPv6 addresses should be allocated to sites:

  • Home network subscribers should receive a /48 prefix.

  • Small and large enterprises should receive a /48 prefix.

  • Very large subscribers could receive a /47 or slightly shorter prefix.

Addresses and Ports

Since IPv4 is relatively simple compared to IPv6, let’s cover the nameserver’s IPv4 configuration together with IPv6. BIND 8.4.0 and later and all BIND 9 nameservers can use both IPv4 and IPv6 as a transport; that is, they can send and receive queries and responses over IPv4 and IPv6. Both nameservers also support similar substatements to configure which network interfaces and ports they listen on and send queries from.

Configuring the IPv4 Transport

You can specify which network interface your BIND 8 or BIND 9 nameserver listens on for queries using the listen-on substatement. In its simplest form, listen-on takes an address match list as an argument:

options {
    listen-on { 192.249.249/24; };
};

The nameserver listens on any of the local host’s network interfaces whose addresses match the address match list. To specify an alternate port (one other than 53) to listen on, use the port modifier:

options {
    listen-on port 5353 { 192.249.249/24; };
};

In BIND 9, you can even specify a different port for each network interface:

options {
    listen-on { 192.249.249.1 port 5353; 192.253.253.1 port 1053; };
};

Note that there’s no way to configure most resolvers to query a nameserver on an alternate port, so this nameserver might not be as useful as you’d think. Still, it can serve zone transfers because you can specify an alternate port in a masters substatement:

zone "movie.edu" {
    type slave;
    masters port 5353 { 192.249.249.1; };
    file "bak.movie.edu";
};

Or, if your BIND 9 nameserver has multiple master nameservers, each listening on a different port, you can use something like:

zone "movie.edu" {
    type slave;
    masters { 192.249.249.1 port 5353; 192.253.253.1 port 1053; };
    file "bak.movie.edu";
};

BIND 9 even allows you to send your NOTIFY messages to alternate ports. To tell your master nameserver to notify all its slave nameservers on the same oddball port, use:

also-notify port 5353 { 192.249.249.9; 192.253.253.9; }; // zardoz's two addresses

To notify each on a different port, use:

also-notify { 192.249.249.9 port 5353; 192.249.249.1 port 1053; };

If your slave nameserver needs to use a particular local network interface to send queries—perhaps because one of its master nameservers recognizes it by only one of its many addresses—use the query-source substatement:

options {
    query-source address 192.249.249.1;
};

Note that the argument isn’t an address match list; it’s a single IP address. You can also specify a particular source port to use for queries:

options {
    query-source address 192.249.249.1 port 53;
};

BIND’s default behavior is to use whichever network interface the route to the destination points out and a random, unprivileged port, i.e.:

options {
    query-source address * port *;
};

Note that query-source applies only to UDP-based queries; TCP-based queries always choose the source address according to the routing table and use a random source port.

There’s an analogous transfer-source substatement that controls the source address to use for zone transfers. In BIND 9, it also applies to a slave nameserver’s SOA queries and to forwarded dynamic updates:

options {
    transfer-source 192.249.249.1;
};

As with query-source, the argument is just a single IP address, but with no address keyword. With BIND 8, there’s no port modifier. With BIND 9, you can specify a source port:

options {
    transfer-source 192.249.249.1 port 1053;
};

However, that source port applies only to UDP-based traffic (i.e., SOA queries and forwarded dynamic updates).

transfer-source can also be used as a zone substatement, in which case it applies only to transfers (and, for BIND 9, SOA queries and dynamic updates) of that zone:

zone "movie.edu" {
    type slave;
    masters { 192.249.249.3; };
    file "bak.movie.edu";
    transfer-source 192.249.249.1; // always use IP address on same network
                                   // for transfers of movie.edu
};

Finally, as of BIND 9.1.0, there’s even a substatement that lets you control which address you send NOTIFY messages from, called notify-source. This comes in handy with multihomed nameservers because, by default, slaves accept only NOTIFY messages for a zone from IP addresses in that zone’s masters substatement. notify-source’s syntax is similar to the syntax of the other -source substatements; for example:

options {
    notify-source 192.249.249.1;
};

As with transfer-source, notify-source can specify a source port and can be used as a zone statement to apply only to that zone:

zone "movie.edu" {
    type slave;
    masters { 192.249.249.3; };
    file "bak.movie.edu";
    notify-source 192.249.249.1 port 5353;
};

If you can’t control the IP address from which NOTIFY messages are sent (because you don’t administer the master server, for example), you can either include all the master’s IP addresses in your zone’s masters substatement, or you can use the allow-notify substatement to explicitly permit NOTIFY messages from addresses not listed in masters.

Configuring the IPv6 Transport

By default, a BIND 9 nameserver won’t listen for IPv6-based queries. To configure it to listen on the local host’s IPv6 network interfaces, use the listen-on-v6 substatement:

options {
    listen-on-v6 { any; };
};

Before BIND 9.3.0, the listen-on-v6 substatement accepted only any and none as arguments. You can also configure a BIND nameserver to listen on an alternate port—or even multiple ports—with the port modifier:

options {
    listen-on-v6 port 1053 { any; };
};

To listen on more than one IPv6 interface or port, use multiple listen-on-v6 substatements. The default port is, of course, 53.

You can also determine which IPv6 address your nameserver uses as the source address for outgoing queries with the transfer-source-v6 substatement, as in:

options {
    transfer-source-v6 222:10:2521:1:210:4bff:fe10:d24;
};

or, also specifying a source port:

options {
    transfer-source-v6 222:10:2521:1:210:4bff:fe10:d24 port 53;
};

Only BIND 9 supports setting the source port, as in the second example. The default is to use the source address corresponding to whichever network interface the route points out and a random, unprivileged source port. As with transfer-source, you can use transfer-source-v6 as a zone substatement. And the source port applies only to SOA queries and forwarded dynamic updates.

Finally, BIND 9.1.0 and later let you determine which IPv6 address to use in NOTIFY messages, à la the notify-source substatement. The IPv6 substatement is called, not surprisingly, notify-source-v6:

options {
    notify-source-v6 222:10:2521:1:210:4bff:fe10:d24;
};

As with transfer-source-v6, you can specify a source port and use the substatement in a zone statement.

EDNS0

UDP-based DNS messages have traditionally been limited to 512 bytes. This limit was instituted to prevent fragmentation, which in the early days of the Internet was costly and unreliable. Times have changed, though, and most paths on the Internet can accommodate much larger UDP datagrams.

Thanks to new developments in DNS, such as DNSSEC and IPv6 support, the average response is getting larger. Responses from signed zones, in particular, can easily exceed the 512-byte limit, which can cause costly retries over TCP.

The Extension Mechanisms for DNS, version 0, referred to as EDNS0, introduces a simple signaling system to DNS. Using this system, a resolver or nameserver can tell another nameserver that it can handle a DNS message larger than 512 bytes. (In fact, the sender can signal other capabilities, too, as we’ll see in the next chapter.)

BIND nameservers have supported EDNS0 since versions 9.0.0 and 8.3.0. These nameservers send EDNS0 signaling information by default, and try to negotiate a UDP-based DNS message size of 4,096 bytes. If they receive a response that indicates that the nameserver they’re talking to doesn’t understand EDNS0, they’ll fall back to using messages that adhere to the old 512-byte limit.

This technique generally works well, but occasionally you’ll run across a nameserver that reacts badly to EDNS0 probes. To cope with these nameservers, you can use the new edns server substatement to turn off EDNS0 for that nameserver:

server 10.0.0.1 {
    edns no;
};

This is supported in BIND 9.2.0 and later and BIND 8.3.2 and later nameservers.

BIND 9.3.0 and later and 8.4.0 and later also allow you to configure the size of the UDP-based DNS messages your nameserver will negotiate with the edns-udp-size options substatment:

options {
    directory "/var/named";
    edns-udp-size 512;
};

This can be useful if your firewall doesn’t understand that DNS messages can exceed 512 bytes in size and keeps dropping legitimate messages. (Of course, we think you should upgrade your firewall, but you may need to resort to this in the interim.) The maximum value for edns-udp-size is 4096; the minimum is 512.

IPv6 Forward and Reverse Mapping

Clearly, the existing A record won’t accommodate IPv6’s 128-bit addresses; BIND expects an A record’s record-specific data to be a 32-bit address in dotted-octet format.

The IETF came up with a simple solution to this problem, described in RFC 1886. A new address record, AAAA, was used to store a 128-bit IPv6 address, and a new IPv6 reverse-mapping domain, ip6.int , was introduced. This solution was straightforward enough to implement in BIND 4. Unfortunately, not everyone liked the simple solution, so it came up with a much more complicated one. This solution, which we’ll describe shortly, involved the new A6 and DNAME records and required a complete overhaul of the BIND nameserver to implement. Then, after much acrimonious debate, the IETF decided that the new A6/DNAME scheme required too much overhead, was prone to failure, and was of unproven usefulness. At least temporarily, it moved the RFC that describes A6 records off the IETF standards track to experimental status, deprecated the use of DNAME records in reverse-mapping zones, and trotted old RFC 1886 back out. Everything old is new again.

For now, the AAAA record is the way to handle IPv6 forward mapping. The use of ip6.int is deprecated, however, mostly for political reasons; it’s been replaced by ip6.arpa. In the interest of preparing you for all possible futures, including one in which A6 and DNAME make a dramatic comeback, we’ll cover both methods.

AAAA and ip6.arpa

The easy way to handle IPv6 forward mapping, described in RFC 1886, is with an address record that’s four times as long as an A record. That’s the AAAA (pronounced “quad A”) record. The AAAA record takes as its record-specific data the textual format of an IPv6 address, as described earlier. So, for example, you’d see AAAA records like this one:

ipv6-host    IN    AAAA    2001:db80:1:2:3:4:567:89ab

RFC 1886 also established ip6.int , now replaced by ip6.arpa, a new reverse-mapping namespace for IPv6 addresses. Each level of subdomain under ip6.arpa represents four bits of the 128-bit address, encoded as a hexadecimal digit just like in the record-specific data of the AAAA record. The least significant (lowest-order) bits appear at the far left of the domain name. Unlike the format of addresses in AAAA records, omitting leading zeros is not allowed, so there are always 32 hexadecimal digits and 32 levels of subdomain below ip6.arpa in a domain name corresponding to a full IPv6 address. The domain name that corresponds to the address in the previous example is:

b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.8.b.d.1.0.0.2.ip6.arpa.

These domain names have PTR records attached, just as the domain names under in-addr.arpa do:

b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.8.b.d.1.0.0.2.ip6.arpa.
  IN  PTR  mash.ip6.movie.edu.

A6, DNAMEs, Bitstring Labels, and ip6.arpa

That’s the easy way. The more difficult—and now only experimental —way of handling IPv6 forward and reverse mapping uses two new record types, A6 and DNAME records. A6 and DNAME records are described in RFCs 2874 and 2672, respectively. Version 9.0.0 was the first version of BIND to support these records.

Warning

There’s no guarantee that this method of doing IPv6 forward and reverse mapping will ever reemerge as the standard, and the latest versions of BIND don’t even support it fully. You may be wasting your time in reading this section, just as we may have wasted our time in writing it. We’re leaving it here because fashion is cyclical, and A6 and friends may yet make a comeback.

If you want to experiment with A6 and bitstring labels, dig out a BIND 9.2.x nameserver. The ISC removed support for bitstring labels in 9.3.0, and advises that A6 is “no longer fully supported.” Also, note that bitstring labels can also cause interoperability problems with some DNS software.

The main reason a replacement for the AAAA record and ip6.int reverse-mapping scheme was sought was because they make network renumbering difficult. For example, if an organization were to change ISPs, it would have to change all the AAAA records in its zone datafiles because some of the bits of an IPv6 address are an identifier for the ISP.[*] Or imagine an ISP changing address registries: this would wreak havoc with its customers’ zone data.

A6 records and forward mapping

To make renumbering easier, A6 records can specify only a part of an IPv6 address, such as the last 64 bits (maybe the interface ID) assigned to a host’s network interface, and then refer to the remainder of the address by a symbolic domain name. This allows zone administrators to specify only the part of the address under their control. To build an entire address, a resolver or nameserver must follow the chain of A6 records from a host’s domain name to the address registry’s ID. And that chain may branch if a site network is connected to multiple ISPs or if an ISP is connected to multiple address registries.

For example, the A6 record:

$ORIGIN movie.edu.
drunkenmaster  IN   A6   64  ::0210:4bff:fe10:0d24  subnet1.v6.movie.edu.

specifies the final 64 bits of drunkenmaster.movie.edu ’s IPv6 address (64 is the number of bits of the prefix not specified in this A6 record) and that the remaining 64 bits can be found by looking up an A6 record at subnet1.v6.movie.edu.

subnet1.v6.movie.edu, in turn, specifies the last 16 bits of the 64-bit prefix (the subnet ID) that we didn’t specify in drunkenmaster.movie.edu ’s A6 address, as well as the domain name of the next A6 record to look up:

$ORIGIN v6.movie.edu.
subnet1  IN  A6  48  0:0:0:1::  movie-u.isp-a.net.
subnet1  IN  A6  48  0:0:0:1::  movie.isp-b.net.

The first 48 bits of the prefix in subnet1.v6.movie.edu’s record-specific data are set to 0 because they’re not significant here.

In fact, these records tell us to look up two A6 records next, one at movie-u.isp-a.net and one at movie.isp-b.net . That’s because Movie U. has connections to two ISPs, ISP A and ISP B. In ISP A’s zone, we might find:

$ORIGIN isp-a.net.
movie-u  IN  A6   40  0:0:21::  isp-a.rir-1.net.

indicating an eight-bit pattern within the global routing prefix field set by ISP A for the Movie U. network. (Remember, the global routing prefix field can be hierarchical, too, comprising both an identifier for our ISP assigned to it by its address registry and our ISP’s identifier for our network.) Since the ISP assigns some bits of the global routing prefix to us but has the rest of the prefix assigned by its address registry, we’d expect to see only our bits in our ISP’s zone data. The remainder of the prefix appears in an A6 record in its address registry’s zone.

In ISP B’s zone, we might find the following record showing us the bits that ISP assigns for our network:

$ORIGIN isp-b.net.
movie  IN  A6  40  0:0:42::  isp-b.rir-2.net.

In the address registries’ zones, we might find the next four bits of the IPv6 address:

$ORIGIN rir-1.net.
isp-a  IN  A6  36  0:0:0500::  rir-2.top-level-v6.net.

and:

$ORIGIN rir-2.net.
isp-b   IN  A6  36  0:0:0600:: rir-1.top-level-v6.net.

Finally, in the top-level IPv6 address registry’s zone, we might find these records showing us the bits of the prefix assigned to RIR 1 and RIR 2:

$ORIGIN top-level-v6.net.
rir-1    IN    A6    0    2001:db80::2
rir-2    IN    A6    0    2001:db80::6

By following this chain of A6 records, a nameserver can assemble all 128 bits of drunkenmaster.movie.edu ’s two IPv6 addresses. These turn out to be:

2001:db80:2521:1:210:4bff:fe10:d24
2001:db80:6642:1:210:4bff:fe10:d24

The first of these uses a route through RIR 1 and ISP A to the Movie U. network, and the second uses a route through RIR 2 and ISP B. (We’re connected to two ISPs for redundancy.) Note that if RIR 1 changes its prefix assignment for ISP A, it needs to change only the A6 record for isp-a.rir-1.net in its zone data; the change “cascades” into all A6 chains that go through ISP A. This makes the management of addressing on IPv6 networks very convenient and makes changing ISPs easy, too.

You can probably already see some of the potential problems with A6 records. Resolving a domain name to a single IPv6 address may require several independent queries (to look up A6 records for an RIR’s domain name, an ISP’s domain name, and so on). Completing all of those queries may take many times longer than resolving a domain name’s single AAAA record, and if any one of the “subresolutions” fails, the overall resolution process fails.

Tip

If a nameserver appears in an NS record and owns one or more A6 records, those A6 records should specify all 128 bits of the IPv6 address. This helps avoid deadlock problems, in which a resolver or nameserver needs to talk to a remote nameserver to resolve part of that nameserver’s IPv6 address.

DNAME records and reverse mapping

Now that you’ve seen how forward mapping works with A6 records, let’s look at how reverse-mapping IPv6 addresses works. As with A6 records, unfortunately, this isn’t nearly as simple as ip6.arpa.

Reverse-mapping IPv6 addresses involves DNAME records, described in RFC 2672, and bitstring labels, introduced in RFC 2673. DNAME records are a little like wildcard CNAME records. They’re used to substitute one suffix of a domain name with another. For example, if we previously used the domain name movieu.edu at Movie U. but have since changed to movie.edu, we can replace the old movieu.edu zone with this one:

$TTL 1d
@    IN  SOA    toystory.movie.edu.  root.movie.edu. (
    2000102300
    3h
    30m
    30d
    1h  )

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

    IN   MX     10 postmanrings2x.movie.edu.

    IN   DNAME  movie.edu.

The DNAME record in the movieu.edu zone applies to any domain name that ends in movieu.edu except movieu.edu itself. Unlike the CNAME record, the DNAME record can coexist with other record types owned by the same domain name as long as they aren’t CNAME or other DNAME records. The owner of the DNAME record may not have any subdomains, though.

When the movieu.edu nameserver receives a query for any domain name that ends in movieu.edu, say cuckoosnest.movieu.edu , the DNAME record tells it to “synthesize” an alias from cuckoosnest.movieu.edu to cuckoosnest.movie.edu, replacing movieu.edu with movie.edu:

cuckoosnest.movieu.edu.  IN  CNAME  cuckoosnest.movie.edu.

It’s a little like sed’s “s” (substitute) command. The movieu.edu nameserver replies with this CNAME record. If it’s responding to a newer nameserver, it also sends the DNAME record in the response, and the recipient nameserver can then synthesize its own CNAME records from the cached DNAME.

Bitstring labels are the other half of the magic involved in IPv6 reverse mapping. Bitstring labels are simply a compact way to represent a long sequence of binary (i.e., one-bit) labels in a domain name. Say you want to permit delegation between any two bits of an IP address. This might compel you to represent each bit of the address as a label in a domain name. But that would require over 128 labels for a domain name that represented an IPv6 address! Oy! That exceeds the limit on the number of labels in a normal domain name!

Bitstring labels concatenate the bits in successive labels into a shorter hexadecimal, octal, binary, or dotted-octet string. The string is encapsulated between the tokens “[” and “]” to distinguish it from a traditional label, and begins with one letter that determines the base of the string: b for binary, o for octal, and x for hexadecimal.

Here are the bitstring labels that correspond to drunkenmaster.movie.edu ’s two IPv6 addresses:

[x2001db802521000102104bfffe100d24]
[x2001db806642000102104bfffe100d24]

Notice that the most significant bit begins the string, as in the text representation of an IPv6 address, but in the opposite order of the labels in the in-addr.arpa domain. Despite this, these two bitstring labels are simply a different encoding of traditional domain names that begin:

0.0.1.0.0.1.0.0.1.0.1.1.0.0.0.0.0.0.0.0.1.0.0.0.0.1.1.1.1.1.1.1...

Also note that all 32 hex digits in the address are present; you can’t drop leading zeros, because there are no colons to separate groups of four digits.

Bitstring labels can also represent parts of IPv6 addresses, in which case you need to specify the number of significant bits in the string, separated from the string by a slash. So RIR 1’s portion of the global routing prefix is [x2001db802/36].

Together, DNAMEs and bitstring labels are used to match portions of a long domain name that encode an IPv6 address and to iteratively change the domain name looked up to a domain name in a zone under the control of the organization that manages the host with that IPv6 address.

Imagine we’re reverse-mapping [x2001db806642000102104bfffe100d24].ip6.arpa, the domain name that corresponds to drunkenmaster.movie.edu ’s network interface (when reached through RIR 2 and ISP B). The root nameservers would probably refer our nameserver to the ip6.arpa nameservers, which contain these records:

$ORIGIN ip6.arpa.
[x2001db802/36]    IN     DNAME      ip6.rir-1.net.
[x2001db806/36]    IN     DNAME      ip6.rir-2.net.

The second of these matches the beginning of the domain name we’re looking up, so the ip6.arpa nameservers reply to our nameserver with an alias that says:

[x2001db806642000102104bfffe100d24].ip6.arpa.  IN  CNAME
[x642000102104bfffe100d24].ip6.rir-2.net.

Notice that the first nine hex digits (the most significant 36 bits) of the address are stripped off, and the end of the target of the alias is now ip6.rir-2.net , since we know this address belongs to RIR 2. In ip6.rir-2.net , we find:

$ORIGIN ip6.rir-2.net.
[x6/4]   IN   DNAME     ip6.isp-b.net.

This turns the domain name in our new query:

[x642000102104bfffe100d24].ip6.rir-2.net

into:

[x42000102104bfffe100d24].ip6.isp-b.net

Next, our nameserver queries the ip6.isp-b.net nameservers for the new domain name. This record in the ip6.isp-b.net zone:

$ORIGIN ip6.isp-b.net.
[x42/8]    IN   DNAME    ip6.movie.edu.

turns the domain name we’re looking up into:

[x000102104bfffe100d24].ip6.movie.edu

The ip6.movie.edu zone, finally, contains the PTR record that gives us the domain name of the host we’re after:

$ORIGIN ip6.movie.edu.
[x000102104bfffe100d24/80]  IN   PTR   drunkenmaster.ip6.movie.edu.

(Though we could have used another DNAME just for subnet1, we didn’t.)

Mercifully, as a zone administrator you’ll probably only be responsible for maintaining PTR records like the ones in ip6.movie.edu . Even if you work for an RIR or ISP, creating DNAME records that extract the appropriate bits of the global routing prefix from your customers’ addresses isn’t too tough. And you gain the convenience of using a single zone datafile for your reverse-mapping information, even though each of your hosts has multiple addresses and can switch ISPs without changing all of your zone datafiles.



[*] And if you’re running a BIND 9 nameserver or BIND 8 from version 8.3.0 on, address match lists can include IPv6 addresses and IPv6 prefixes. These are described later in the chapter.

[*] This idea will seem familiar to anyone who’s ever used a journaling filesystem.

[*] BIND 9.1.0 and later nameservers go so far as to warn you that IP address-based access control lists are insecure if you try to use them.

[*] Actually, in the case of reloading a zone, the nameserver may not send the NOTIFY messages right away. To avoid causing a flurry of refresh queries from slaves, BIND nameservers reloading zones wait a fraction of each zone’s refresh interval before sending NOTIFY messages for that zone.

[*] Before BIND 8.2.3, you need to specify the number of bytes, rather than just “1M,” because of a bug.

[*] Actually, until BIND 9, PTR records weren’t rotated. BIND 9 rotates all record types.

[*] The right way to do this, in case you’re wondering, is to attach the addresses of foo1.bar.baz, foo2.bar.baz, and foo3.bar.baz directly to the domain name foo.bar.baz.

[*] Fixed order works only if you happen to have your records in DNSSEC’s sorted order. See Chapter 11 for details on DNSSEC’s sorting.

[*] Note that a root nameserver doesn’t normally receive recursive queries unless a nameserver’s administrator configured it to use the root server as a forwarder, a host’s administrator configured its resolver to use the root server as a nameserver, or a user pointed nslookup or dig at the root server. All of these happen more often than you’d expect, though.

[*] In general. Of course, programs designed to send nonrecursive queries, or programs that can be configured to send nonrecursive queries, such as nslookup or dig, will still work.

[*] And we really mean won’t respond. Whereas queriers disallowed by an allow-query access control list get a response back indicating that their query was refused, queries on the blackhole list get nothing back. Nada.

[*] Beware older versions of the Microsoft DNS Server, which can’t handle many-answers zone transfers that include DNS messages over 16 KB. If some of your slaves run this version, upgrade them or stick with the one-answer format until they’re upgraded.

[*] Chapter 14 describes better solutions to the “too many open files” problem than bumping up the limit on files.

[*] And, of course, the new ISP might use a different address registry, which would mean more bits to change.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset