DekGenius.com
I l@ve RuBoard Previous Section Next Section

10.2 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 assign IP addresses dynamically. Nearly all ISPs assign addresses to dialup 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 name server is authoritative. An updater can find the authoritative name servers for a zone by retrieving the zone's NS records. If the name server 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 master name server for a zone, after all, has a "writable" copy of the zone data; all of the slaves get their copies of the zone data from the primary master, either directly or indirectly (through other slaves). Once the primary master 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.

A note on update forwarding: BIND name servers didn't implement update forwarding before 9.1.0, so it's particularly important when using BIND name servers older than 9.1.0 that you make sure the update is sent directly to the primary master name server for the zone you're trying to update. You can do this by ensuring that the primary master name server 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 of the authoritative name servers to send the update to.

For the most part, dynamic update functionality is used by programs like 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 exist.

prereq nxrrset

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

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
>

tells the server to add an address for mib.fx.movie.edu only if the domain name does not already exist. Note that the last blank line is nsupdate 's cue to send the update. Subtle, eh?

The command:

% 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.
>

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

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.

10.2.1 Dynamic Update and Serial Numbers

When a name server 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 name server doesn't necessarily increment the serial number for each dynamic update.

BIND 8 name servers defer updating a zone's serial number for as long as five minutes or 100 updates, whichever comes first. The deferral is intended to deal with a mismatch between a name server's ability to process dynamic updates and its ability to transfer zones: the latter may take significantly longer for large zones. When the name server 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 name servers update the serial number once for each dynamic update that is processed.

10.2.2 Dynamic Update and Zone Data Files

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 data file each time a record is added to or deleted from the zone could be prohibitively onerous for a name server. Writing a zone data file takes time, and the name server could conceivably receive tens or hundreds of dynamic updates each second.

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

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

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

On a BIND 8 name server, the log files should disappear hourly (though they may reappear very quickly if your name server receives lots of updates) as well as when the name server exits gracefully. On a BIND 9 name server, the log files won't disappear at all. Both name servers incorporate the record of the changes in the log file into the zone if the log file exists when the name server starts.

In case you're interested, BIND 8's log files 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 log files, unfortunately, aren't human-readable. Well, not to these humans, anyway.

10.2.3 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 name servers 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
};

10.2.4 TSIG-Signed Updates

Given that BIND 9.1.0 and later slave name servers can forward updates, what's the use of an IP address-based access control list? If the primary master name server allows updates from its slaves' addresses, then any forwarded update will be allowed, regardless of the original sender. That's not good.[3]

[3] BIND 9.1.0 goes so far as to warn you that IP address-based access control lists are insecure if you try to use them.

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 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 name servers, 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 master zones, since 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 name [types]

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

name

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

subdomain

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

wildcard

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

self

Matches when the domain name being updated is the same as the name in the identity (not name) 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, then the name 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 name field when using a nametype of self.

name, naturally, is a domain name appropriate to the nametype specified. For example, if you specify wildcard as the nametype, the name 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 NXT. (ANY is a convenient shorthand for "all types but NXT.") If you leave types out, it matches all record types except SOA, NS, SIG, and NXT.

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 mummy.fx.movie.eduuses a key called mummy.fx.movie.eduto sign its dynamic updates, we could restrict mummy.fx.movie.eduto 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 could restrict all of our clients to updating only their own address records by using:

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

Here's a more complicated example: to allow all clients the ability 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 records associated with Windows 2000 (in the _udp.fx.movie.edu, _tcp.fx.movie.edu, _sites.fx.movie.edu, and _msdcs.fx.movie.edu subdomains), you could use:

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

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.

In case you're wondering, the difference between:

grant identity subdomain fx.movie.edu

and:

grant identity wildcard fx.movie.edu:

is that the former allows the key specified by identity to modify records attached to fx.movie.edu (say, the zone's NS records) while the latter doesn't.

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 the next chapter for that.

    I l@ve RuBoard Previous Section Next Section