DekGenius.com
I l@ve RuBoard Previous Section Next Section

7.1 Controlling the Name Server

Traditionally, administrators have controlled the BIND name server, named, with Unix signals. The name server interprets the receipt of certain signals as an instruction to take a particular action, such as reloading all of the primary master zones that have changed. However, there are a limited number of signals available, and signals offer no means of passing along additional information such as the domain name of a particular zone to reload.

In BIND 8.2, the ISC introduced a method of controlling the name server by sending messages to it on a special control channel. The control channel can be either a Unix domain socket or a TCP port that the name server listens on for messages. Because the control channel isn't limited to a finite number of discrete signals, it's more flexible and powerful. The ISC says that the control channel is the way of the future and that administrators should use it, rather than signals, for all name server management.

You send messages to a name server via the control channel using a program called ndc (in BIND 8) or rndc (in BIND 9). ndc has been around since BIND 4.9, but prior to BIND 8.2, it was simply a shell script that allowed you to substitute convenient arguments (such as reload ) for signals (such as HUP ). We'll talk about that version of ndc later in this chapter.

7.1.1 ndc and controls (BIND 8)

Executed without arguments, ndc will try to communicate with a name server running on the local host by sending messages through a Unix domain socket. The socket is usually called /var/run/ndc , though some operating systems use a different pathname. The socket is normally owned by root and readable and writable only by the owner. BIND 8.2 and later name servers create the Unix domain socket when they start up. You can specify an alternate pathname or permissions for the socket using the controls statement. For example, to change the socket's path to /etc/ndc and group ownership to named, and to make the socket readable and writable by both owner and group, you could use:

controls {
	unix "/etc/ndc" perm 0660 owner 0 group 53;  // group 53 is "named"
};

The permission value must be specified as an octal quantity (with a leading zero to indicate its octalness). If you're not familiar with this format, see the chmod(1) manpage. The owner and group values must also be numeric.

The ISC recommends, and we agree, that you restrict access to the Unix domain socket to administrative personnel authorized to control the name server.

You can also use ndc to send messages across a TCP socket to a name server, possibly remote from the host that you're running ndc on. To use this mode of operating, run ndc with the -c command-line option, specifying the name or address of the name server, a slash, and the port on which it's listening for control messages. For example:

# ndc -c 127.0.0.1/953

To configure your name server to listen on a particular TCP port for control messages, use the controls statement:

controls {
	inet 127.0.0.1 port 953 allow { localhost; };
};

By default, BIND 8 name servers don't listen on any TCP ports. BIND 9 name servers listen on port 953 by default, so we're using that port here. We're configuring the name server to listen only on the local loopback address for messages, and to allow only messages from the local host. Even this isn't especially prudent, since anyone with a login on the local host will be able to control the name server. If we felt even more imprudent (and we don't advise this), we could widen the allow access list and let the name server listen on all local network interfaces by specifying:

controls {
	inet * port 953 allow { localnets; };
};

ndc supports two modes of operation, interactive and noninteractive. In noninteractive mode, you specify the command to the name server on the command line, for example:

# ndc reload

If you don't specify a command on the command line, you enter interactive mode:

# ndc
Type   help  -or-   /h   if you need help.
ndc>

/h gives you a list of commands that ndc (not the name server) understands. These apply to ndc 's operation, not the name server's:

ndc> /h
        /h(elp)                 this text
        /e(xit)                 leave this program
        /t(race)                toggle tracing (protocol and system events)
        /d(ebug)                toggle debugging (internal program events)
        /q(uiet)                toggle quietude (prompts and results)
        /s(ilent)               toggle silence (suppresses nonfatal errors)
ndc>

For example, the /d command induces ndc to produce debugging output (e.g., what it's sending to the name server and what it's getting in response). It has no effect on the name server's debugging level. For that, see the debug command, described later.

Note that /e, not /x or /q, exitsndc. That's a little counterintuitive.

help tells you the commands at your disposal. These control the name server:

ndc> help
getpid
status
stop
exec
reload [zone] ...
reconfig [-noexpired] (just sees new/gone zones)
dumpdb
stats
trace [level]
notrace
querylog
qrylog
help
quit
ndc>

There are two commands that aren't listed here, though you can still use them: start and restart. They're not listed because ndc is telling you what commands the name server—as opposed to ndc—understands. The name server can't perform a start command, since to do so it would need to be running (and if it's running, it doesn't need to be started). It can't perform a restart command, either, because if it exited, it would have no way to start a new instance of itself (it wouldn't be around to do it). None of this prevents ndc from doing a start or restart, though.

Here's what those commands do:

getpid

Prints the name server's current process ID.

status

Prints lots of useful status information about the name server, including its version, its debug level, the number of zone transfers running, and whether query logging is on.

start

Starts the name server. If you need to start named with any command-line arguments, you can specify these after start. For example, start -c /usr/local/etc/named.conf.

stop

Causes the name server to exit, writing dynamic zones to their zone data files.

restart

Stops and then starts the name server. As with start, you can specify command-line arguments for named after the command.

exec

Stops and then starts the name server. Unlike restart, however, you can't specify command-line options for named; the name server just starts a new copy of itself with the same command-line arguments.

reload

Reloads the name server. Send this command to a primary master name server after modifying its configuration file or one or more of its zone data files. Send this command to a 4.9 or later slave name server to have it update its slave zones if they are not current. You can also specify one or more domain names of zones as arguments to reload; if you do, the name server will reload only these zones.

reconfig [-noexpired]

Tells the name server to check its configuration file for new or deleted zones. Send this command to a name server if you've added or deleted zones but haven't changed any existing zones' data. Specifying the -noexpired flag tells the name server not to bother you with error messages about zones that have expired. This can come in handy if your name server is authoritative for thousands of zones and you want to avoid seeing a flurry of expiration messages you already know about.

dumpdb

Dumps a copy of the name server's internal database to named_dump.db in /usr/tmp (Version 4) or in the name server's current directory (Version 8).

stats

Appends the name server's statistics to named.stats in /usr/tmp (Version 4) or in the name server's current directory (Version 8).

trace [level]

Appends debugging information to named.run in /usr/tmp (Version 4) or in the name server's current directory (Version 8). Specifying higher debug levels increases the amount of detail in the debugging information. For information on what is logged at each level, see Chapter 13.

notrace

Turns off debugging.

querylog (or qrylog )

Toggle logging all queries with syslog. Logging takes place at priority LOG_INFO. named must be compiled with QRYLOG defined (it is defined by default). This feature was added in Version 4.9.

quit

Ends the control session.

7.1.2 rndc and controls (BIND 9)

BIND 9, like BIND 8, uses the controls statement to determine how the name server listens for control messages. The syntax is the same, except that only the inet substatement is allowed. (BIND 9.1.0 doesn't support Unix domain sockets for the control channel, and the ISC suggests BIND 9 probably never will.)

With BIND 9, you can leave out the port specification and the name server will default to listening on port 953. You must also add a keys specification:

controls {
       inet * allow { any; } keys { "rndc-key"; };
};

This determines which cryptographic key rndc users must authenticate themselves with to send control messages to the name server. If you leave the keys specification out, you'll see this message after the name server starts:

Jan 13 18:22:03 terminator named[13964]: type 'inet' control channel 
has no 'keys' clause; control channel will be disabled

The key or keys specified in the keys substatement must be defined in a key statement:

key "rndc-key" {
        algorithm hmac-md5;
        secret "Zm9vCg==";
};

The key statement can go directly in named.conf, but if your named.conf file is world-readable, it's safer to put it in a different file that's not world-readable and include that file in named.conf:

include "/etc/rndc.key";

The only algorithm currently supported is HMAC-MD5, a technique for using the fast MD5 secure hash algorithm to do authentication.[1] The secret is simply the base 64 encoding of a password that named and authorized rndc users will share. You can generate the secret using programs like mmencode or dnssec-keygen from the BIND distribution, as described in Chapter 11.

[1] See RFCs 2085 and 2104 for more information on HMAC-MD5.

For example, you can use mmencode to generate the base 64 encoding of foobarbaz:

% mmencode
foobarbaz
CmZvb2JhcmJh

To use rndc, you need to create an rndc.conf file to tell rndc which authentication keys to use and which name servers to use them with. rndc.conf usually lives in /etc. Here's a simple rndc.conf file:

options {
        default-server localhost;
        default-key "rndc-key";
};

key "rndc-key" {
        algorithm hmac-md5;
        secret "Zm9vCg==";
};

The syntax of the file is very similar to the syntax of named.conf. In the options statement, you define the default name server to send control messages to (which you can override on the command line) and the name of the default key to present to remote name servers (which you can also override on the command line).

The syntax of the key statement is the same as that used in named.conf, described earlier. The name of the key in rndc.conf, as well as the secret, must match the key definition in named.conf.

Remember that since you're storing keys (which are essentially passwords) in rndc.conf and named.conf, you should make sure that neither file is readable by users who aren't authorized to control the name server.

If you're using rndc to control only a single name server, its configuration is straightforward. You define an authentication key using identical key statements in named.conf and rndc.conf. Then you define your name server as the default server to control with the default-server substatement in the rndc.conf options statement, and define the key as the default key using the default-key substatement. Then run rndc as:

% rndc reload

If you have multiple name servers to control, you can associate each with a different key. Define the keys in separate key statements, and then associate each key with a different server in a server statement:

server localhost { 
	key "rndc-key";
};

server wormhole.movie.edu {
	key "wormhole-key";
};

Then run rndc with the -s option to specify the server to control:

% rndc -s wormhole.movie.edu reload

If you haven't associated a key with a particular name server, you can still specify which key to use on the command line with the -y option:

% rndc -s wormhole.movie.edu -y rndc-wormhole reload

Finally, if your name server is listening on a nonstandard port for control messages (i.e., a port other than 953), you must use the -p option to tell rndc which port to connect to:

% rndc -s terminator.movie.edu -p 54 reload

Now the bad news: in BIND 9.0.0, rndc supports only the reload command—and not single-zone reloads, which aren't supported until 9.1.0. Though BIND 9.1.0 doesn't support all the commands that BIND 8 does, it does support the reload, stop, stats, querylog,and dumpdb commands, as well as the new refresh and halt commands:

refresh

Schedules immediate maintenance for a slave zone

halt

Stops the name server without saving pending updates to journa l files

7.1.3 Using Signals

Now, back in the old days, all we had to control the name server with were signals. If you're stuck in the past (with a version of BIND older than 8.2), you'll need to use signals to manage your name server. We'll give you a list of the signals you can send to a name server and tell you which modern ndc command each is equivalent to. If you have the shell script version of ndc (from BIND 4.9 to 8.1.2), you don't have to pay attention to the signal names because ndc will translate the commands into the appropriate signals. Be careful not to use a BIND 4 version of ndc with a BIND 8 name server, since the signal to send for statistics has changed.

Command

Signal

reload

HUP

dumpdb

INT

stats

ABRT (BIND 4) or ILL (BIND 8)

trace

USR1

notrace

USR2

querylog

WINCH

stop (BIND 8)

TERM

So to toggle query logging with an older version of ndc, you could use:

# ndc querylog

just as you would with the newer version of ndc. Under the hood, though, this ndc is tracking down named 's PID and sending it the WINCH signal.

If you don't have ndc, you'll have to do what ndc does by hand: find named 's process ID and send it the appropriate signal. The BIND name server leaves its process ID in a disk file called the pid file, making it easier to chase the critter down—you don't have to use ps. The most common path for the pid fileis /var/run/named.pid. On some systems, the pid file is /etc/named.pid. Check the named manual page to see which directory named.pid is in on your system. Since the name server's process ID is the only thing in the pid file, sending a HUP signal can be as simple as:

# kill -HUP `cat /var/run/named.pid`

If you can't find the pid file, you can always find the process ID with ps. On a BSD-based system, use:

% ps -ax | grep named

On a SYS V-based system, use:

% ps -ef | grep named

However, you may find more than one named process running if you use ps, since BIND name servers spawn children to perform zone transfers. During a zone transfer, the name server pulling the zone data—the slave—may start a child process, and the name server providing the zone data—its master—may also start a child process. We'll digress a little here and explain why child processes are used.

BIND 4 and BIND 8 slave name servers start a child process to perform a zone transfer. This allows the slave name server to keep answering queries while the zone data is being transferred from the master server to the local disk by the child process. Once the zone is on the local disk, the slave name server reads in the new data. Using a child process to do the zone transfer fixed a problem with pre-4.8.3 versions of BIND in which slave name servers wouldn't answer queries during a zone transfer. This could be a real nuisance on name servers that loaded lots of zones or large zones: they'd go silent for long periods of time.

BIND 9 slave name servers, with their new architecture, don't need to spawn a child process to prevent the name server from going silent while transferring a zone. A name server can transfer a zone while it answers queries.

Version 8 and 9 master name servers do not spawn a child process to provide a zone to a slave name server. Instead, the master server transfers the zone at the same time that it answers queries. If the master server loads a new copy of the zone from a zone data file while a transfer of that zone is in progress, it aborts that zone transfer and loads the new zone from the zone data file. The slave server will have to attempt the zone transfer again after the master has completed loading the new zone.

A Version 4 master name server starts a child process to provide a zone to a slave name server. This creates an additional load on the host running the master server, especially if the zones are very large or many zone transfers are active at one time.

If the ps output shows multiple name servers, you should be able to easily tell which name server process is the parent and which processes are children. A child name server started by a slave server to pull a copy of a zone is called named-xfer instead of named:

root  548 547  0 22:03:17 ?     0:00 named-xfer -z movie.edu
      -f /usr/tmp/NsTmp0 -s 0 -P 53 192.249.249.3

A child name server started by a master name server changes its command-line options to indicate which slave server it is providing the zone to:

root 1137 1122 6 22:03:18 ?     0:00 /etc/named -zone XFR
     to [192.249.249.1]

You may encounter a version of named that doesn't change its command line, but you can still figure out the relationship between multiple named processes by examining their process IDs and parent process IDs. All the child processes will have the parent name server's process ID as their parent process ID. This may seem like stating the obvious, but you should only send signals to the parent name server process. The child processes go away after the zone transfers complete.

    I l@ve RuBoard Previous Section Next Section