Sample Resolver Configurations
Minimizing Pain and Suffering
They were indeed a queer-looking party that assembled on the bank - the birds with draggled feathers, the animals with their fur clinging close to them, and all dripping wet, cross, and uncomfortable.
Now that you or someone else in your organization has set up name servers for your zones, you'll want to configure the hosts on your network to use them. That involves configuring those hosts' resolvers. You should also check files like hosts.equiv and .rhosts and make any changes dictated by using DNS; you may need to convert some of the host names in these files to domain names. And you may also want to add aliases, both for your users' convenience and to minimize the shock of the conversion to DNS.
This chapter covers these topics, and also describes configuring the resolver in many common versions of UNIX and in Microsoft's Windows 95 and Windows NT.
We introduced resolvers way back in Chapter 2, How Does DNS Work?, but we didn't say much more about them. The resolver, you'll remember, is the client half of the Domain Name System. It's responsible for translating a program's request for host information into a query to a name server and for translating the response into an answer for the program.
We haven't done any resolver configuration yet, because the occasion for it hasn't arisen. When we set up our name servers in Chapter 4, Setting Up BIND, the resolver's default behavior worked just fine for our purposes. But if we'd needed the resolver to do more than what it does by default, or to behave differently from the default, we would have had to configure the resolver.
There's one thing we should mention up front: what we'll describe in the next few sections is the behavior of the vanilla DNS 8.1.2 resolver in the absence of other naming services. Not all resolvers behave quite this way; some vendors still ship resolvers based on earlier versions of the DNS code, and some have implemented special resolver functionality that lets you modify the resolver algorithm. Whenever we think it's important, we'll point out differences between the behavior of the 8.1.2 DNS resolver and that of earlier resolvers, particularly the 4.8.3 resolver, which is what many vendors were shipping when we last updated this book. We'll cover various vendors' extensions later in this chapter.
So what exactly does the resolver allow you to configure? Most resolvers let you configure at least three aspects of the resolver's behavior: the default domain, the search list, and the name server(s) that the resolver queries. Many UNIX vendors allow you to configure other resolver behavior, too, through nonstandard extensions to DNS. Sometimes these extensions are necessary to cope with other software, like Sun's Network Information Service (NIS); sometimes they're simply value added by the vendor.
 NIS used to be called "Yellow Pages," or "YP," but was changed to NIS because the British phone company had a copyright on the name Yellow Pages.
Almost all resolver configuration is done in the file /etc/resolv.conf (this may be /usr/etc/resolv.conf or something similar on your host - check the resolver manual page, usually in section 4 or 5, to make sure). There are five main directives you can use in resolv.conf: the domain directive, the search directive, the nameserver directive, the sortlist directive, and the options directive. These directives control the behavior of the resolver. There are other, vendor-specific directives available on some versions of UNIX - we'll discuss them at the end of this chapter.
The default domain is the domain considered "local" to the host. For example, when you add an entry like:
to your .rhosts file, the name relay is assumed to be in your default domain. This makes a lot more sense than allowing access to every host on the Internet whose domain name starts with relay. Other authorization files like hosts.equiv and hosts.lpd work the same way.
Normally, the default domain is determined from the host's hostname; the default domain is everything after the first "." in the name. If the name doesn't contain a ".", the default domain is assumed to be the root domain. So the hostname asylum.sf.ca.us implies a default domain of sf.ca.us, while the hostname dogbert implies a root default domain - which probably isn't correct, given that there are no hosts immediately under the root domain.
You can also set the default domain with the domain directive in resolv.conf. If the domain directive is specified, it overrides the domain in the hostname.
The domain directive has a very simple syntax, but you've got to get it right, since the resolver doesn't report errors. The keyword domain starts the line in column one, followed by whitespace (one or more blanks or tabs), then the name of the default domain. The default domain should be written without a trailing dot, like this:
In older versions of the DNS resolver (those before DNS 4.9.3), trailing spaces are not allowed on the line, and will cause your default domain to be set to a name ending with one or more spaces, which is almost certainly not what you want. And there's yet another way to set the default domain - via the LOCALDOMAIN environment variable. LOCALDOMAIN is handy because you can set it on a per-user basis. For example, you might have a big, massively parallel box in your corporate computing center to which employees from all over the world log in. Each may do most of his work in a different company subdomain. With LOCALDOMAIN, each employee can set his default domain to the appropriate domain in his shell startup file.
Which method should you use - hostname, the domain directive, or LOCALDOMAIN? We prefer using hostname, but primarily because that's the way Berkeley does it, and it seems "cleaner" in that it requires less explicit configuration. Also, some Berkeley software, particularly software that uses the ruserok() library call to authenticate users, allows short host names in files like hosts.equiv only if hostname is set to the full domain name.
If you run software that can't tolerate long hostnames, though, you can use the domain directive. The hostname command will continue to return a short name, and the resolver will fill in the domain from resolv.conf. You may even find occasion to use LOCALDOMAIN on a host with lots of users.
The default domain, whether derived from hostname or resolv.conf, also determines the default search list. The search list was designed to make users' lives a little easier by saving them some typing. The idea is to search one or more domains for names typed at the command line that might be incomplete - that is, that might not be fully qualified domain names.
Most UNIX networking commands that take a domain name as an argument, like telnet, ftp, rlogin, and rsh, apply the search list to those arguments.
Both the way the default search list is derived and the way the search list is applied changed from DNS 4.8.3 to DNS 4.9. If your resolver is an older make, you'll still see the 4.8.3 behavior, but if you've got a newer model, including DNS 8.1.2, you'll see the improvements in the 4.9 resolver.
 Though the ISC added lots of new server functionality in DNS 8, the resolver is nearly identical to the DNS 4.9 resolver.
With any DNS resolver, a user can indicate that a domain name is fully qualified by adding a trailing dot to it. For example, the trailing dot in the command:
 Note that we said that the resolver can handle a trailing dot. Some programs, particularly UNIX mail user agents, don't deal correctly with a trailing dot in email addresses. They cough even before they hand the domain name in the address to the resolver.
means "don't bother searching any other domains; this domain name is fully qualified." This is analogous to the leading slash in full pathnames in the UNIX and MS-DOS filesystems. Pathnames without a leading slash are interpreted as relative to the current working directory, while pathnames with a leading slash are absolute, anchored at the root.
With DNS 4.8.3 resolvers, the default search list includes the default domain and each of its parent domains with two or more labels. Therefore, on a host running a 4.8.3 resolver and configured with:
the default search list would contain first cv.hp.com, the default domain, then hp.com, the default domain's parent, but not com, as it only has one label. The name is looked up as is, after the resolver appends each element of the search list, and only if the name typed contains at least one dot. Thus, a user typing:
 One reason older DNS resolvers didn't append just the top-level domain is that there were - and still are - very few hosts at the second level of the Internet's name space, so tacking on just com or edu to foo is unlikely to result in the domain name of a real host. Also, looking up the address of a foo.com or foo.edu might well require sending a query to a root name server, which taxes the roots and can be time-consuming.
will cause lookups of pronto.cv.hp.com.cv.hp.com and pronto.cv.hp.com.hp.com before the resolver looks up pronto.cv.hp.com by itself. A user typing:
on the same host would cause the resolver to look up asap.cv.hp.com and asap.hp.com, but not just asap, since the name typed ("asap") contains no dots.
Note that application of the search list stops as soon as a prospective domain name turns up the data being looked up. In the asap example, the search list would never get around to appending hp.com if asap.cv.hp.com resolved to an address.
With DNS 4.9, the default search list includes just the default domain. So, if you configure a host with:
the default search list would contain just cv.hp.com. Also, in a change from earlier resolvers, the search list is usually applied after the name is tried as is. As long as the argument you type has at least one dot in it, it's looked up exactly as you typed it before any element of the search list is appended. If that lookup fails, the search list is applied. Even if the argument has no dots in it (that is, it's a single label name), it's tried as-is, after the resolver appends the elements of the search list.
Why is it better to try the argument literatim first? From experience, the designers of DNS found that, more often than not, if a user bothered to type in a name with even a single dot in it, he was probably typing in a fully qualified domain name without the trailing dot. With older search list behavior, the resolver would send several fruitless queries before ever trying the name as typed.
Therefore, with a 4.9 resolver, a user typing:
would have pronto.cv.hp.com looked up first (there are three dots in the argument). If that query failed, the resolver would try pronto.cv.hp.com.cv.hp.com. A user typing:
on the same host would cause the resolver to look up asap.cv.hp.com first, since the name doesn't contain a dot, and then just asap.
What if you don't like the default search list you get when you set your default domain? In DNS 4.8.3 and all newer resolvers, you can set the search list explicitly, domain by domain, in the order you want the domains searched. You do this with the search directive.
The syntax of the search directive is very similar to that of the domain directive, except that it can take multiple domain names as arguments. The keyword search starts the line in column one, followed by from one to six domain names, in the order you want them searched. The first domain in the list is interpreted as the default domain, so the search and domain directives are mutually exclusive. If you use both in resolv.conf, the one that appears last will override the other.
search corp.hp.com paloalto.hp.com hp.com
for example, would instruct the resolver to search the corp.hp.com domain first, then paloalto.hp.com, and then both domains' parent, hp.com.
This directive might be useful on a host whose users access hosts in both corp.hp.com and paloalto.hp.com frequently. On the other hand, on a DNS 4.8.3 resolver, the directive:
would have the resolver skip searching the default domain's parent domain when the search list is applied. (On a 4.9 resolver, the parent domain isn't in the search list, so this is no different from the default behavior.) This might be useful if the host's users only access hosts in the local domain, or if connectivity to the parent name servers isn't good (because it minimizes unnecessary queries to the parent name servers).
NOTE: If you use the domain directive and update your resolver to DNS version 4.9 or later, users who relied on your default domain's parent being in the search list may believe the resolver has suddenly broken. You can restore the old behavior by using the search directive to configure your resolver to use the same search list that it would have built before. For example, under DNS 4.9 or DNS 8, you can replace domain nsr.hp.com with search nsr.hp.com hp.com and get the same functionality.
Back in Chapter 4, we talked about two types of name servers: primary master name servers and slave name servers. But what if you don't want to run a name server on a host, yet still want to use DNS? Or, for that matter, what if you can't run a name server on a host (because the operating system doesn't support it, for example)? Surely you don't have to run a name server on every host, right?
No, of course you don't. By default, the resolver looks for a name server running on the local host - which is why we could use nslookup on terminator and wormhole right after we configured their name servers. You can, however, instruct the resolver to look to another host for name service. This configuration is called a DNS client in the BIND Operations Guide.
The nameserver directive (yep, all one word) tells the resolver the IP address of a name server to query. For example, the line:
instructs the resolver to send queries to the name server running at IP address 184.108.40.206, instead of to the local host. This means that on hosts that don't run name servers, you can use the nameserver directive to point them at a remote name server. Typically, you would configure the resolvers on your hosts to query your own name servers.
However, since name servers before DNS 4.9 don't have any notion of access control, you can configure your resolver to query almost anyone's name server. Of course, configuring your host to use someone else's name server without first asking permission is presumptuous, if not downright rude, and using one of your own will usually give you better performance, so we'll consider this only an emergency option.
You can also configure the resolver to query the host's local name server, by using either the local host's IP address or the zero address. The zero address, 0.0.0.0, is interpreted by most TCP/IP implementations to mean "this host." The host's real IP address, of course, also means "this host." On hosts that don't understand the zero address, you can use the loopback address, 127.0.0.1.
Now what if the name server your resolver queries is down? Isn't there any way to specify a backup? Do you just fall back to using the host table?
The resolver will also allow you to specify up to three (count 'em, three) name servers using multiple nameserver directives. The resolver will query those name servers, in the order listed, until it receives an answer or times out. The number of name servers you configure dictates other aspects of the resolver's behavior, too.
NOTE: If you use multiple nameserver directives, don't use the loopback address! There's a bug in some Berkeley-derived TCP/IP implementations that can cause problems with DNS if the local name server is down. The resolver's connected datagram socket won't rebind to a new local address if the local name server isn't running, and consequently the resolver will send query packets to the fallback remote name servers with a source address of 127.0.0.1. When the remote name servers try to reply, they'll end up sending the reply packets to themselves.
If there's only one name server configured, the resolver queries that name server with a timeout of five seconds. The timeout is the length of time the resolver will wait for a response from the name server before sending another query. If the resolver encounters an error that indicates the name server is really down or unreachable, or if it times out, it will double the timeout and query the name server again. The errors that would cause this include:
 When we say "one name server configured," that means either one nameserver directive in resolv.conf or no nameserver directive with a name server running locally.
Receipt of an ICMP port unreachable message, which means that no name server is listening on the name server port
Receipt of an ICMP host unreachable or network unreachable message, which means that queries can't be sent to the destination IP address
If the domain name or data don't exist, the resolver doesn't retry the query. Theoretically, at least, each name server should have an equivalent "view" of the name space; there's no reason to believe one and not another. So if one name server tells you that a given domain name doesn't exist, or that the type of data you're looking for doesn't exist for the domain name you specified, any other name server should give you the same answer. If the resolver receives a network error each time it sends a query (for a total of four errors), it falls back to using the host table. Note that these are errors, not timeouts. If it times out on even one query, the resolver returns a null answer and does not fall back to /etc/hosts.
 The built-in latency of DNS makes this a small fib - a primary can have authority for a zone and have different data from a slave that also has authority for the zone. The primary may have just loaded new zone data from disk, while the slave may not have had time to transfer the new zone data from the primary. Both name servers return authoritative answers for the zone, but the primary may know about a brand-new host that the slave doesn't yet know about.
With more than one name server configured, the behavior is a little different. Here's what happens: the resolver starts by querying the first name server in the list, with a timeout of five seconds, just as in the single name server case. If the resolver times out or receives a network error, it will fall back to the next name server, waiting the same five seconds for that name server. Unfortunately, the resolver won't receive many of the possible errors; the socket the resolver uses is "unconnected," since it must be able to receive responses from any of the name servers it queries, and unconnected sockets don't receive ICMP error messages. If the resolver queries all the configured name servers, to no avail, it updates the timeouts and cycles through them again.
The resolver timeout for the next round of queries is based on the number of name servers configured in resolv.conf. The timeout for the second round of queries is ten seconds divided by the number of name servers configured, rounded down. Each successive round's timeout is double the previous timeout. After three sets of retransmissions (a total of four timeouts for every name server configured), the resolver gives up trying to query name servers.
For you mathophobes, Table 6.1 shows what the timeouts look like when you have one, two, or three name servers configured.
Name Servers Configured
(Note that this is how DNS versions 4.9 and later behave. The behavior of older versions of DNS is similar, but not necessarily identical.)
So if you configure three servers, the resolver queries the first server, with a timeout period of five seconds. If that query times out, the resolver queries the second server with the same timeout, and similarly for the third. If the resolver cycles through all three servers, it doubles the timeout period and divides by three (to three seconds, 10/3 rounded down) and queries the first server again.
Do these times seem awfully long? Remember, this describes a worst-case scenario. With properly-functioning name servers running on tolerably fast hosts, your resolvers should get their answers back in well under a second. Only if all the configured servers are really busy or they or your network is down will the resolver ever make it all the way through the retransmission cycle and give up.
What does the resolver do after it gives up? It times out and returns an error. Typically this results in an error like:
telnet tootsietootsie: Host name lookup failure
Of course, it'll take at least 75 seconds of waiting to see this message, so be patient.
The sortlist directive is a mechanism in DNS 4.9 and later resolvers that lets you specify subnets and networks for the resolver to prefer if it receives multiple addresses as the result of a query. In some cases, you'll have reason to want your host to use a particular network to get to certain destinations. For example, say your workstation and your NFS server have two network interfaces each: one on an Ethernet, subnet 128.32.1; and one on an FDDI ring, subnet 128.32.42. If you leave your workstation's resolver to its own devices, it's anybody's guess which of the NFS server's IP addresses you'll use for a mount - presumably, the first one in a reply packet from the name server. To make sure you try the interface on the FDDI ring first, you can add a sortlist directive to resolv.conf that sorts the address on 128.32.42 to the preferred position in the structure passed back to programs:
The argument after the slash is the subnet mask for the subnet in question. To prefer an entire network, you can omit the slash and the subnet mask:
The resolver will assume you mean the entire class B network 128.32. (The resolver derives the default unsubnetted net mask for the network from the first few bits of the IP address.)
And, of course, you can specify several subnets and networks to prefer over others:
sortlist 220.127.116.11/255.255.255.0 18.104.22.168
The resolver sorts any addresses in a reply that match these arguments into the order in which they appear in the directive, and appends addresses that don't match to the end.
The options directive was introduced with DNS 4.9. options will let you tweak two internal resolver settings. The first is the debug flag, RES_DEBUG. The directive:
sets RES_DEBUG, producing lots of exciting debugging information on standard output, assuming your resolver was configured with DEBUG defined. (Actually, that may not be a good assumption, since most vendors compile their stock resolvers without DEBUG defined.) This is very useful if you're attempting to diagnose a problem with your resolver or with name service in general, but very annoying otherwise.
The second setting you can modify is ndots, which sets the minimum number of dots a domain name argument must have so that the resolver will look it up before applying the search list. By default, one or more dots will do; this is equivalent to ndots:1. The resolver will try the domain name as typed first as long as the name has any dots in it. You can raise the threshold if you believe your users are more likely to type partial domain names that will need the search list applied. For example, if your default domain is mit.edu and your users are accustomed to typing:
and having mit.edu automatically appended to produce prep.ai.mit.edu, then you may want to raise ndots to two so that your users won't unwittingly cause lookups to the root name servers for names in the top-level ai domain. You could do this with:
You can combine both option settings on the same line in resolv.conf, like so:
options debug ndots:2
Also introduced with DNS 4.9 resolvers, and about time, if you ask us, is the ability to put comments in the resolv.conf file. Lines that begin with a pound sign or semi-colon in the first column are interpreted as comments and ignored by the resolver.
If you're just moving to a DNS 4.9.3 or 4.9.4 resolver, be careful when using the new directives. You may still have older resolver code statically linked into programs on your host. Often, this isn't a problem because UNIX resolvers ignore directives they don't understand. But don't count on all programs on your host obeying the new directive.
If you're running on a host with programs that include really old resolver code, before 4.8.3, and you'd still like to use the search directive with programs that can take advantage of it, here's a trick: use both a domain directive and a search directive in resolv.conf, with the domain directive first. Old resolvers will read the domain directive and ignore the search directive, because they won't recognize it. New resolvers will read the domain directive, but the following search directive will override its behavior.