Something is always changing on your network - the new workstations arrive, you finally retire or sell the relic, or you move a host to a different network. Each change means the db files must be modified. Should you make the changes manually? Should you wimp out and use a tool to help you?
First, we'll discuss how to make the changes manually. Then we'll talk about a tool to help out: h2n. Actually, we recommend that you use a tool to create the db files - we were kidding about that wimp stuff, okay? Or, at least use a tool to increment the serial number for you. The syntax of the DNS files lends itself to making mistakes. It doesn't help that the address and pointer records are in different files, which must agree with each other. However, even when you use a tool, it is critical to know what goes on when the files are updated, so we'll start with the manual method.
After creating your db files initially, it should be fairly apparent what needs to be changed when you add a new host. We'll go through the steps here in case you weren't the one to set up those files, or if you'd just like a checklist to follow. Make these changes to your primary master name server's DNS database files. If you make the change to your slave name server's backup files, the slave's data will change, but the next zone transfer will overwrite it.
Update the serial number in db.DOMAIN. The serial number is likely to be at the top of the file, so it's easy to do first and reduces the chance that you'll forget.
Add any A (address), CNAME (alias), and MX (mail exchanger) records for the host to the db.DOMAIN file. We added the following resource records to the db.movie file when a new host (cujo) was added to our network:
cujo IN A 192.253.253.5 ; cujo's internet address IN MX 10 cujo ; if possible, mail directly to cujo IN MX 20 terminator ; otherwise, deliver to our mail hub
Update the serial number and add PTR records to each db.ADDR file for which the host has an address. cujo only has one address, on network 192.253.253; therefore, we added the following PTR record to the db.192.253.253 file:
5 IN PTR cujo.movie.edu.
Restart the primary master name server by sending it a HUP signal; this forces it to load the new information:
#kill -HUP `cat /etc/named.pid`
After it has been restarted, the primary master name server will load the new data. Slave name servers will load this new data sometime within the time interval defined in the SOA record for refreshing their data.
Sometimes your users won't want to wait for the slaves to pick up the new data - they'll want it available right away. (Are you wincing or nodding knowingly as you read this?) Can you force a slave to load the new information right away? With version 8 masters and slaves, the slaves will pick up the new data quickly because the primary master notifies the slave of changes within 15 minutes of the change. If your name server is 4.9 or later, you can send it a HUP signal just as you did for your primary master name server. If your name server is 4.8.3 or earlier, remove all of the slave's backup files (or just the ones you want to force), kill the slave server, and start up a new one. Since the backup files are gone, the slave must immediately pull new copies of the zones.
To delete a host, remove the resource records from the db.DOMAIN and from each db.ADDR file pertaining to that host. Increment the serial number in each file you changed and restart your primary master name server.
Each of the DNS database files has a serial number. Every time the data in the db file is changed, the serial number must be incremented. If the serial number is not incremented, slave name servers for the zone will not pick up the updated data. The change is simple. If the original db file had the following SOA record:
movie.edu. IN SOA terminator.movie.edu. al.robocop.movie.edu. ( 100 ; Serial 10800 ; Refresh 3600 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL
the updated db file would have the following SOA record:
movie.edu. IN SOA terminator.movie.edu. al.robocop.movie.edu. ( 101 ; Serial 10800 ; Refresh 3600 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL
This simple change is the key to distributing the data to all of your secondaries. Failing to increment the serial number is the most common mistake made when updating a name server. The first few times you make a change to a DNS database file, you'll remember to update the serial number because this process is new and you are paying close attention. After the db file modifications become second nature, you'll make some "quickie" little change, forget to update the serial number...and none of the slaves will pick up the new data. That's why you should use a tool that updates the serial number for you! Your tool could be h2n or something written locally, but use a tool.
BIND does allow you to use a decimal serial number, like 1.1, but we recommend that you stay with integer values. Here's how BIND version 4 handles decimal serial numbers: if there is a decimal point in the serial number, BIND multiplies the digits to the left of the decimal by 1000. The digits to the right of the decimal point are then concatenated to the digits on the left. Therefore, a number like 1.1 is converted to 10001 internally. 1.10 is converted to 100010. This creates certain anomalies; for example, 1.1 is "greater" than 2, and 1.10 is "greater" than 2.1. Because this is so counterintuitive, it's best to stick with integer serial numbers.
There are several good ways to manage
integer serial numbers. The obvious way is just to use a counter:
increment the serial number by one each time the file is
modified. Another method is to derive the serial number from the
date. For example, you could use the eight-digit number formed by
YYYYMMDD
. Suppose today is January 15,
1997. In this form, your serial number would be 19970115. This scheme
only allows one update per day, though, and that may not be
enough. Add another two digits to this number to indicate how many
times the file has been updated that day. The first number for January
15, 1997, would then be 1997011500. The next modification that day
would change the serial number to 1997011501. This scheme allows 100
updates per day. h2n will generate the serial
number from the date if you use the -y option.
Whatever scheme you choose, the serial number must fit in a 32-bit
integer.
What do you do if the serial number on one of your zones accidentally becomes very large and you want to change it back to a more reasonable value? There is a way that works with all versions of BIND, and a couple of ways that work with version 4.9 and later.
The way that always works with all versions is to purge your slaves of any knowledge of the old serial number. Then you can start numbering from one (or any convenient point). Here's how. First, change the serial number on your primary master server and restart it; now the primary master server has the new integer serial number. Log onto one of your slave name server hosts and kill the server process with the command kill `cat /etc/named.pid`. Remove its backup copies of the db files (e.g., rm db.movie db.192.249.249 db.192.253.253). Start up your slave name server. Since the backup copies were removed, the slave must load a new version of the DNS database files - picking up the new serial numbers. This process must be repeated for each slave server. If there are any servers not under your control backing up your zones, you'll have to contact their administrators to get them to do the same.
If all of your secondaries are version 4.9 and later, you have two choices, and both involve two steps. One method involves synchronizing the serial number at zero, and the other involves incrementing the serial number by the largest amount possible.
If you set the zone serial number to zero, each 4.9 slave will transfer the zone the next time it checks. Serial number zero is special in that way. In fact, the zone will be transferred every time the slave checks, so don't forget to increment the serial number once all the slaves have synchronized on serial number zero. But there is a limit to how far you can increment the serial number. Read on.
The other method of fixing the serial number (with 4.9 and later slaves) will be easier to understand if we first cover some background material. The DNS serial number is a 32-bit unsigned integer. Its value ranges from 0 to 4,294,967,295. The DNS serial number uses sequence space arithmetic, which means that for any serial number, half of the numbers in the number space (2,147,483,647 numbers) are less than the serial number, and half of the numbers are larger.
Let's go over an example of sequence space numbers. Suppose the serial number is 5. Serial numbers 6 through (5 + 2,147,483,647) are larger than serial number 5. Serial numbers (5 + 2,147,483,649) through 4 are smaller serial numbers. Notice that the serial number wrapped around to 4 after reaching 4,294,967,295. Notice also that we didn't include the number (5 + 2,147,483,648) because this is exactly halfway around the number space, and it could be larger or smaller than 5, depending on the implementation. To be safe, don't use it.
Now back to the original problem. If your zone serial number is 25,000 and you want to start numbering at 1 again, you can speed through the serial number space in two steps. First, add the largest increment possible to your serial number (25,000 + 2,147,483,647 = 2,147,508,647). If the number you come up with is larger than 4,294,967,295 (the largest 32-bit value), you'll have wrap around to the beginning of the number space by subtracting 4,294,967,296 from it. After changing the serial number, you must wait for all of your secondaries to pick up a new copy of the zone. Second, change the zone serial number to its target value (1), which is now larger than the current serial number (2,147,508,647). After the secondaries pick up a new copy of the zone, you're done!
After you've been running a name server for a while, you may want to add data to your name server to help you manage your zone. Have you ever been stumped when someone asked you where one of your hosts is? Maybe you don't even remember what kind of host it is. Administrators have to manage larger and larger populations of hosts these days, making it easy to lose track of this information. The name server can help you out. And if one of your hosts is acting up and someone notices remotely, the name server can help them get in touch with you.
So far in the book, we've covered SOA, NS, A, CNAME, PTR, and MX records. These records are critical to everyday operation - name servers need them to operate, and applications look up data of these types. DNS defines more data types. The next most useful resource record types are TXT and RP; these can be used to tell you the machine's location and responsible person. For a complete list of the resource records, see Appendix A, DNS Message Format and Resource Records.
TXT stands for TeXT. These records are simply a list of strings, each less than 256 characters in length. Versions of BIND prior to 4.8.3 do not support TXT records. In version 4, BIND limits the db file TXT record to a single string of almost 2K of data.
TXT records can be used for anything you want; one use is to list a host's location:
cujo IN TXT "Location: machine room dog house"
BIND version 8 has the same 2K limit, but you can specify the TXT record as multiple strings:
cujo IN TXT "Location:" "machine room dog house"
Domain administrators will undoubtedly develop a love/hate relationship with the Responsible Person, or RP, record. The RP record can be attached to any domain name, internal or leaf, and indicates who is responsible for that host or zone. This will enable you to locate the miscreant responsible for the host peppering you with DNS queries, for example. But it will also lead people to you when one of your hosts acts up.
The record takes two arguments as its record-specific data: an electronic mail address, in domain name format, and a domain name, which points to additional data about the contact. The electronic mail address is in the same format the SOA record uses: it substitutes a "." for the "@". The next argument is a domain name, which must have a TXT record associated with it. The TXT record then contains free-format information about the contact, like full name and phone number. If you omit either field, you must specify the root domain (".") as a placeholder instead.
Here are some example RP (and associated) records:
robocop IN RP root.movie.edu. hotline.movie.edu. IN RP richard.movie.edu. rb.movie.edu. hotline IN TXT "Movie U. Network Hotline, (415) 555-4111" rb IN TXT "Richard Boisclair, (415) 555-9612"
Note that TXT records for root.movie.edu and richard.movie.edu aren't necessary, since they're only the domain-name encoding of electronic mail addresses, not real domain names.
This resource record didn't exist when BIND 4.8.3 was implemented, but BIND 4.9 supports it. Check the documentation for your version of the name server to see if it supports RP before trying to use it.
As you saw in Chapter 4, Setting Up BIND, we defined a well-structured process for converting host table information to name server information. We've written a tool in Perl to automate this process, called h2n. Using a tool to generate your data has one big advantage: there will be no syntax errors or inconsistencies in your database files - assuming we wrote h2n correctly! One common inconsistency is having an A (address) record for a host, but no corresponding PTR (pointer) record, or the other way around. Because these data are in separate files, it is easy to err.
What does h2n do? Given the /etc/hosts file and some command-line options, h2n creates the db files for your domain. As a system administrator, you keep the host table current. Each time you modify the host table, you run h2n again. h2n rebuilds each db file from scratch, assigning each new file the next higher serial number. It can be run manually, or from a cron script each night. If you use h2n, you'll never need to worry about forgetting to update the serial number.
First, h2n needs to know the name of your domain and your network numbers. These map conveniently into the db filenames: movie.edu data goes in db.movie, and network 192.249.249 data goes into db.192.249.249. The domain name and network number are specified with the -d and -n flags, as follows:
The domain name of your zone.
The network number of your network. If you are generating files for several networks, use several -n options on the command line. Omit trailing zeros from the network numbers.
The h2n command requires the -d flag and at least one -n flag; they have no default values. For example, to create the BIND database for the zone movie.edu, which consists of two networks, give the command:
%h2n -d movie.edu -n 192.249.249 -n 192.253.253
For greater control over the data, you can use other options:
The servers for the NS records. As with -n, use several -s options if you have multiple primary master or slave servers. A version 8 server will NOTIFY this list of servers when a zone changes. The default is the host on which you run h2n.
The host for the SOA record. host
must be the
primary master server to ensure proper operation of the version 8
NOTIFY feature. The default is the host on which
you run h2n.
The mail address of the person in charge of the domain's data. This defaults to root on the host on which you run h2n.
Other SOA values, not including the serial number, as a colon-separated list. These default to 10800:3600:604800:86400.
Read the h2n options from the named file
,
rather than from the command line. If you have lots of options, keep
them in a file.
Generate configuration files for version 4 or version 8. Version 4 is the default.
Generate the serial number from the date.
Here is an example that uses all the options mentioned so far:
%h2n -f opts
Contents of file opts:
-d movie.edu -n 192.249.249 -n 192.253.253 -s terminator.movie.edu -s wormhole -u al -h terminator -o 10800:3600:604800:86400 -v 8 -y
If an option requires a host name, you can provide either a full domain name (e.g., terminator.movie.edu), or just the host's name (e.g., terminator). If you give the host name only, h2n will form a complete domain name by adding the domain name given with the -d option. (If a trailing dot is necessary on the name, h2n will add it also.)
There are more options to h2n than we've shown here. For the complete list of options, you'll have to look at the manpage.
Of course, a few kinds of resource records aren't easy to generate from /etc/hosts - the necessary data simply aren't there. You may need to add these records manually. But since h2n always rewrites db files, won't your changes be overwritten?
h2n provides a "back door" for inserting this kind of data. Put these special records in a file named spcl.DOMAIN, where DOMAIN is the domain name of your zone. When h2n finds this file, it will "include" it within the database files by adding the line:
$INCLUDE spcl.DOMAIN
to the end of the db.DOMAIN file. (The $INCLUDE directive is described later in this chapter.) For example, the administrator of movie.edu may add extra MX records into the file spcl.movie so that users can mail to movie.edu directly instead of sending mail to hosts within movie.edu. Upon finding this file, h2n would put the line:
$INCLUDE spcl.movie
As explained in Chapter 4, the db.cache file tells your server where the servers for the "root" zone are. It must be updated periodically. The root name servers do not change very often, but they do change. A good practice is to check your db.cache file every month or two. In Chapter 4, we told you to get the servers by ftping to ftp.rs.internic.net. And that's probably your best method to keep current.
If you have on your system a copy of dig, a utility that works a lot like nslookup and is included in the BIND distribution, you can retrieve the current list of roots just by running:
%dig @a.root-servers.net . ns > db.cache