In Chapter 4 we described the traditional method for making changes to zone data and how those changes are propagated: any changes to a zone are made on the zone's primary server, and secondary servers periodically poll the primary to check if the zone has changed. If the zone has new information, the secondaries perform a zone transfer to download the entire zone. This scheme is effective but inefficient and it's not suitable for every environment. The DNS console is great for making changes by hand, but what about automated changes (say you want to have a program change information in a zone)? It can also be frustrating to wait for all the secondaries to be updated with the new information. And for a large zone, it's a waste of time and bandwidth to transfer the entire zone if only a single record was added or deleted.
The next three sections describe relatively recent changes to the DNS protocol called dynamic update, NOTIFY, and incremental zone transfer that work together to address these issues. The Microsoft DNS Server implements all three.
11.1.1 Dynamic Update
Dynamic update was implemented in the Microsoft DNS Server starting with Windows 2000. Like many other protocols used by Windows, it's an Internet standard, defined in RFC 2136. Dynamic update allows a name server to be updated by sending it a message over the network. This is a big improvement over the traditional method, which requires a human to fire up the DNS console to make the change in person. Dynamic update allows nonhumans i.e., programs to easily update DNS information. Dynamic update is now used extensively in Windows: a modern Windows client uses it to add an A record to DNS for its IP address and recent Windows DHCP servers also use dynamic update to add PTR records as they assign leases.
No security is built into the dynamic update protocol. It's up to an individual name server to decide whether or not to accept an update message. About the only means of authentication a name server has is to look at the source IP address of the dynamic update message, and that's not a very strong means of authentication at all: it's easy to "spoof" or forge a packet's source IP address. And since a complete dynamic update message travels in a single UDP packet, all an attacker needs to know is an IP address that the name server accepting dynamic updates trusts. The Bad Guy just creates a dynamic update with a spoofed source IP address and sends it to the unsuspecting name server.
This deficiency begs for some stronger security based on cryptography, which fortunately has been developed. The DNS standards community developed a protocol extension to use transaction signatures to sign any kind of DNS message including dynamic updates sent between two parties: client to server, server to server, dynamic updater to server, etc.
The transaction signatures, or TSIGs for short, in DNS use a technique called HMAC Keyed-Hashing for Message Authentication (see RFC 2104) which employs a shared secret and a one-way cryptographic hash function to sign data. A shared secret is like a password known only to the two parties involved in exchanging data. A one-way cryptographic hash function computes a fixed-size checksum based on any amount of input. What differentiates a cryptographic hash function, such as MD5 or SHA1, from a run-of-the-mill checksum, such as a CRC (Cyclic Redundancy Check), is that it's computationally infeasible to find two different input streams that produce the same hash output. With a CRC checksum, on the other hand, the algorithm is easily reversible: given any checksum, it's trivial to calculate an input stream to generate that checksum. Another property of a good cryptographic hash function is that varying the input by even a small amount such as changing just one bit produces a major change in the hash output. In other words, the hash output is like a fingerprint of the original input.
A transaction signature is so-named because it's ephemeral: the signature applies only to a single transaction and is not reusable. Let's say a client wants to send a dynamic update signed with a TSIG to the appropriate name server. After generating the dynamic update message, it appends the secret it shares with the server to the message and runs everything through MD5. The output is the TSIG itself, which is placed into a TSIG resource record that goes in the dynamic update message. Since TSIGs are generated on the fly like this, you see a TSIG record only on a packet sniffer, never in the DNS console or a zone datafile. Note that TSIG doesn't encrypt the data being sent: it only authenticates it. HMAC is illustrated in Figure 11-1.
Figure 11-1. HMAC illustrated
One difficulty with TSIG is distributing the shared secrets. Imagine having hundreds of clients that need to send TSIG-signed dynamic updates to a name server: that would require generating hundreds of keys and distributing them securely to each client. Microsoft found itself in just such a predicament. As we discussed in Chapter 8, individual Windows clients do send dynamic updates to name servers. TSIG is a requirement for these transactions to happen securely, but it's not feasible to statically configure shared secrets on each Windows client. The solution: Kerberos to the rescue!
Windows Server 2003 (and Windows 2000 before it) uses Kerberos for authentication and authorization. Kerberos allows two parties who want to communicate securely to negotiate the necessary information to do so. Every Windows Server 2003 domain controller is a Kerberos Key Distribution Center, or KDC. Every modern Windows client and server is a Kerberos "principal." Every Kerberos principal shares a secret with the KDC. (This shared secret is generated when the host is joined to the domain.) The KDC acts as a trusted third party that allows two principals to communicate securely. For example, suppose a client named Alice wants to send an encrypted message to a client named Bob. Alice asks the KDC to help negotiate a session key with Bob. Alice and Bob don't (yet) trust each other, but they do trust the KDC, which facilitates distributing the session key to each of them. This explanation is quite an oversimplification of how Kerberos actually works, but it does show the underlying concepts.
Microsoft extended TSIG in Windows to use Kerberos. A Windows client that wants to send a TSIG-signed dynamic update message to a name server doesn't have to be statically configured to share a secret with that server. The client uses Kerberos to obtain a session key, which serves as a one-time shared secret. This variant of TSIG is called GSS-TSIG and is documented in an Internet-Draft.
The Microsoft DNS Server supports GSS-TSIG for securing dynamic updates, but only for zones that are AD-integrated (stored in Active Directory as opposed to a zone datafile). GSS-TSIG-secured dynamic updates allow quite fine-grained access control to a zone's contents. For example, the server can allow only the specific host that added an A record for itself to change or remove that record. This extra authorization can't be stored in a zone datafile there aren't the necessary fields so the server needs to store a zone in Active Directory to support secure dynamic updates. More information about AD-integrated zones and secure dynamic updates can be found in Chapter 8.
11.1.2 NOTIFY (Zone Change Notification)
As we described earlier, secondaries have traditionally used a polling scheme to determine when they need a zone transfer. The polling interval is called the refresh time and it's specified as a field in a zone's SOA record. Other parameters in the zone's SOA record govern other aspects of the polling mechanism.
But this scheme requires the secondaries to ask the primary, "Has the zone changed yet?", over and over. Wouldn't it be nice if the primary name server could tell its secondary servers when the information in a zone changed? After all, the primary name server knows the data has changed: every time a zone is changed with the DNS console or a dynamic update message is received, the server immediately changes the zone in its memory. The primary's notification can come soon after the actual modification instead of waiting for the refresh interval to expire.
RFC 1996 describes a mechanism that allows primary servers to notify their secondaries of changes to a zone's data. The Microsoft DNS Server implements this protocol, called NOTIFY for short.
NOTIFY works like this: when a primary name server notices a change to data in a zone, it sends a special notification message to all secondary servers for that zone. It uses the list of NS records in the zone to build the list of servers to notify. The primary removes any NS record corresponding to the local host, which prevents it from sending a notification message to itself. You can also override using the list of NS records and specify your own list of secondary servers to notify.
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. Other than that, the request looks much like a query for the SOA record for the zone: it specifies the zone's domain name, class, and a type of SOA.
When a secondary receives a NOTIFY request for a zone from one of its configured master name servers, it sends a NOTIFY response. The response tells the master that the secondary received the NOTIFY request and to stop sending NOTIFY messages for the zone. Then the secondary proceeds just as if the zone's refresh timer had expired: it queries the master server for the SOA record for the zone the master claimed had changed. If the serial number is higher, the secondary performs the zone transfer, using an incremental zone transfer if possible (see the next section for details on this new kind of zone transfer).
Why doesn't the secondary simply take the master's word that the zone has changed? It's possible that a miscreant could forge NOTIFY requests to our secondaries, causing lots of unnecessary zone transfers that might amount to a denial-of-service attack against our master server.
If the secondary 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 may not be able to notify all the secondary servers for the zone itself, since it's possible that some secondaries can't communicate directly with the primary and so use another secondary as their master. The Microsoft DNS Server follows this behavior if NOTIFY is enabled for a secondary zone (it's disabled by default for secondary zones) and you don't list a specific set of name servers to NOTIFY.
Here's how this process works in practice: on our network, terminator.movie.edu is the primary for movie.edu, and wormhole.movie.edu and zardoz.movie.edu are secondaries (as shown in Figure 11-2).
Figure 11-2. movie.edu zone transfer example
When we update movie.edu on terminator, terminator sends NOTIFY messages to wormhole and zardoz. Both secondaries check to see whether movie.edu's serial number has been incremented and, if they find it has, perform a zone transfer.
Let's also look at a more complicated zone transfer scheme. In Figure 11-3, a is the primary name server for the zone and b's master server, but b is c's master server. Moreover, b has two network interfaces.
Figure 11-3. Complex zone transfer example
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 been 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, 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.
Older BIND secondary name servers, and other name servers that don't support NOTIFY, respond with a "Not Implemented" (NOTIMP) error, wait until their refresh timers expire, and then transfer the zone. The Microsoft DNS Server just ignores the NOTIMP error.
NOTIFY is controlled on a zone-by-zone basis and is enabled by default for primary zones (and disabled by default for secondary zones). The controls for NOTIFY are somewhat hidden: highlight a zone in DNS console's left pane, select Action Properties, and choose the Zone Transfers tab of the zone properties window, which produces a window like the one shown in Figure 11-4.
Figure 11-4. Zone transfer configuration for movie.edu
Figure 11-5. NOTIFY configuration for movie.edu
Select the Notify button to open the window shown in Figure 11-5, which illustrates the NOTIFY configuration for the movie.edu zone on the zone's primary, terminator. You have two choices for configuring which servers get NOTIFY messages for a zone. The first is to check the Servers listed on the Name Servers tab, which lets the server decide based on the name servers listed in the zone's NS records. (The Name Servers tab of the zone properties window simply shows the name servers listed in the zone's NS records.) The second choice is to specify exactly which secondary servers should receive NOTIFY messages. This option is required if you have secondary servers not listed in the zone's NS records: such secondaries are effectively hidden, and the only way the primary knows to send NOTIFY messages to them is if you tell it to.
11.1.3 Incremental Zone Transfer
The Microsoft DNS Server in Windows 2003 supports a new kind of zone transfer. Incremental zone transfer, or IXFR for short, is specified in RFC 1995, and it does exactly what you'd expect based on its name. A traditional zone transfer always transfers the entire contents of a zone, even if only one record has changed. Incremental zone transfers allow a name server to send a list of just the records that have changed since the last zone transfer (whether it was a full or incremental one).
This new feature is critical for zones that change frequently. Imagine the scenario with dynamic update: every dynamic update is a change to the zone that requires a zone transfer. Doing a full zone transfer with every small change wastes bandwidth and CPU time. The situation is compounded when the zone being updated and transferred is large.
For IXFR to function, the master servers need to keep track of the differences between successive versions of the zone. A secondary requests an incremental zone transfer and presents its current serial number. The master server calculates and sends the changes needed on the secondary to make its version of the zone current. If the master server can't calculate the changes for whatever reason perhaps the secondary has an old version of the zone and the primary hasn't kept a record of changes that far back the primary is allowed to say "Sorry, but you've got to accept a full zone transfer."
A Microsoft DNS Server acting as a secondary requests an incremental zone transfer by default. If the master server doesn't support incremental zone transfer, the Microsoft DNS Server asks for a standard full zone transfer. A Microsoft DNS Server acting as a primary master stores a record of changes going back several versions. The number of versions the server keeps in memory depends on the zone's size: it keeps 25% of the total number of resource records of the zone, up to a total of 64,000. For example, given a zone of 100 resource records, the server would store changes corresponding to the last 25 versions of the zone. It responds with a full zone transfer instead of an incremental when it doesn't have the necessary information to produce the list of changes to the zone or when the list of changes would be larger than a full zone transfer.
AD-integrated zones introduce an extra wrinkle. Recall that every server for an AD-integrated zone stores the zone in Active Directory. Because of Active Directory's multimaster replication scheme, the notion of one server being a "primary" doesn't apply anymore. Instead, any of the zone's authoritative servers can accept a dynamic update for the zone. The change is stored locally and replicated to the other servers using Active Directory. This situation means that different servers can potentially apply changes to the zone in a different order. To maintain a consistent view of changes to a zone, a secondary must always use the same master server. If a particular master server becomes unavailable and a secondary is forced to use another, it automatically requests a full zone transfer for the first transfer from that server to avoid inconsistencies.
11.1.4 More Efficient Zone Transfers
As long as we're on the topic of zone transfers, we should mention another enhancement. A zone transfer 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 DNS message can carry many more records.
The Microsoft DNS Server understands a newer zone-transfer format that puts as many records as possible into a single DNS message. The resulting "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 DNS server uses the "many answers" format by default, which is fine if all your secondaries can understand it. Older BIND name servers (prior to Version 4.9.4) can't cope with this format and require the traditional one. Fortunately, you can tell the Microsoft DNS Server to use the traditional method with a server properties setting. Right-click on a server in the left pane of the DNS console and choose Properties, then select the Advanced tab. Click the box next to BIND secondaries. When this box is checked, the server sends traditional zone transfers to satisfy older BIND servers. The box is checked by default, but that doesn't affect zone transfers between two Microsoft DNS Servers. They recognize each other, and the master uses the "many answers" format to the secondary.
You should change this setting only if you have no BIND secondaries or if all your BIND secondaries are running Version 4.9.4 or later.