As we discussed in Chapter 2, TCP/IP networking may rely on different schemes to convert names into addresses. The simplest way is a host table stored in /etc/hosts. This is useful only for small LANs that are run by one single administrator and otherwise have no IP traffic with the outside world. The format of the hosts file has already been described in Chapter 5.
Alternatively, you can use the Berkeley Internet Name Domain service (BIND) for resolving hostnames to IP addresses. Configuring BIND can be a real chore, but once you've done it, you can easily make changes in the network topology. On Linux, as on many other Unixish systems, name service is provided through a program called named. At startup, it loads a set of master files into its internal cache and waits for queries from remote or local user processes. There are different ways to set up BIND, and not all require you to run a name server on every host.
This chapter can do little more than give a rough sketch of how DNS works and how to operate a name server. It should be sufficient if you have a small LAN and an Internet uplink. For the most current information, you may want to check the documentation contained in the BIND source package, which supplies manual pages, release notes, and the BIND Operator's Guide (BOG). Don't let this name scare you off; it's actually a very useful document. For a more comprehensive coverage of DNS and associated issues, you may find DNS and BIND by Paul Albitz and Cricket Liu (O'Reilly) a useful reference. DNS questions may be answered in a newsgroup called comp.protocols.tcp-ip.domains. For technical details, the Domain Name System is defined by RFC numbers 1033, 1034, and 1035.
The term resolver refers not to a special application, but to the resolver library. This is a collection of functions that can be found in the standard C library. The central routines are gethostbyname(2) and gethostbyaddr (2), which look up all IP addresses associated with a host name, and vice versa. They may be configured to simply look up the information in hosts, to query a number of DNS name servers, or to use the hosts database of Network Information Service (NIS).
The resolver functions read configuration files when they are invoked. From these configuration files, they determine what databases to query, in which order, and other details relevant to how you've configured your environment. The older Linux standard library, libc, used /etc/host.conf as its master configuration file, but Version 2 of the GNU standard library, glibc, uses /etc/nsswitch.conf. We'll describe each in turn, since both are commonly used.
The /etc/host.conf tells the older Linux standard library resolver functions which services to use, and in what order.
Options in host.conf must appear on separate lines. Fields may be separated by white space (spaces or tabs). A hash sign (#) introduces a comment that extends to the next newline. The following options are available:
This option determines the order in which the resolving services are tried. Valid options are bind for querying the name server, hosts for lookups in /etc/hosts, and nis for NIS lookups. Any or all of them may be specified. The order in which they appear on the line determines the order in which the respective services are tried.
multi takes on or off as options. This determines if a host in /etc/hosts is allowed to have several IP addresses, which is usually referred to as being “multi-homed.” The default is off. This flag has no effect on DNS or NIS queries.
As we'll explain in the section the section called Reverse Lookups,” DNS allows you to find the hostname belonging to an IP address by using the in-addr.arpa domain. Attempts by name servers to supply a false hostname are called spoofing. To guard against this, the resolver can be configured to check whether the original IP address is in fact associated with the obtained hostname. If not, the name is rejected and an error is returned. This behavior is turned on by setting nospoof on.
This option takes on or off as arguments. If it is turned on, any spoof attempts will cause the resolver to log a message to the syslog facility.
This option takes an argument specifying a domain name that will be removed from hostnames before lookup. This is useful for hosts entries, for which you might only want to specify hostnames without a local domain. If you specify your local domain name here, it will be removed from a lookup of a host with the local domain name appended, thus allowing the lookup in /etc/hosts to succeed. The domain name you add must end with the (.) character (e.g., :linux.org.au.) if trim is to work correctly.
trim options accumulate; you can consider your host as being local to several domains.
A sample file for vlager is shown in Example 6-1.
Example 6-1. Sample host.conf File
# /etc/host.conf # We have named running, but no NIS (yet) order bind,hosts # Allow multiple addrs multi on # Guard against spoof attempts nospoof on # Trim local domain (not really necessary). trim vbrew.com.
The settings from host.conf may be overridden using a number of environment variables:
This variable specifies a file to be read instead of /etc/host.conf.
This variable overrides the order option given in host.conf. Services are given as hosts, bind, and nis, separated by a space, comma, colon, or semicolon.
This variable determines the measures taken against spoofing. It is completely disabled by off. The values warn and warn off enable spoof checking by turning logging on and off, respectively. A value of * turns on spoof checks, but leaves the logging facility as defined in host.conf.
This variable uses a value of on or off to override the multi options from host.conf.
This variable specifies a list of trim domains that override those given in host.conf. Trim domains were explained earlier when we discussed the trim keyword.
This variable specifies a list of trim domains that are added to those given in host.conf.
Version 2 of the GNU standard library includes a more powerful and flexible replacement for the older host.conf mechanism. The concept of the name service has been extended to include a variety of different types of information. Configuration options for all of the different functions that query these databases have been brought back into a single configuration file; the nsswitch.conf file.
The nsswitch.conf file allows the system administrator to configure a wide variety of different databases. We'll limit our discussion to options that relate to host and network IP address resolution. You can easily find more information about the other features by reading the GNU standard library documentation.
Options in nsswitch.conf must appear on separate lines. Fields may be separated by whitespace (spaces or tabs). A hash sign (#) introduces a comment that extends to the next newline. Each line describes a particular service; hostname resolution is one of these. The first field in each line is the name of the database, ending with a colon. The database name associated with host address resolution is hosts. A related database is networks, which is used for resolution of network names into network addresses. The remainder of each line stores options that determine the way lookups for that database are performed.
The following options are available:
Use the Domain Name System (DNS) service to resolve the address. This makes sense only for host address resolution, not network address resolution. This mechanism uses the /etc/resolv.conf file that we'll describe later in the chapter.
Search a local file for the host or network name and its corresponding address. This option uses the traditional /etc/hosts and /etc/network files.
Use the Network Information System (NIS) to resolve the host or network address. NIS and NIS+ are discussed in detail in Chapter 13.
The order in which the services to be queried are listed determines the order in which they are queried when attempting to resolve a name. The query-order list is in the service description in the /etc/nsswitch.conf file. The services are queried from left to right and by default searching stops when a resolution is successful.
A simple example of host and network database specification that would mimic our configuration using the older libc standard library is shown in Example 6-2.
Example 6-2. Sample nsswitch.conf File
# /etc/nsswitch.conf # # Example configuration of GNU Name Service Switch functionality. # Information about this file is available in the `libc6-doc' package. hosts: dns files networks: files
This example causes the system to look up hosts first in the Domain Name System, and the /etc/hosts file, if that can't find them. Network name lookups would be attempted using only the /etc/networks file.
You are able to control the lookup behavior more precisely using “action items” that describe what action to take given the result of the previous lookup attempt. Action items appear between service specifications, and are enclosed within square brackets, [ ]. The general syntax of the action statement is:
[ [!] status = action ... ]
There are two possible actions:
Controls returns to the program that attempted the name resolution. If a lookup attempt was successful, the resolver will return with the details, otherwise it will return a zero result.
The resolver will move on to the next service in the list and attempt resolution using it.
The available status values on which we can act are:
The requested entry was found without error. The default action for this status is return.
There was no error in the lookup, but the target host or network could not be found. The default action for this status is continue.
The service queried was unavailable. This could mean that the hosts or networks file was unreadable for the files service or that a name server or NIS server did not respond for the dns or nis services. The default action for this status is continue.
This status means the service is temporarily unavailable. For the files files service, this would usually indicate that the relevant file was locked by some process. For other services, it may mean the server was temporarily unable to accept connections. The default action for this status is continue.
A simple example of how you might use this mechanism is shown in Example 6-3.
Example 6-3. Sample nsswitch.conf File Using an Action Statement
# /etc/nsswitch.conf # # Example configuration of GNU Name Service Switch functionality. # Information about this file is available in the `libc6-doc' package. hosts: dns [!UNAVAIL=return] files networks: files
This example attempts host resolution using the Domain Name Service system. If the return status is anything other than unavailable, the resolver returns whatever it has found. If, and only if, the DNS lookup attempt returns an unavailable status, the resolver attempts to use the local /etc/hosts. This means that we should use the hosts file only if our name server is unavailable for some reason.
When configuring the resolver library to use the BIND name service for host lookups, you also have to tell it which name servers to use. There is a separate file for this called resolv.conf. If this file does not exist or is empty, the resolver assumes the name server is on your local host.
To run a name server on your local host, you have to set it up separately, as will be explained in the following section. If you are on a local network and have the opportunity to use an existing name server, this should always be preferred. If you use a dialup IP connection to the Internet, you would normally specify the name server of your service provider in the resolv.conf file.
The most important option in resolv.conf is name server, which gives the IP address of a name server to use. If you specify several name servers by giving the name server option several times, they are tried in the order given. You should therefore put the most reliable server first. The current implementation allows you to have up to three name server statements in resolv.conf. If no name server option is given, the resolver attempts to connect to the name server on the local host.
Two other options, domain and search, let you use shortcut names for hosts in your local domain. Usually, when just telnetting to another host in your local domain, you don't want to type in the fully qualified hostname, but use a name like gauss on the command line and have the resolver tack on the mathematics.groucho.edu part.
This is just the domain statement's purpose. It lets you specify a default domain name to be appended when DNS fails to look up a hostname. For instance, when given the name gauss, the resolver fails to find gauss. in DNS, because there is no such top-level domain. When given mathematics.groucho.edu as a default domain, the resolver repeats the query for gauss with the default domain appended, this time succeeding.
That's just fine, you may think, but as soon you get out of the Math department's domain, you're back to those fully qualified domain names. Of course, you would also want to have shorthands like quark.physics for hosts in the Physics department's domain.
This is when the search list comes in. A search list can be specified using the search option, which is a generalization of the domain statement. Where the latter gives a single default domain, the former specifies a whole list of them, each to be tried in turn until a lookup succeeds. This list must be separated by blanks or tabs.
The search and domain statements are mutually exclusive and may not appear more than once. If neither option is given, the resolver will try to guess the default domain from the local hostname using the getdomainname(2) system call. If the local hostname doesn't have a domain part, the default domain will be assumed to be the root domain.
If you decide to put a search statement into resolv.conf, you should be careful about what domains you add to this list. Resolver libraries prior to BIND 4.9 used to construct a default search list from the domain name when no search list was given. This default list was made up of the default domain itself, plus all of its parent domains up to the root. This caused some problems because DNS requests wound up at name servers that were never meant to see them.
Assume you're at the Virtual Brewery and want to log in to foot.groucho.edu. By a slip of your fingers, you mistype foot as foo, which doesn't exist. GMU's name server will therefore tell you that it knows no such host. With the old-style search list, the resolver would now go on trying the name with vbrew.com and com appended. The latter is problematic because groucho.edu.com might actually be a valid domain name. Their name server might then even find foo in their domain, pointing you to one of their hosts—which clearly was not intended.
For some applications, these bogus host lookups can be a security problem. Therefore, you should usually limit the domains on your search list to your local organization, or something comparable. At the Mathematics department of Groucho Marx University, the search list would commonly be set to maths.groucho.edu and groucho.edu.
If default domains sound confusing to you, consider this sample resolv.conf file for the Virtual Brewery:
# /etc/resolv.conf # Our domain domain vbrew.com # # We use vlager as central name server: name server 172.16.1.1
When resolving the name vale, the resolver looks up vale and, failing this, vale.vbrew.com.
When running a LAN inside a larger network, you definitely should use central name servers if they are available. The name servers develop rich caches that speed up repeat queries, since all queries are forwarded to them. However, this scheme has a drawback: when a fire destroyed the backbone cable at Olaf's university, no more work was possible on his department's LAN because the resolver could no longer reach any of the name servers. This situation caused difficulties with most network services, such as X terminal logins and printing.
Although it is not very common for campus backbones to go down in flames, one might want to take precautions against cases like this.
One option is to set up a local name server that resolves hostnames from your local domain and forwards all queries for other hostnames to the main servers. Of course, this is applicable only if you are running your own domain.
Alternatively, you can maintain a backup host table for your domain or LAN in /etc/hosts. This is very simple to do. You simply ensure that the resolver library queries DNS first, and the hosts file next. In an /etc/host.conf file you'd use “order bind,hosts”, and in an /etc/nsswitch.conf file you'd use “hosts: dns files”, to make the resolver fall back to the hosts file if the central name server is unreachable.