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