Chapter 17. Miscellaneous

“The time has come,” the Walrus said, “To talk of many things: Of shoes—and ships—and sealing-wax—Of cabbages—and kings—And why the sea is boiling hot—And whether pigs have wings.”

It’s time we tied up loose ends. We’ve already covered the mainstream of DNS and BIND, but there’s a handful of interesting niches we haven’t explored. Some of these may actually be useful to you, such as instructions on how to accommodate Active Directory with BIND; others may just be interesting. We can’t in good conscience send you out into the world without completing your education!

Using CNAME Records

We talked about CNAME resource records in Chapter 4. We didn’t tell you everything about CNAME records, though; we saved that for this chapter. When you set up your first nameservers, you probably wouldn’t have cared about the subtle nuances of the magical CNAME record. Some of this trivia is interesting, some is arcane. We’ll let you decide which is which.

CNAMEs Attached to Interior Nodes

If you’ve ever renamed your zone because of a company reorganization or acquisition, you may have considered creating a single CNAME record that pointed from the zone’s old domain name to its new domain name. For instance, if the fx.movie.edu zone were renamed magic.movie.edu, we’d be tempted to create a single CNAME record to map all the old domain names to the new names:

fx.movie.edu.  IN  CNAME  magic.movie.edu.

With this in place, you’d expect a lookup of empire.fx.movie.edu to result in a lookup of empire.magic.movie.edu. Unfortunately, this doesn’t work: you can’t have a CNAME record attached to an interior node like fx.movie.edu if it owns other records. Remember that fx.movie.edu has an SOA record and NS records, so attaching a CNAME record to it violates the rule that a domain name be either an alias or a canonical name, not both.

If you’re running BIND 9, though, you can use the brand-spanking-new DNAME record (introduced in Chapter 10) to create an alias from your zone’s old domain name to its new one:

fx.movie.edu.  IN  DNAME  magic.movie.edu.

The DNAME record can coexist with other record types at fx.movie.edu—like the SOA record and NS records that are undoubtedly there—but you can’t have any other domain names that end in fx.movie.edu. It’ll “synthesize” CNAME records from domain names in fx.movie.edu to like domain names in magic.movie.edu when the names in fx.movie.edu are looked up.

If you don’t have BIND 9, you’ll have to create aliases the old-fashioned way—a CNAME record for each individual domain name within the zone:

empire.fx.movie.edu.       IN  CNAME  empire.magic.movie.edu.
bladerunner.fx.movie.edu.  IN  CNAME  bladerunner.magic.movie.edu.

If the subdomain isn’t delegated, and consequently doesn’t have an SOA record and NS records attached, you can also create an alias for fx.movie.edu. However, this applies only to the domain name fx.movie.edu and not to other domain names in the fx.movie.edu zone.

Hopefully, the tool you use to manage your zone datafiles can handle creating CNAME records for you. (h2n, which was introduced in Chapter 4, does just that.)

CNAMEs Pointing to CNAMEs

You may have wondered whether it is possible to have an alias (CNAME record) pointing to another alias. This might be useful in situations where an alias points from a domain name outside your zone to a domain name inside your zone. You may not have any control over the alias outside your zone. What if you want to change the domain name it points to? Can you simply add another CNAME record?

The answer is yes: you can chain together CNAME records. The BIND implementation supports it, and the RFCs don’t expressly forbid it. But while you can chain CNAME records, is it a wise thing to do? The RFCs recommend against it because of the possibility of creating a CNAME loop and because it slows resolution. You may be able to do it in a pinch, but you probably won’t find much sympathy on the Net if something breaks. And all bets are off if a new (non-BIND-based) nameserver implementation emerges.[*]

CNAMEs in the Resource Record Data

For any other record besides a CNAME record, you must use canonical domain names in the resource record data. Applications and nameservers won’t operate correctly otherwise. As we mentioned back in Chapter 5, for example, sendmail recognizes only the canonical name of the local host on the right side of an MX record. If sendmail doesn’t recognize the local host’s name, it won’t strip the correct MX records out when paring down the MX list and may try to deliver mail to itself or to less preferred hosts, causing mail to loop.

BIND 8 nameservers log messages like these when they encounter aliases on the right side of a record:

Sep 27 07:43:48 toystory named[22139]: "digidesign.com IN NS" points to a CNAME
(ns1.digidesign.com)
Sep 27 07:43:49 toystory named[22139]: "moreland.k12.ca.us IN MX" points
to a CNAME (mail.moreland.k12.ca.us)

BIND 9 nameservers, unfortunately, don’t seem to notice.

Multiple CNAME Records

One pathological configuration that honestly hadn’t occurred to us—and many pathological configurations have occurred to us—is multiple CNAME records attached to the same domain name. Some administrators use this with round robin to rotate between RRsets. For example, the records:

fullmonty  IN  CNAME  fullmonty1
fullmonty  IN  CNAME  fullmonty2
fullmonty  IN  CNAME  fullmonty3

can be used to return all the addresses attached to fullmonty1, then all the addresses of fullmonty2, then all the addresses of fullmonty3 on a nameserver that didn’t recognize this as the abomination it is. (It violates the “CNAME and other data” rule, for one.)

BIND 4 doesn’t recognize this as a misconfiguration; BIND 8 and 9.1.0 and later do. BIND 8 lets you permit it if you want to with:

options {
                multiple-cnames yes;
};

In BIND 9, there’s no option to allow it. The default, naturally, is to disallow it.

Looking Up CNAMEs

At times you may want to look up a CNAME record itself, not data for the canonical name. With nslookup or dig, this is easy to do. You can either set the query type to cname, or set the query type to any and then look up the name:

%nslookup
Default Server:  wormhole
Address:  0.0.0.0

> set query=cname
> toys
Server:  wormhole
Address:  0.0.0.0

toys.movie.edu  canonical name = toystory.movie.edu

> set query=any
> toys
Server:  wormhole
Address:  0.0.0.0

toys.movie.edu  canonical name = toystory.movie.edu
> exit

% dig toys.movie.edu cname
; <<>> DiG 9.3.2 <<>> toys.movie.edu cname
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43984
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 4

;; QUESTION SECTION:
;toys.movie.edu.                    IN    CNAME

;; ANSWER SECTION:
toys.movie.edu.         86400 IN CNAME     toystory.movie.edu.

Finding Out a Host’s Aliases

One thing you can’t easily do with DNS is find out a host’s aliases. With the host table, it’s easy to find both the canonical name of a host and any aliases: no matter which you look up, they’re all there, together, on the same line:

%grep toystory /etc/hosts
192.249.249.3  toystory.movie.edu toystory toys

With DNS, however, if you look up the canonical name, all you get is the canonical name. There’s no easy way for the nameserver or the application to know whether aliases exist for that canonical name.

%nslookup
Default Server:  wormhole
Address:  0.0.0.0

> toystory
Server:  wormhole
Address:  0.0.0.0

Name:    toystory.movie.edu
Address:  192.249.249.3

If you use nslookup or dig to look up an alias, you’ll see that alias and the canonical name. nslookup and dig report both the alias and the canonical name in the message. But you won’t see any other aliases that might point to that canonical name:

%nslookup
Default Server:  wormhole
Address:  0.0.0.0

> toys
Server:  wormhole
Address:  0.0.0.0

Name:    toystory.movie.edu
Address:  192.249.249.3
Aliases:  toys.movie.edu

> exit

% dig toys.movie.edu

; <<>> DiG 9.3.2 <<>> toys.movie.edu
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29782
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 4

;; QUESTION SECTION:
; toys.movie.edu.                    IN    A

;; ANSWER SECTION:
toys.movie.edu.         86400 IN CNAME     toystory.movie.edu.
toystory.movie.edu.     86400 IN A         192.249.249.3

About the only way to find out all the CNAMEs for a host is to transfer the whole zone and pick out the CNAME records in which that host is the canonical name:

%nslookup
Default Server:  wormhole
Address:  0.0.0.0

> ls -t cname movie.edu
[wormhole.movie.edu]
$ORIGIN movie.edu.
toys                    1D IN CNAME     toystory
wh                      1D IN CNAME     wormhole
mi                      1D IN CNAME     monsters-inc
>

Even this method shows you the aliases only within that zone; there could be aliases in a different zone, pointing to canonical names in this zone.

Wildcards

Something else we haven’t covered in detail yet is DNS wildcards. There are times when you want a single resource record to cover any possible name, rather than creating zillions of resource records that are all the same except for the domain name to which they apply. DNS reserves a special character, the asterisk (*), to use in zone datafiles as a wildcard name. It matches any number of labels in a name as long as there isn’t an exact match with a name already in the nameserver’s database.

Most often, you’d use wildcards to forward mail to non-Internet-connected networks. Suppose our site wasn’t connected to the Internet, but we had a host that relayed mail between the Internet and our network. We can add a wildcard MX record to the movie.edu zone for Internet consumption that points all our mail to the relay. Here is an example:

*.movie.edu.  IN  MX  10 movie-relay.nea.gov.

Since the wildcard matches one or more labels, this resource record applies to names such as toystory.movie.edu , empire.fx.movie.edu, or casablanca.bogart.classics.movie.edu. The danger with wildcards is that they clash with search lists. This wildcard also matches cujo.movie.edu.movie.edu, making wildcards dangerous to use in our internal zone data. Remember that some versions of sendmail apply the search list when looking up MX records:

%nslookup
Default Server:  wormhole
Address:  0.0.0.0

> set type=mx                                   Look up MX records
> cujo.movie.edu                                for cujo
Server:  wormhole
Address:  0.0.0.0

cujo.movie.edu.movie.edu                        This isn't a real host's name!
        preference = 10, mail exchanger = movie-relay.nea.gov

What are other limitations of wildcards? Wildcards do not match domain names for which there is already data. Suppose we did use wildcards within our zone data, as in these partial contents of db.movie.edu:

*     IN  MX  10 mail-hub.movie.edu.
et    IN  MX  10 et.movie.edu.
jaws  IN  A   192.253.253.113
fx    IN  NS  bladerunner.fx.movie.edu.
fx    IN  NS  outland.fx.movie.edu.

Mail to toystory.movie.edu is sent to mail-hub.movie.edu, but mail to et.movie.edu is sent directly to et.movie.edu. An MX lookup of jaws.movie.edu results in a response saying there was no MX data for that domain name. The wildcard doesn’t apply because an A record exists. The wildcard also doesn’t apply to domain names in fx.movie.edu because wildcards don’t apply across delegation. Nor does the wildcard apply to the domain name movie.edu, because the wildcard amounts to zero or more labels followed by a dot, followed by movie.edu.

A Limitation of MX Records

While we are on the topic of MX records, let’s talk about how they can result in mail taking a longer path than necessary. The MX records are a list of data returned when the domain name of a mail destination is looked up. The list isn’t ordered according to which exchanger is closest to the sender. Here is an example of this problem. Your non-Internet-connected network has two hosts that can relay Internet mail to your network. One host is in the United States, and one host is in France. Your network is in Greece. Most of your mail comes from the United States, so you have someone maintain your zone and install two wildcard MX records—the highest preference to the U.S. relay and a lower preference to the relay in France. Since the United States relay is at a higher preference, all mail will go through that relay (as long as it is reachable). If someone in France sends you a letter, it will travel across the Atlantic to the United States and back because there is nothing in the MX list to indicate that the French relay is closer to that sender.

Dial-up Connections

Another recent development in networking (recent only relative to DNS’s age) that presents a challenge to DNS is the dial-up Internet connection. When the Internet was young, and DNS was born, there was no such thing as a dial-up connection. With the enormous explosion in the Internet’s popularity and the propagation of Internet service providers who offer dial-up Internet connectivity to the masses, a whole new breed of problems with name service has been introduced.

The basic goal when setting up DNS to work with dial-up is to enable every host in your network to resolve the domain names of every host it needs to access. (Of course, when your connection to the Internet is down, your hosts probably don’t need to resolve Internet domain names.) If you’re using dial-on-demand, there’s the additional goal of minimizing unnecessary dialouts: if you’re looking up the domain name of a host on your local network, that shouldn’t require your router to bring up a connection to the Internet.

We’ll separate dial-up connections into two categories: manual dial-up, by which we mean a connection to the Internet that must be brought up by a user, and dial-on-demand, which implies the use of a device—often a router, but sometimes just a host running Linux or another server operating system—to connect to the Internet automatically whenever hosts generate traffic bound for the Internet. We’ll also describe two scenarios for each category of dial-up: one in which you have just one host dialing up a connection to the Internet, and one in which you have a small network of hosts dialing up a connection. Before we talk about these scenarios, though, let’s discuss what causes dialouts and how to avoid them.

What Causes Dialouts

Many users, particularly in Europe, where ISDN is popular, connect to the Internet via dial-on-demand connections. Nearly all of these users want to minimize, if not completely prevent, unnecessary connections to the Internet. Connection setup is often more expensive than successive minutes, and always takes time.

BIND nameservers, unfortunately, aren’t terribly well suited to running behind dial-on-demand connections. They periodically send system queries to look up the current list of root nameservers, even when the nameserver isn’t resolving domain names. And the operation of the search list can cause the nameserver to query remote nameservers. For example, say your local domain name is tinyoffice.megacorp.com and you have a local nameserver authoritative for that zone. Your default search list, on some resolvers, might include:

tinyoffice.megacorp.com
megacorp.com

Let’s say you try to FTP to one of your local systems, deadbeef.tinyoffice.megacorp.com, but you misspell it deadbeer:

%ftp deadbeer

Because of your search list, your resolver first looks up deadbeer.tinyoffice.megacorp.com. Your local nameserver, authoritative for the tinyoffice.megacorp.com zone, can tell that domain name doesn’t exist. But then your resolver appends the second domain name in the search list and looks up deadbeer.megacorp.com. To figure out whether that domain name exists, your nameserver needs to query a megacorp.com server, which requires bringing up the dial-on-demand link.

Avoiding Dialouts

There are several general techniques that can help you minimize unnecessary dialouts. The first, and probably simplest, is to run a version of BIND that supports negative caching (which means any version of BIND 8 or 9). That way, if you mistakenly put deadbeer into a configuration file, your nameserver looks up deadbeer.megacorp.com once, and then caches the fact that the domain name doesn’t exist for the duration of megacorp.com’s negative caching TTL.

Another technique is to use a minimal search list. If your local domain name is tinyoffice.megacorp.com, you could make do with a search list of just tinyoffice.megacorp.com. That way, a typo won’t cause a dialout.

Using a modern resolver is also important. The default search list for a post-BIND 4.9 resolver is just the local domain name, which qualifies as “minimal” in our book. And a modern resolver knows to try a domain name with dots as-is, even if it doesn’t end in a dot.

Finally, you can use other naming services, such as /etc/hosts, for local name resolution and configure your resolvers to use DNS only if a name cannot be found in /etc/hosts. As long as you keep the names of all your local hosts in /etc/hosts, you won’t need to worry about needless connections to the Internet.

Now let’s apply these techniques to our scenarios.

Manual Dial-up with One Host

The easiest way to deal with the simple dial-up scenario is to configure your host’s resolver to use a nameserver provided by your Internet service provider. Most ISPs run nameservers for their subscribers’ use. If you’re not sure whether your ISP provides nameservers for your use, or if you don’t know what its IP addresses are, check its web site, send an email, or call the provider.

Some operating systems, such as Windows NT, Windows 2000, and Windows XP, let you define a set of nameservers for use with a particular dial-up provider. So, for example, you can configure one set of nameservers to use when you dial up UUNet and another to use when you dial up your office. This is useful if you dial in to multiple ISPs.

This configuration is usually adequate for most casual dial-up users. Name resolution will fail unless the dial-up connection is up, but that’s not likely to be a problem because there’s no use for Internet name service without Internet connectivity.

Some of you, however, may want to run a nameserver when your dial-up connection is active. It can help your performance by caching domain names you look up frequently, for example. This is easy to set up with a Unix-like operating system such as Linux: you’ll typically use a script like ifup to bring up your dial-up connection and ifdown to bring it down. If that’s the case, there are probably also scripts called ifup-post and ifdown-post that ifup and ifdown call, respectively, after they’ve done most of their work. You can start named as named or with ndc start in ifup-post, and shut it down with ndc stop or rndc stop in ifdown-post. About the only other thing you’d need to do is set your local domain name in resolv.conf. The default resolver behavior, querying a nameserver on the local host, should do fine both when the nameserver’s running and when it’s not.

Manual Dial-up with Multiple Hosts

The simplest solution to use with the multiple host/manual dial-up scenario is similar to the resolver-only configuration. You can configure your resolvers to use your ISP’s nameservers, but also configure the resolvers to check /etc/hosts (or NIS, if you go for that sort of thing) before querying a nameserver. Then make sure your /etc/hosts file contains the names of all the hosts on your local network.

If you’d like to run a nameserver locally, you need to modify this configuration only slightly: configure the resolvers to use your local nameserver instead of your ISP’s. This gives you the benefits of local caching, but local name resolution will work (via /etc/hosts) even when your connection to the Internet is down. You may as well start and stop the local nameserver from ifup-post and ifdown-post, as described earlier.

For those of you who really want to use DNS for all name resolution, you can forgo the /etc/hosts file and create forward-mapping and reverse-mapping zones on your local nameserver for your hosts. You should trim your resolvers’ search lists to the bare minimum, though, to minimize the chance that you’ll induce your nameserver to look up some wacky remote domain name.

Dial-on-Demand with One Host

If you have a single host with a dial-on-demand connection to the Internet, your simplest solution is still a resolver-only configuration. Configure your resolver to use your ISP’s nameservers, and when the resolver needs to look up a domain name, it’ll query one of those nameservers and bring up the link. If there are some domain names that your host looks up routinely as part of “housekeeping,” such as localhost or 1.0.0.127.in-addr.arpa, you can add the appropriate entries to /etc/hosts and configure your resolver to check /etc/hosts before querying a nameserver.

If you’d like to run a nameserver locally, make sure it is able to map localhost and 1.0.0.127.in-addr.arpa to 127.0.0.1 and localhost, respectively, and trim your search list to the minimum.

If your nameserver brings up the link more than you think it should, try turning on query logging (with ndc querylog on a BIND 8 nameserver or rndc querylog on a BIND 9.1.0 or later nameserver) and look for the domain names that bring up the link. If many of them are in a single zone, you might consider configuring your local nameserver as a slave for that zone. At least that way, you’ll bring up the link at most only once per refresh interval to resolve domain names in the zone.

Dial-on-Demand with Multiple Hosts

The simplest solution in this scenario is exactly the same as the first solution we described earlier in the section "Manual Dialup with Multiple Hosts“: a resolver-only configuration with the resolvers configured to check /etc/hosts before querying a nameserver. As with all dial-on-demand configurations, you’ll want to trim your search list.

Alternatively, you could try one of the two variants: running a local nameserver and using it as a backup to /etc/hosts, or creating forward- and reverse-mapping zones for the local hosts on the local nameserver.

Running Authoritative Nameservers over Dial-on-Demand

This may sound like a silly subject to some of you—who would run an authoritative nameserver behind a dial-on-demand connection?—but in some parts of the world, where bandwidth and Internet connectivity aren’t easy to come by, this is a necessity. And, believe it or not, BIND provides a mechanism to accommodate such nameservers.

If you run an authoritative nameserver behind a dial-on-demand link, you want to concentrate zone maintenance activities into as short a window as possible. If your nameserver is authoritative for 100 zones, you’d rather not have zone refresh timers popping every few minutes and the resulting SOA queries bringing up the dial-on-demand link over and over again.

With BIND 8.2 and newer nameservers and BIND 9.1.0 and later nameservers, you can configure a heartbeat interval. The heartbeat interval is how frequently you’d like your nameserver to bring up its dial-on-demand connection, in minutes:

options {
    heartbeat-interval 180;      // 3 hours
};

The default is 60 minutes, and you can disable zone maintenance by setting the interval to 0.

If you then mark one or more of your zones as dial-up zones, the nameserver will try to concentrate all maintenance of that zone into a short period and to perform the maintenance no more often than the heartbeat interval. For a slave zone, that means inhibiting the normal refresh timer (even ignoring the refresh interval, if it’s smaller than the heartbeat interval!) and querying the master for the zone’s SOA record only at the heartbeat interval. For a master zone, that means sending out NOTIFY messages, which will presumably bring up the dial-on-demand link and trigger a refresh on the slaves.

To mark all of a nameserver’s zones as dial-up zones, use the dialup substatement in an options statement:

options {
    heartbeat-interval 60;
    dialup yes;
};

To mark a single zone as a dial-up zone, use the dialup substatement in the zone statement:

zone "movie.edu" {
    type master;
    file "db.movie.edu";
    dialup yes;
};

Dial-up zones are also useful in another, perhaps unintended way: on nameservers that serve as slaves for thousands of zones. Some ISPs provide slave service on a large scale but get bitten by miscreants who set their zone’s refresh intervals far too low. Their nameservers end up swamped with sending out SOA queries for those zones. By configuring all the zones as dial-up zones and setting the heartbeat interval to something reasonable, ISPs can prevent this.

Network Names and Numbers

The original DNS specifications didn’t provide the ability to look up a network name based on a network number—a feature that was provided by the original HOSTS.TXT file. Since then, RFC 1101 has defined a system for storing network names; this system also works for subnets and subnet masks, so it goes significantly beyond HOSTS.TXT. Moreover, it doesn’t require any modification to the nameserver software at all; it’s based entirely on the clever use of PTR and A records.

Remember that to map an IP address to a name in DNS, you reverse the IP address, append in-addr.arpa, and look up PTR records. This same technique maps a network number to a network name—for example, to map network 15/8 to “HP Internet.” To look up the network number, include the network bits and pad them with trailing zeros to make four bytes, and look up PTR data just as you did with a host’s IP address. For example, to find the network name for the old ARPAnet, network 10/8, look up PTR data for 0.0.0.10.in-addr.arpa. You get back an answer like ARPAnet.ARPA.

If the ARPAnet is subnetted, you’ll also find an address record at 0.0.0.10.in-addr.arpa. The address would be the subnet mask, 255.255.0.0, for instance. If you were interested in the subnet name instead of the network name, you apply the mask to the IP address and look up the subnet number.

This technique allows you to map the network number to a name. To provide a complete solution, there must be a way to map a network name to its network number. This, again, is accomplished with PTR records. The network name has PTR data that points to the network number (reversed with in-addr.arpa appended).

Let’s see what the data might look like in HP’s zone datafiles (the HP Internet has network number 15/8) and step through mapping a network number to a network name.

Partial contents of the file db.hp.com:

;
; Map HP's network name to 15.0.0.0.
;
hp-net.hp.com.            IN  PTR 0.0.0.15.in-addr.arpa.

Partial contents of the file db.corp.hp.com:

;
; Map corp's subnet name to 15.1.0.0.
;
corp-subnet.corp.hp.com.  IN  PTR 0.0.1.15.in-addr.arpa.

Partial contents of the file db.15:

;
; Map 15.0.0.0 to hp-net.hp.com.
; HP's subnet mask is 255.255.248.0.
;
0.0.0.15.in-addr.arpa.    IN  PTR hp-net.hp.com.
                          IN  A   255.255.248.0

Partial contents of the file db.15.1:

;
; Map the 15.1.0.0 back to its subnet name.
;
0.0.1.15.in-addr.arpa.    IN  PTR corp-subnet.corp.hp.com.

Here’s the procedure to look up the subnet name for the IP address 15.1.0.1:

  1. Apply the default network mask for the address’s class. Address 15.1.0.1 is a Class A address, so the mask is 255.0.0.0. Applying the mask to the IP address makes the network number 15.

  2. Send a query (type=A or type=ANY) for 0.0.0.15.in-addr.arpa.

  3. The query response contains address data. Since there is address data at 0.0.0.15.in-addr.arpa (the subnet mask, 255.255.248.0), apply the subnet mask to the IP address. This yields 15.1.0.0.

  4. Send a query (type=A or type=ANY) for 0.0.1.15.in-addr.arpa.

  5. The query response does not contain address data, so 15.1.0.0 is not further subnetted.

  6. Send a PTR query for 0.0.1.15.in-addr.arpa.

  7. The query response contains the network name for 15.1.0.1: corp-subnet.corp.hp.com.

In addition to mapping between network names and numbers, you can also list all the networks for your zone with PTR records:

movie.edu.  IN  PTR  0.249.249.192.in-addr.arpa.
            IN  PTR  0.253.253.192.in-addr.arpa.

Now for the bad news: despite the fact that RFC 1101 contains everything you need to know to set this up, there’s very little software we know of that actually uses this type of network name encoding, and very few administrators go to the trouble of adding this information. Until software actually makes use of DNS-encoded network names, about the only reason for setting this up is to show off. But that’s a good enough reason for many of us.

Additional Resource Records

There are a number of resource records that we haven’t covered yet in this book. Some of these are experimental, but some are on the standards track and are coming into more prevalent use. We’ll describe them here to give you a little head start in getting used to them.

AFSDB

AFSDB has a syntax like that of the MX record, and semantics a bit like that of the NS record. An AFSDB record gives either the location of an AFS cell database server or of a DCE cell’s authenticated nameserver. The type of server the record points to and the name of the host running the server are contained in the record-specific data portion of the record.

So what’s an AFS cell database server? Or AFS, for that matter? AFS originally stood for the Andrew File System, designed by the good folks at Carnegie-Mellon University as part of the Andrew Project. (It’s now an IBM product.) AFS is a network filesystem, like NFS, but one that handles the latency of wide area networks much better than NFS does and provides local caching of files to enhance performance. An AFS cell database server runs the process responsible for tracking the location of filesets (groups of files) on various AFS fileservers within a cell (a logical group of hosts). So being able to find the AFS cell database server is the key to finding any file in the cell.

And what’s an authenticated nameserver? It holds location information about all sorts of services available within a DCE cell. A DCE cell? That’s a logical group of hosts that share services offered by The Open Group’s Distributed Computing Environment (DCE).

And now, back to our story. To access another cell’s AFS or DCE services across a network, you must first find out where that cell’s cell database servers or authenticated nameservers are—hence the new record type. The domain name the record is attached to gives the name of the cell the server knows about. Cells often share names with DNS domains, so this usually doesn’t look at all odd.

As we said, the AFSDB record’s syntax is like the MX record’s syntax. In place of the preference value, you specify the number 1 for an AFS cell database server or 2 for a DCE authenticated nameserver.

In place of the mail exchanger host, you specify the name of the host running the server. Simple!

Suppose an fx.movie.edu system administrator sets up a DCE cell (which includes AFS services) because she wants to experiment with distributed processing to speed up graphics rendering. She runs both an AFS cell database server and a DCE nameserver on bladerunner.fx.movie.edu , another cell database server on empire.fx.movie.edu, and another DCE nameserver on aliens.fx.movie.edu. She should set up the AFSDB records as follows:

; Our DCE cell is called fx.movie.edu, same as the domain name of the zone
fx.movie.edu.  IN  AFSDB  1 bladerunner.fx.movie.edu.
               IN  AFSDB  2 bladerunner.fx.movie.edu.
               IN  AFSDB  1 empire.fx.movie.edu.
               IN  AFSDB  2 aliens.fx.movie.edu.

LOC

RFC 1876 defines an experimental record type, LOC, that allows zone administrators to encode the locations of their computers, subnets, and networks. In this case, location means latitude, longitude, and altitude. Future applications could use this information to produce network maps, assess routing efficiency, and more.

In its basic form, the LOC record takes latitude, longitude, and altitude (in that order) as its record-specific data. Latitude and longitude are expressed in the format:

<degrees> [minutes [seconds.<fractional seconds>]] (N|S|E|W)

Altitude is expressed in meters.

If you’re wondering how in the world you’re going to get that data, check out “RFC 1876 Resources” at http://www.ckdhr.com/dns-loc. This site, created by Christopher Davis, one of the authors of RFC 1876, is an indispensable collection of information, useful links, and utilities for people creating LOC records.

If you don’t have your own Global Positioning System receiver to carry around to all of your computers—and we know many of you do—two sites that may come in handy are Tele Atlas’s Eagle Geocoding at http://www.geocode.com/modules.php?name=TestDrive_Eagle, which you can use to find the latitude and longitude of most addresses in the United States, and AirNav’s Airport Information at http://www.airnav.com/airports, which lets you find the elevation of the closest airport to you. If you don’t have a major airport near you, don’t worry: the database even includes the helipad at your neighborhood hospital!

Here’s a LOC record for one of our hosts:

huskymo.boulder.acmebw.com.  IN  LOC  40 2 0.373 N 105 17 23.528 W 1638m

Optional fields in the record-specific data allow you to specify how large the entity you’re describing is, in meters (LOC records can describe networks, after all, which can be quite large), as well as the horizontal and vertical precision. The size defaults to one meter, which is perfect for a single host. Horizontal precision defaults to 10,000 meters, and vertical precision to 10 meters. These defaults represent the size of a typical zip or postal code, the idea being that you can fairly easily find a latitude and longitude given a zip code.

You can also attach LOC records to the names of subnets and networks. If you’ve taken the time to enter information about the names and addresses of your networks in the format described in RFC 1101 (covered earlier in this chapter), you can attach LOC records to the network names:

;
; Map HP's network name to 15.0.0.0.
;
hp-net.hp.com.   IN   PTR 0.0.0.15.in-addr.arpa.
                 IN   LOC 37 24 55.393 N 122 8 37 W 26m

SRV

Locating a service or a particular type of server within a zone is a difficult problem if you don’t know which host it runs on. Some zone administrators have attempted to solve this problem by using service-specific aliases in their zones. For example, at Movie U., we created the alias ftp.movie.edu and pointed it to the domain name of the host that runs our FTP archive:

ftp.movie.edu.      IN    CNAME           plan9.fx.movie.edu.

This makes it easy for people to guess a domain name that will get them to our FTP archive, and separates the domain name people use to access the archive from the domain name of the host it runs on. If we want to move the archive to a different host, we can simply change the CNAME record.

The experimental SRV record, introduced in RFC 2782, is a general mechanism for locating services. In addition, SRV provides powerful features that allow zone administrators to distribute load and provide backup services, similar to what the MX record provides. In fact, you might think of an SRV record as a generalized MX record, useful for services besides SMTP-based electronic mail.

A unique aspect of the SRV record is the format of the domain name it’s attached to. Like service-specific aliases, the domain name to which an SRV record is attached gives the name of the service sought, as well as the protocol it runs over, concatenated with a domain name. The labels representing the service name and the protocol begin with an underscore to distinguish them from labels in the domain name of a host. So, for example:

_ftp._tcp.movie.edu

represents the SRV records someone ftp‘ing to movie.edu should retrieve in order to find the movie.edu FTP servers, while:

_http._tcp.www.movie.edu

represents the SRV records someone accessing the URL http://www.movie.edu should look up in order to find the www.movie.edu web servers.

The names of the service and protocol should appear in IANA’s list of port number assignments (available at http://www.iana.org/assignments/port-numbers) or be unique names used only locally. Don’t use the port or protocol numbers, just the names.

The SRV record has four resource record-specific fields: priority, weight, port, and target. Priority, weight, and port are unsigned 16-bit numbers (between 0 and 65535). Target is a domain name.

Priority

Works very similarly to the preference in an MX record: the lower the number in the priority field, the more desirable the associated target. When searching for hosts offering a given service, clients should try all targets at a lower priority value before trying those at a higher priority value.

Weight

Allows zone administrators to distribute load to multiple targets. Clients should query targets that have the same priority in proportion to their weight. For example, if one target has a priority of 0 and a weight of 1, and another target also has a priority of 0 but a weight of 2, the second target should receive twice as much load (in queries, connections, whatever) as the first. It’s up to the service’s clients to direct that load: they typically use a system call to choose a random number. If the number is, say, in the top one-third of the range, they try the first target, and if the number is in the bottom two-thirds of the range, they try the second target.

Port

Specifies the port on which the service being sought is running. This allows zone administrators to run servers on nonstandard ports. For example, an administrator can use SRV records to point web browsers at a web server running on port 8000 instead of the standard HTTP port (80).

Target

Specifies the domain name of a host on which the service is running (on the port specified in the port field). Target must be the canonical name of the host (not an alias), with address records attached to it.

So, for the movie.edu FTP server, we added these records to db.movie.edu:

_ftp._tcp.movie.edu.  IN  SRV  1  0  21  plan9.fx.movie.edu.
                      IN  SRV  2  0  21  thing.fx.movie.edu.

This instructs SRV-capable FTP clients to try the FTP server on plan9.fx.movie.edu’s port 21 first when accessing movie.edu’s FTP service, and then to try the FTP server on thing.fx.movie.edu’s port 21 if plan9.fx.movie.edu’s FTP server isn’t available.

The records:

_http._tcp.www.movie.edu.  IN  SRV  0  2  80   www.movie.edu.
                           IN  SRV  0  1  80   www2.movie.edu.
                           IN  SRV  1  1  8000 postmanrings2x.movie.edu.

direct web queries for www.movie.edu (the web site) to port 80 on www.movie.edu (the host) and www2.movie.edu, with www.movie.edu getting twice the queries that www2.movie.edu does. If neither is available, the queries will go to postmanrings2x.movie.edu on port 8000.

To advertise that a particular service isn’t available, use a dot in the target field:

_gopher._tcp.movie.edu.  IN  SRV  0  0  0  .

Unfortunately, support for the SRV record among clients is, to put it mildly, thin. Certain SIP clients, Windows 2000, Windows XP, and Windows Server 2003 are notable exceptions. (More about Windows support for SRV records later in this chapter.) That’s really too bad, given how useful SRV could be. Since SRV isn’t widely supported, don’t use SRV records in lieu of address records. It’s prudent to include at least one address record for the “base” domain name to which your SRV records are attached (that is, the domain name without the labels that begin with underscores), and more if you’d like the load spread between addresses. If you only list a host as a backup in the SRV records, don’t include its IP address. Also, if a host runs a service on a nonstandard port, don’t include an address record for it since there’s no way to redirect clients to a nonstandard port with an A record.

So, for www.movie.edu, we included all these records:

_http._tcp.www.movie.edu.  IN  SRV  0  2  80   www.movie.edu.
                           IN  SRV  0  1  80   www2.movie.edu.
                           IN  SRV  1  1  8000 postmanrings2x.movie.edu.
www.movie.edu.             IN  A    200.1.4.3 ; the address of www.movie.edu and
                           IN  A    200.1.4.4 ; the address of www2.movie.edu
                                              ; for the benefit of non-SRV aware
                                              ; clients

Browsers that can handle SRV records will send twice as many requests to www.movie.edu as to www2.movie.edu, and will use postmanrings2x.movie.edu only if both of the main web servers are unavailable. Browsers that don’t use SRV records will have their requests round-robined between the addresses of www.movie.edu and www2.movie.edu.

ENUM

ENUM, which stands for Telephone Number Mapping, is a new application of DNS; its overall function is to use DNS to map E.164 numbers to URIs.[*] These URIs might identify a particular VoIP user, an email address, a fax machine, or many other possibilities.

You’re probably already familiar with E.164 numbers, though perhaps not by that name. The E.164 recommendation from the International Telecommunication Union, or ITU, specifies the format of world telephone numbers. These formats begin with a country code (such as “1,” which actually identifies not a particular country but the North American Dialing Plan, which includes the United States, Canada, and parts of Mexico and the Caribbean), then usually an area code or a city code. The format of the rest of the number is defined locally.

Phone numbers may be written with various forms of punctuation separating the country code and other fields. In the United States, for example, we often write the area code in parentheses, as in (408) 555-1234. Other common formats use dashes, periods, parentheses, or some combination of these. A plus sign (“+”) is frequently used before a country code to help identify it.

Mapping an E.164 number to a URI makes it possible, for example, for a caller to reach a VoIP user even though he doesn’t know and can’t dial the URI that identifies the VoIP user. As long as the caller knows an E.164 number that maps to the correct URI, his phone (or, more likely, some software or device acting on behalf of his phone) can determine the destination URI and make the call. ENUM also allows users of different VoIP networks to communicate without resorting to using the public switched telephone network. And ENUM promises to become a kind of unified directory of methods for communicating with people. Under a single E.164 number, you can list URIs that allow people to contact you via phone, email, fax, and instant messaging, for example.

Translating E.164 Numbers into Domain Names

ENUM uses DNS to map E.164 numbers to URIs, and DNS uses domain names to index data, so we need to write the phone number in a canonical format and translate it into a domain name before looking it up. This requires the following steps:

  1. Remove all punctuation separating the digits of the phone number and add a plus sign before the country code. (This converts the phone number “+1-408-555-1234” to the string “+14085551234.”) The result is referred to as ENUM’s Application Unique String, or AUS, which we’ll use later.

  2. Remove the plus sign and reverse the order of the digits in the number. (This converts the string “+14085551212” to the string “21215558041.”)

  3. Insert periods after each of the digits in the string and append “e164.arpa.” The result is the domain name to be looked up. (This converts the string “2121558041” to the domain name 2.1.2.1.5.5.5.8.0.4.1.e164.arpa.)

The NAPTR Record

Now that we’ve turned our E.164 number into a domain name to look up, we need to know what to look up. ENUM stores the information we need in a type of record called a NAPTR record.[*] NAPTR records take six record-specific fields, some of them fairly unusual:

Order

Similar to an MX record’s preference value or an SRV record’s priority, this field tells ENUM clients the order in which to use this record relative to the other NAPTR records attached to this domain name. The value is an unsigned, 16-bit integer. The lower the value, the earlier in the order the record should be used.

Preference

Also an unsigned, 16-bit integer, this field provides ENUM clients with a hint as to which record to use. If an ENUM client supports access using more than one of the URIs listed in a set of NAPTR records with the same value for order, it can use the value of preference to help decide which record to choose, lower preference values indicating greater preference. On the other hand, the client is also free to choose among the record according to its own capabilities and preferences.

Flags

The “u” flag is the only flag defined in NAPTR records that are used with ENUM. It indicates that this NAPTR record is terminal; that is, it maps an E.164 number directly to a URI. As you’ll see, NAPTR records can also map to other domain names, which in turn map to URIs.

Service

The service field for ENUM records always begins with “e2u+” (in uppercase or lowercase—case isn’t significant). “e2u” stands for “E.164 to URI.” The string after e2u+ indicates the type, and optionally the subtype, of URI this NAPTR record maps to. For example, the e2u+sip service maps E.164 numbers to URIs that begin with “sip:” or “sips:”.

Regular expression

This field contains a substitution expression, much like you’d expect to find in Perl or sed. The substitution expression modifies the AUS we derived earlier. The first half of the substitution expression is a POSIX extended regular expression. The second half can contain a combination of bytes to replace a portion of the AUS and back references to portions of the AUS matched between parentheses. The optional flag “i” indicates that the substitution expression should be applied case-insensitively. We show some examples later in this section.

Replacement

For nonterminal NAPTR records, this field specifies the next domain name to look up.

Here are some examples of NAPTR records taken from RFC 3761, which describes ENUM:

$ORIGIN 3.8.0.0.6.9.2.3.6.1.4.4.e164.arpa.
    NAPTR 10 100 "u" "E2U+sip" "!^.*$!sip:[email protected]!" .
    NAPTR 10 101 "u" "E2U+h323" "!^.*$!h323:[email protected]!" .
    NAPTR 10 102 "u" "E2U+msg" "!^.*$!mailto:[email protected]!" .

(Note that in each record, the final record-specific field, replacement, is a single dot, which indicates that there’s no replacement domain name.)

These NAPTR records map the E.164 number +441632960083 to three possible URIs. All have the same value for order, but the administrator of the records indicated a preference for the SIP URI.

The regular expression fields look weird enough in a DNS context to warrant some explanation. The exclamation point (!) is used as a delimiter, just as a forward-slash (/) often is. There must be exactly three: one appears before the substitution expression, one between the substitution and the replacement, and one after the replacement and before any flags. You can use any nonnumeric character for the delimiter that’s not a valid flag (that is, not the letter “i”). It’s prudent to use either “/” or “!” because they’re easy to identify.

The extended regular expression matches all or part of the AUS. In the case of these records, “^.*$” matches the entire AUS. “^” anchors the expression to the beginning of the AUS, and “$” to the end. “.*” matches zero or more occurrences of any character. So the expression matches the whole AUS, start to finish. The replacement values simply replace the AUS wholesale with a URI: , in the first record. Most terminal NAPTR records in ENUM, mercifully, just replace the whole AUS with a URI.

Here’s an example of a NAPTR record that uses a back reference to extract part of the AUS and use it in the URI:

$ORIGIN 0.5.6.1.e164.arpa.
*    NAPTR 10 100 "u" "E2U+sip" "/^+1650(.*)$/sip:[email protected]/" .

The extended regular expression uses parentheses to save everything in the AUS after +1650, then uses it in the SIP URI that replaces the AUS. (“1” is replaced by whatever matched the portion of the regular expression in parentheses, just as in Perl.)

Of course, once an E.164 number has been translated to a URI, it may require additional DNS lookups to map domain names in the URI to IP addresses or other data.

Registering ENUM Domain Names

E.164 numbers, like domain names in DNS, are hierarchical. This makes delegation under e164.arpa straightforward: country code-level subdomains of e164.arpa will generally be delegated to registries acting on behalf of that country. The registries will then delegate subdomains to carriers or other telecommunications companies.

For example, 9.4.e164.arpa, the ENUM zone for country code 49, which belongs to Germany, has already been delegated to DENIC—also the registry for the de top-level domain. Any user with a German phone number can register NAPTR records under 9.4.e164.arpa by working through participating DENIC members, who will validate that the user actually owns the number and request that the appropriate NAPTR records be added.

To find out whether your country code’s subdomain of e164.arpa has been delegated, and, if so, to whom, you can check RIPE’s web site at http://www.ripe.net/enum/request-archives/.

Privacy and Security Issues with ENUM

There are justifiable concerns about the privacy and security of ENUM data. To be useful, records in the e164.arpa namespace must be accessible by anyone. It would be trivial for a spammer to mine all of the email addresses out of that namespace, for example, by walking all possible phone numbers. A hacker might be able to spoof the NAPTR records associated with an E.164 number, redirecting calls made to that number.

DNSSEC can help with the second type of threat. In fact, several of the ENUM RFCs refer to DNSSEC as a possible solution.

Internationalized Domain Names

One shortcoming in the original design of DNS that has become painfully obvious over the years is the character set supported in domain names. While DNS purists may tell you that labels in domain names can contain any binary value, US-ASCII characters are really the only values that are useful and supported by all DNS implementations. As the Internet has expanded internationally, this has meant that companies in countries in which European languages aren’t widely spoken have been forced to use ASCII characters for their domain names. Even Europeans have had to transcribe their non-ASCII characters into ASCII; most Germans, for example, reflexively write ä and ö as ae and oe, respectively.

RFC 3490 introduced a method for encoding international characters in the labels of domain names. Because simply inserting non-ASCII characters into domain names doesn’t work, most DNS software interprets multibyte characters as a sequence of ASCII characters, for example; these international characters are encoded into ASCII. The resulting ASCII-compatible encoding, or ACE, is basically unintelligible to ordinary humans in the same way that base-64 encodings are. To help distinguish an ACE-encoded label in a domain name from a normal but particularly cryptic ASCII label, ACE encodings include a specific prefix, “xn--,” which is now forbidden to appear in a normal, ASCII label. Domain names with one or more labels encoded in ACE are referred to as internationalized domain names, or IDNs.

Rather than trying to accommodate the multitude of language- and script-specific character sets that computers support, RFC 3490 encodes only a single character set, called Unicode, into ASCII. But what a character set it is! Unicode contains tens of thousands of characters from the world’s scripts.[*] In almost all cases, it’s possible to transform a string typed in a script-specific character set (say ISO Latin-1) into a Unicode equivalent.

The burden of encoding Unicode into ACE is placed on applications, not on resolvers or nameservers. If a web browser allows a user to type www.etwas-ähnlich.de as a URL, it’s incumbent upon that web browser to encode the “etwas-ähnlich” label into the equivalent ACE encoding before passing the domain name to the resolver to look up.[*] In a way, that’s good news for you, the administrator, because you don’t need to upgrade your resolvers or nameservers. On the other hand, if your Marketing folks drop by with a list of internationalized domain names they want registered, you may end up with a whole lot of very nasty-looking zone data.

For example, say Marketing wants you to register etwas-ähnlich.de. DENIC, the registry that runs the top-level de zone, requires that you have a zone’s nameservers up and running before it’ll delegate the zone to you. So you’ll need to determine the ACE encoding of etwas-ähnlich.de.

There are several web sites that offer simple ACE encoding utilities, among them:

Using any of these, you can determine that “xn—etwas-hnlich-lcb.de” is the ACE-encoded equivalent of etwas-ähnlich.de. In the named.conf file on your primary nameserver, you need to add a zone statement like this:

zone "xn—etwas-hnlich-lcb.de" {
    type master;
    file "db.xn—etwas-hnlich-lcb.de";
};

The zone datafile, too, needs to refer to the ACE-encoded domain name:

$TTL 1d
xn—etwas-hnlich-lcb.de.    IN    SOA    ns1.xn—etwas-hnlich-lcb.de. (
    hostmaster.xn—etwas-hnlich-lcb.de.
    2006012500 1h 15m 30d 1h )
            IN    NS    ns1.xn—etwas-hnlich-lcb.de.
            IN    NS    ns2.xn—etwas-hnlich-lcb.de.

Of course, you can avoid some of this by using nameservers with regular ASCII domain names and by using a different email address in the SOA record.

If you’re planning on doing any large-scale manipulation of internationalized domain names, you’ll probably need a set of library routines to convert ACE to Unicode and back. There are several available; here are a couple:

A few notes of caution about IDNs. First, support for IDNs in web browsers is spotty. While Firefox and Opera support IDN, Internet Explorer doesn’t until IE 7.0, which as of this writing is in beta. Most other programs that take domain names as input, such as mail clients, have no IDN support at all.

There’s also concern that IDNs complicate an already tricky problem with homographs, different characters whose glyphs (written forms) look the same. This has been a relatively minor problem in the ASCII past, exploited by hackers who take advantage of the fact that it can be difficult to differentiate between “1” and “l” or “0” and “O,” and who try to lure you into clicking on a familiar-looking URL like www.goog1e.com. IDNs pose a greater threat, because many different Unicode characters appear indistinguishable. Consequently, some newer versions of the browsers that support IDN actually display the ACE version of an IDN label rather than its Unicode equivalent. Yuck.

DNS and WINS

In our first edition—oh, for those simpler days!—we mentioned the close alignment between NetBIOS names and domain names, but noted that, alas, there was no way for DNS to function as a NetBIOS nameserver. Basically, a nameserver would need to support dynamic updates to function as a NetBIOS nameserver.

Of course, BIND 8 and 9 do support dynamic updates. Unfortunately, neither NetBIOS clients nor WINS servers send dynamic updates to nameservers. WINS servers accept only the peculiar, proprietary dynamic updates sent by NetBIOS clients. In other words, a WINS server doesn’t speak DNS.

However, Microsoft provides a nameserver, the Microsoft DNS Server, which in turn can talk to WINS servers. The Microsoft DNS Server has a nice graphical administration tool, as you would expect from Microsoft, and provides a handy hook into WINS: you can configure the server to query a WINS server for address data if it doesn’t find the data in a DNS zone.

This is done by adding a new WINS record to the zone. The WINS record, like the SOA record, is attached to the zone’s domain name. It acts as a flag to tell the Microsoft DNS Server to query a WINS server if it doesn’t find an address for the name it’s looking up. The record:

@        0       IN     WINS            192.249.249.39 192.253.253.39

tells the Microsoft DNS Server to query the WINS servers running at 192.249.249.39 and 192.253.253.39 (in that order) for the name. The zero TTL is a precaution against the record being looked up and cached.

There’s also a companion WINS-R record that allows a Microsoft DNS Server to reverse-map IP addresses using a NetBIOS NBSTAT request. If an in-addr.arpa zone contains a WINS-R record such as:

@        0      IN      WINS-R          movie.edu

and the IP address sought doesn’t appear in the zone, the nameserver attempts to send a NetBIOS NBSTAT request to the IP address being reverse-mapped. This amounts to calling a phone number and asking the person on the other end, “What’s your name?” The nameserver then appends a dot and the domain name in the record-specific data, in this case “.movie.edu,” to the result.

These records provide valuable glue between the two namespaces. Unfortunately, the integration isn’t perfect. As they say, the devil is in the details.

The main problem, as we see it, is that only Microsoft DNS Servers support the WINS and WINS-R records. Therefore, if you want lookups in the fx.movie.edu zone to be relayed to the Special Effects Department’s WINS server, then all fx.movie.edu nameservers must be Microsoft DNS Servers. Why? Imagine that the nameservers for fx.movie.edu were mixed, with some Microsoft DNS Servers and some BIND nameservers. If a remote nameserver tried to look up a NetBIOS name in fx.movie.edu, it would choose which of the fx.movie.edu nameservers to query according to round-trip time. If the server it happened to choose were a Microsoft DNS Server, it would be able to resolve the name to a dynamically assigned address. However, if it happened to choose a BIND nameserver, it wouldn’t be able to resolve the name.

The best DNS-WINS configuration we’ve heard of so far puts all WINS-mapped data in its own zone, say wins.movie.edu. All the nameservers for wins.movie.edu are Microsoft DNS Servers, and the zone wins.movie.edu contains just an SOA record, NS records, and a WINS record pointing to the WINS servers for wins.movie.edu. This way, there’s no chance of inconsistent answers between authoritative servers for the zone.

Reverse-mapping data, of course, can’t easily be split into separate zones for BIND and Microsoft nameservers to maintain. So if you want both traditional, PTR record-based reverse mapping and WINS-R-enhanced reverse mapping, you’ll need to host your reverse-mapping zones solely on Microsoft DNS Servers.

Another problem is that WINS and WINS-R are proprietary. BIND nameservers don’t understand them, and, in fact, a BIND slave that transfers a WINS record from a Microsoft DNS Server primary master will fail to load the zone because WINS is an unknown type. (We discussed this, and how to work around it, in Chapter 14.)

The answer to these problems is the DNS standard dynamic update functionality that was first introduced in BIND 8 (described in Chapter 10) and the support for it in Windows 2000, Windows XP, and Windows Server 2003. Dynamic update allows the addition and deletion of records from a zone, which in turn gives the folks at Microsoft the functionality they need to use DNS as a name service for NetBIOS. So without further ado . . .

DNS, Windows, and Active Directory

Modern Windows operating systems —by which we mean Windows 2000, Windows XP, and Windows Server 2003—can use standard dynamic updates to register hosts in DNS. For a modern Windows client, registration means adding a name-to-address mapping and an address-to-name mapping for that client—information Windows clients formerly registered with WINS servers. For a Windows server, registration involves adding records to a zone to tell clients which services it’s running and where (on which host and port). For example, an Active Directory Domain Controller uses dynamic update to add SRV records that tell Windows clients which services it’s running.

How Windows Uses Dynamic Update

So what gets added when a client registers? Let’s reboot a Windows client in the Special Effects Lab and see.

Our client is called mummy.fx.movie.edu. It has the fixed IP address 192.253.254.13 (it doesn’t get its address from our DHCP server). At boot time, the dynamic update routines on the client go through the following steps:

  1. Look up the SOA record for mummy.fx.movie.edu on the local nameserver. Though there isn’t an SOA record for that domain name, the authority section of the response includes the SOA record of the zone that contains mummy.fx.movie.edu, which is fx.movie.edu.

  2. Look up the address of the nameserver in the MNAME field of the SOA record, bladerunner.fx.movie.edu .

  3. Send a dynamic update to bladerunner.fx.movie.edu with two prerequisites: that mummy.fx.movie.edu isn’t an alias (i.e., doesn’t own a CNAME record) and that it doesn’t already have an address record pointing to 192.253.254.13. The dynamic update contains no update section; it’s just a probe to see what’s out there.

  4. If mummy.fx.movie.edu already points to the correct address, stop. Otherwise, send another dynamic update to bladerunner.fx.movie.edu with the prerequisites that mummy.fx.movie.edu isn’t an alias and doesn’t have an address record—any address record—already. If the prerequisites are satisfied, the update adds an address record pointing mummy.fx.movie.edu to 192.253.254.13. If mummy.fx.movie.edu already has an address record, the client sends an update to delete that address record and add its own.

  5. Look up the SOA record for 254.253.192.in-addr.arpa.

  6. Look up the address of the nameserver in the MNAME field of the SOA record (though because the MNAME field contains bladerunner.fx.movie.edu , which we looked up recently, and modern Windows OSes have a caching resolver, this shouldn’t require another query).

  7. Send a dynamic update to bladerunner.fx.movie.edu with the prerequisite that 13.254.253.192.in-addr.arpa isn’t an alias. If the prerequisite is satisfied, the update adds a PTR record mapping 192.253.254.13 back to mummy.fx.movie.edu. If 13.254.253.192.in-addr.arpa is an alias, stop.

If we’re using the Microsoft DHCP Server included with a modern Windows server operating system, the DHCP server, by default, adds the PTR record. There’s also an option in the DHCP server’s MMC-based management interface that allows the administrator to specify that the DHCP server add both the PTR record and the A record. If the DHCP server had added the A record, though, it wouldn’t have set a prerequisite.

Servers, particularly Domain Controllers, register lots of information in DNS using dynamic update, both when they’re first set up and periodically thereafter. (The netlogon service, for example, registers its SRV records hourly!) This allows clients to locate services on whichever host and port they’re running. Since we just set up an Active Directory domain called fx.movie.edu, let’s take a look at the records that our Domain Controller, matrix.fx.movie.edu, added:

fx.movie.edu. 600 IN A 192.253.254.14
ec4caf62-31b2-4773-bcce-7b1e31c04d25._msdcs.fx.movie.edu. 600 IN CNAME
matrix.fx.movie.edu.
gc._msdcs.fx.movie.edu. 600 IN A 192.253.254.14
_gc._tcp.fx.movie.edu. 600 IN SRV 0 100 3268 matrix.fx.movie.edu.
_gc._tcp.Default-First-Site-Name._sites.fx.movie.edu. 600 IN SRV 0 100
3268 matrix.fx.movie.edu.
_ldap._tcp.gc._msdcs.fx.movie.edu. 600 IN SRV 0 100 3268 matrix.fx.movie.edu.
_ldap._tcp.Default-First-Site-Name._sites.gc._msdcs.fx.movie.edu. 600 IN SRV
0 100 3268 matrix.fx.movie.edu.
_kerberos._tcp.dc._msdcs.fx.movie.edu. 600 IN SRV 0 100 88 matrix.fx.movie.edu.
_kerberos._tcp.Default-First-Site-Name._sites.dc._msdcs.fx.movie.edu. 600
IN SRV 0 100 88 matrix.fx.movie.edu.
_kerberos._tcp.fx.movie.edu. 600 IN SRV 0 100 88 matrix.fx.movie.edu.
_kerberos._tcp.Default-First-Site-Name._sites.fx.movie.edu. 600 IN SRV
0 100 88 matrix.fx.movie.edu.
_kerberos._udp.fx.movie.edu. 600 IN SRV 0 100 88 matrix.fx.movie.edu.
_kpasswd._tcp.fx.movie.edu. 600 IN SRV 0 100 464 matrix.fx.movie.edu.
_kpasswd._udp.fx.movie.edu. 600 IN SRV 0 100 464 matrix.fx.movie.edu.
_ldap._tcp.fx.movie.edu. 600 IN SRV 0 100 389 matrix.fx.movie.edu.
_ldap._tcp.Default-First-Site-Name._sites.fx.movie.edu. 600 IN SRV 0 100
389 matrix.fx.movie.edu.
_ldap._tcp.pdc._msdcs.fx.movie.edu. 600 IN SRV 0 100 389 matrix.fx.movie.edu.
_ldap._tcp.97526bc9-adf7-4ec8-a096-0dbb34a17052.domains._msdcs.fx.movie.edu.
600 IN SRV 0 100 389 matrix.fx.movie.edu.
_ldap._tcp.dc._msdcs.fx.movie.edu. 600 IN SRV 0 100 389 matrix.fx.movie.edu.
_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.fx.movie.edu. 600 IN SRV
0 100 389 matrix.fx.movie.edu.

Whoa! That’s a lot of records!

These records tell Active Directory clients where the services offered by the Domain Controller, including Kerberos and LDAP, are running.[*] You can see from the SRV records that they’re all running on matrix.fx.movie.edu, our only Domain Controller. If we had another Domain Controller, you’d see twice as many records.

The owner names of all the records end in fx.movie.edu, the name of the Active Directory domain. If the Active Directory domain was called ad.movie.edu, the dynamic update routines would update the zone containing the domain name ad.movie.edu, which is movie.edu.

Problems with Active Directory and BIND

While Microsoft’s decision to replace WINS with DNS was laudable, the implementation poses some problems for folks who run BIND nameservers. First, Windows clients and DHCP servers have a nasty habit of deleting address records owned by the same domain name as the clients or servers. For example, if we let the users in the Special Effects Lab configure their own computers and choose their computers’ names, and one user happens to use a name that is already taken, maybe by one of our rendering servers, his computer will try to delete the conflicting address record (that of the rendering server) and add its own. That’s not very sociable.

Luckily, that behavior can be corrected on the client. The client does, in fact, check to see whether the domain name it’s using already owns an address record by setting the prerequisite described in the previous section’s Step 4. (It just deletes it if it does exist, by default.) But you can follow the instructions in Microsoft Knowledge Base article Q246804 to tell the client not to delete conflicting records. The price? A client can’t differentiate between an address being used by a different host with the same domain name and an address that formerly belonged to it, so if the client changes addresses, it can’t automatically update the zone.

If you elect to have your Microsoft DHCP Server handle all registration, you don’t have the option of leaving conflicting addresses alone. The Microsoft DHCP Server doesn’t use prerequisites to detect collisions; it just unceremoniously deletes conflicting address records.

Given the limitations of having the DHCP server handle all the registering, why would anyone consider it? Because if you allow any client to register itself, and you can use only primitive, IP address-based access lists to authorize dynamic updates, you are allowing any client’s address to dynamically update your zones. Savvier users of those clients can easily fire off a few custom-made dynamic updates to change your zone’s MX records or the address of your web server.

Secure Dynamic Update

Surely Microsoft doesn’t just live with these problems, right? No, not with the Microsoft DNS Server. The Microsoft DNS Server supports GSS-TSIG, a dialect of TSIG (which we covered in Chapter 11). A client that uses GSS-TSIG negotiates a TSIG key with the help of a Kerberos server, then uses that key to sign a dynamic update. The use of GSS, the Generic Security Service, to retrieve the key means that an administrator doesn’t need to hardcode a key on each of his clients.

Since the name of the TSIG key the client uses to sign the update is just the domain name of the client, the nameserver can make sure that only the client that added an address can delete it later, simply by tracking the domain name of the TSIG key used to add a given record. Only an updater with the same TSIG key is allowed to delete that record.

Modern Windows clients try GSS-TSIG-signed dynamic updates if their unsigned dynamic updates are refused. You can also configure them to send signed updates first by following the instructions in Knowledge Base article Q246804, mentioned earlier.

BIND and GSS-TSIG

Unfortunately, BIND nameservers don’t yet support GSS-TSIG, so you can’t use Windows’s secure dynamic update with BIND. A forthcoming version of BIND 9, however, is scheduled to support GSS-TSIG. Once BIND does support GSS-TSIG, you’ll be able to use all the update policy rules described in Chapter 10 to control which keys can update which records. A simple set of rules that says:

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

may someday be enough to let Windows clients and servers register what they need in your zone.

What to Do?

In the meantime, how do you handle the proliferation of Windows and Active Directory on your network? Well, Microsoft would advise you to “upgrade” all your nameservers to the Microsoft DNS Server. But if you like BIND—and we do—you’d probably like some other options.

Handling Windows clients

The first (and probably most common) option for handling your Windows clients is to create a delegated subdomain for all of them to live in. We might call ours win.fx.movie.edu. Within win.fx.movie.edu, anything goes: clients can stomp on other clients’ addresses, and someone may send a bunch of hand-crafted dynamic updates to add bogus records to the zone. The intent is to create a sandbox (or jail, if you prefer) that the clients can’t break out of and that they can trash if they want to. If you have kids, you have an intuitive understanding of this concept.

By default, a Windows client will try to register itself in a forward-mapping zone with the same name as its Active Directory domain. So we’ll have to do some extra configuration to tell our clients to register in win.fx.movie.edu instead of in fx.movie.edu. In particular, we’ll have to go to a window that resides at My Computer → Properties → Network Identification → Properties → More, uncheck “Change primary DNS suffix when domain membership changes,” and type win.fx.movie.edu in the field labeled Primary DNS suffix of this computer. On all our clients.

Another possibility is to leave your clients in your main production zone (for our lab, that’s fx.movie.edu) but allow dynamic updates only from the address of the DHCP server. You then configure your DHCP server to assume responsibility for maintaining both A records and PTR records. (You can manually add A and PTR records for hosts that don’t use DHCP.)

In this scenario, it’s more difficult for the little imps to send their custom dynamic updates to your nameserver because it involves spoofing the address of the DHCP server. It’s still possible that someone will bring up a client with a domain name that conflicts with an existing domain name in the zone, though.

If you’re willing to consider using a different DHCP server, you can deploy an even more secure solution. The latest versions of the ISC DHCP server support TSIG-signed dynamic updates and use a clever mechanism based on TXT records to avoid name collisions in DHCP clients. When the DHCP server adds an A record on behalf of a DHCP client, it also adds a TXT record to the client’s domain name, in which the record-specific data is a one-way hash of the client’s MAC address. The resulting records look like this:

walktheline        A       192.253.254.237
                   TXT     "313f1778871429e6d240893c1afc163aee"

If the DHCP server later tries to add a different A record to that domain name on behalf of a client, it checks whether the client’s MAC address hashes to the same value that’s stored in the TXT record. If it does, the DHCP server removes the old A record because it belonged to the same client; the client has probably just moved to a new subnet or leased a different address. If it doesn’t, the DHCP server won’t perform the update because the old A record likely belongs to a different client that happens to have the same domain name.

For more information on the ISC DHCP server, see http://www.isc.org/sw/dhcp/.

Handling Windows servers

The main server you need to accommodate with your nameservers is the Domain Controller (or Controllers, if you have more than one). The DC wants to add the passel of records we showed earlier. If it can’t add them at setup time, it’ll write the records, in master file format, to a file called System32Config etlogon.dns under the system root.

First, you need to determine which zone you need to update. That’s just a matter of finding the zone that contains the Active Directory domain name. If your Active Directory domain has the same name as an existing zone, of course, that’s the zone to update. Otherwise, just keep stripping off the leading labels of your Active Directory domain until you get to the domain name of a zone.

Once you have the zone that you need to update, you need to decide how to proceed. If you don’t mind letting your Domain Controller dynamically update your zone, just add an appropriate allow-update substatement to the zone statement and you’re done. If you’d rather not allow your DC complete control of the zone, you can leave dynamic updates disabled and let the DC create the netlogon.dns file. Then use an $INCLUDE control statement to read the contents of the file into your zone datafile:

$INCLUDE netlogon.dns

If neither option appeals to you because you want the DC to be able to change its records but don’t want it mangling your zone, you still have a trick up your sleeve. You can take advantage of the funny format of the owner names in SRV records and create delegated subdomains called (in our case) _udp.fx.movie.edu, _tcp.fx.movie.edu, _sites.fx.movie.edu, and _msdcs.fx.movie.edu. (You might have to turn off name checking for _msdcs.fx.movie.edu, because the Domain Controller wants to add an address record to the zone in addition to a slew of SRV records, and the owner name of that record will contain an underscore.) Then let the DC dynamically update these zones, but not your main zone:

acl dc { 192.253.254.13; };

zone "_udp.fx.movie.edu" {
    type master;
    file "db._udp.fx.movie.edu";
    allow-update { dc; };
};

zone "_tcp.fx.movie.edu" {
    type master;
    file "db._tcp.fx.movie.edu";
    allow-update { dc; };
};

zone "_sites.fx.movie.edu" {
    type master;
    file "db._sites.fx.movie.edu";
    allow-update { dc; };
};

zone "_msdcs.fx.movie.edu" {
    type master;
    file "db._msdcs.fx.movie.edu";
    allow-update { dc; };
    check-names ignore;
};

If your Domain Controllers run Windows Server 2003, you need to add two more zones to that list: DomainDNSZones.fx.movie.edu and ForestDNSZones.fx.movie.edu:

zone "DomainDNSZones.fx.movie.edu" {
    type master;
    file "db.DomainDNSZones.fx.movie.edu";
    allow-update { dc; };
};

zone "ForestDNSZones.fx.movie.edu" {
    type master;
    file "db.ForestDNSZones.fx.movie.edu";
    allow-update { dc; };
    check-names ignore;
};

Now you have the best of both worlds: dynamic registration of services with a safe production zone.



[*] And one has (the Microsoft DNS Server, shipped with server versions of Windows). It also permits CNAMEs that point to CNAMEs, though.

[*] URIs are Uniform Resource Identifiers. URLs, or Uniform Resource Locators, such as you’d type into a browser, are a subset of URIs, as are URNs, or Uniform Resource Names.

[*] NAPTR records were actually developed before ENUM and can be used for other purposes, but their only common use today is to support ENUM.

[*] To learn more about Unicode, see The Unicode Consortium’s web site at http://www.unicode.org/.

[*] Since “www” and “com” are simple ASCII labels, they don’t need to be encoded.

[*] For an explanation of the function of each of these records, see the document “How DNS Support for Active Directory Works” at http://www.microsoft.com/Resources/Documentation/windowsserv/2003/all/techref/en-us/w2k3tr_addns_how.asp.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset