Traditionally, BIND slaves have used a polling scheme to determine when they need a zone transfer. The polling interval is called the refresh time. Other parameters in the zone's SOA record govern other aspects of the polling mechanism.
Wouldn't it be nice if the primary master name server could tell its slave servers when the information in a zone changed? After all, the primary master name server knows the data has changed: Someone signaled it with a SIGHUP, and it checked the mtime (the UNIX file modification time) of all of its zone data files to determine which had been changed. The primary's notification could come soon after the actual modification, instead of waiting for the refresh interval to expire.
RFC 1996 proposed a mechanism that would allow primary master servers to notify their slaves of changes to a zone's data. BIND 8 implements this scheme, called DNS NOTIFY for short.
DNS NOTIFY works like this: when a primary master name server notices a change to data in a zone, it sends a special request to all of the slave servers for that zone. It determines which servers are the slaves for the zone by looking at the list of NS records in the zone and taking out the one that points to the name server listed in the first record-specific field in the zone's SOA record as well as the local host.
The special NOTIFY request is identified by its opcode in the query header. The opcode for most queries is QUERY. NOTIFY messages have a special opcode, NOTIFY (duh). Other than that, the request looks very much like a query for the SOA record for the zone: it specifies the zone's domain name, class, and a type of SOA. The authoritative answer bit is also set.
When a slave receives a NOTIFY request for a zone from one of its configured master name servers, it responds with a NOTIFY response. The response tells the master that the slave received the NOTIFY request, so that it can stop sending it NOTIFY messages for the zone. Then the slave proceeds just as if the refresh timer had expired: it queries the master server for the SOA record for the zone that the master claimed 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 requests to our slaves, causing lots of unnecessary zone transfers, amounting to a denial of service attack against our master server.
If the slave actually transfers the zone, RFC 1996 says that it should issue its own NOTIFY requests to the other authoritative name servers for the zone. The idea is that the primary master may not be able to notify all of the slave servers for the zone itself, since it's possible some slaves can't communicate directly with the primary master and use another slave as their master. However, BIND 8 doesn't implement this, and BIND 8 slaves don't send NOTIFY messages unless explicitly configured to.
Here's how that works in practice. On our network, terminator.movie.edu is the primary master for movie.edu, and wormhole.movie.edu and zardoz.movie.edu are slaves, as shown in Figure 10.1.
When we update movie.edu on terminator, terminator sends NOTIFY messages to wormhole and zardoz. Both slaves check to see whether movie.edu's serial number has incremented, and when they find it has, perform a zone transfer.
Let's also look at a more complicated zone transfer scheme. Here, a is the primary master name server for the zone, and b's master server, but b is c's master server. Moreover, b has two network interfaces, as shown in Figure 10.2.
In this scenario, a notifies both b and c after the zone is updated. b checks to see whether the zone's serial number has incremented and initiates a zone transfer. However, c ignores a's NOTIFY message, because a is not c's configured master name server (b is). If b is explicitly configured to notify c, then after b's zone transfer completes, it sends c a NOTIFY message, which prompts c to check the serial number b holds for the zone.
Note also that if there's any possibility that c will receive a NOTIFY message 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 messages from the unknown interface.
BIND 4 slave name servers, and other name servers that don't support NOTIFY, will respond with a Not Implemented (NOTIMP) error. Note that Microsoft's Windows NT DNS Server does support DNS NOTIFY.
In BIND 8, DNS NOTIFY is on by default, but you can turn NOTIFY off globally with the substatement:
options { notify no; };
You can also turn NOTIFY on or off for a particular zone. For example, say you know that all of the slave servers for your acmebw.com zone are running BIND 4, and therefore don't understand NOTIFY requests. The zone statement:
zone "acmebw.com" { type master; file "db.acmebw"; notify no; };
avoids sending useless NOTIFY messages to the slaves for acmebw.com. A zone-specific NOTIFY setting overrides any global setting for that zone. Unfortunately, the current version of BIND doesn't allow you to turn off NOTIFY on a server-by-server basis.
BIND 8 even has a provision for adding servers to your "NOTIFY list" besides those in your zone's NS records. For example, you may have one or more unregistered slave servers (described in Chapter 8, Growing Your Domain) that you'd still like to pick up zone changes quickly. Or the server you're configuring may be a slave for the zone, but is the master server for another slave, and needs to send NOTIFY messages to it.
To add a server to your NOTIFY list, use the also-notify substatement of the zone statement:
zone "acmebw.com" { type master; file "db.acmebw.com"; notify yes; also-notify 15.255.152.4; };