TUTORIAL FOR LPI EXAM 202: part 3
Topic 207: Domain Name System (DNS)
David Mertz, Ph.D.
Professional Neophyte
November, 2005
Welcome to "Domain Name System", the third of seven tutorials
covering intermediate network administration on Linux. In this
tutorial, we discuss how to use Linux as a DNS server, chiefly using
BIND 9, with minor discussion of other utilities.
BEFORE YOU START
------------------------------------------------------------------------
About this series
The Linux Professional Institute (LPI) certifies Linux system
administrators at junior and intermediate levels. There are two exams
at each certification level. This series of seven tutorials helps you
prepare for the second of the two LPI intermediate level system
administrator exams--LPI exam 202. A companion series of tutorials is
available for the other intermediate level exam--LPI exam 201. Both
exam 201 and exam 202 are required for intermediate level
certification. Intermediate level certification is also known as
certification level 2.
Each exam covers several or topics and each topic has a weight. The
weight indicate the relative importance of each topic. Very roughly,
expect more questions on the exam for topics with higher weight. The
topics and their weights for LPI exam 202 are:
* Topic 205: Network Configuration (8)
* Topic 206: Mail and News (9)
* Topic 207: Domain Name System (DNS) (8)
* Topic 208: Web Services (6)
* Topic 210: Network Client Management (6)
* Topic 212: System Security (10)
* Topic 214: Network Troubleshooting (1)
About this tutorial
Welcome to "Domain Name System", the third of seven tutorials covering
intermediate network administration on Linux. In this tutorial, we
discuss how to use Linux as a DNS server, chiefly using BIND 9, with
minor discussion of other utilities.
Prerequisites
To get the most from this tutorial, you should already have a basic
knowledge of Linux and a working Linux system on which you can
practice the commands covered in this tutorial.
About DNS
The Domain Name System, very usefully, allows users of TCP/IP
applications to refer to servers by symbolic name rather than by
numeric IP address. The Berkley Internet Name Domain (BIND) software
provides a server daemon called 'named' that answers requests for
information about the IP address assigned to a symbolic name (or a
reverse lookup, or other information). On the client side of the DNS
system, applications a -resolver- is a set of libraries that
applications may utilize to communicating with DNS servers. The BIND
package comes with several client utilities to assist in configuring,
querying, and debugging a BIND 9 server: 'dig', 'nslookup', 'host',
'rndc' (formerly 'ndc'); in essence, these utilities call the same
libraries as other client applications do, but provide direct feedback
on answers provided by DNS servers.
About BIND
As of this writing, the current version of BIND is 9.3.1. The first
stable version of the BIND9 series was released in October 2000. You
may find BIND8, which is still maintained for security patches
(currently at 8.4.6) on some older installations. But as a rule,
upgrade to BIND9 whenever possible. Truly ancient systems might
have BIND4 installed on them, but you should upgrade those as soon as
possible since BIND4 is deprecated.
All version of BIND may be obtained from the Internet Systems
Consortium at: . You may also
find documentation and other resources on BIND at that site.
Other resources
As with most Linux tools, it is always useful to examine the manpages
for any utilities discussed. Versions and switches might change
between utility or kernel version, or with different Linux
distributions. For more in depth information, the Linux Documentation
Project has a variety of useful documents, especially its HOWTOs. See
http://www.tldp.org/. A variety of books on Linux networking have
been published; I have found O'Reilly's _TCP/IP Network
Administration_, by Craig Hunt to be quite helpful (find whatever
edition is most current when you read this).
For DNS and BIND information specifically, O'Reilly's _DNS and BIND_,
Fourth Edition (Paperback) by Paul Albitz and Cricket Liu, is a good
resource. Several other books on BIND are avaialable from various
publishers. This tutorial, of course, cannot cover as much detail as
that 622 page book.
UNDERSTANDING DOMAIN NAME SYSTEM QUERIES
------------------------------------------------------------------------
The topology of DNS
DNS is a hierarchical system of domain -zones-. Each zone provides a
limited set of answers about domain name mappings: those within its
own subdomain. A given server will query up to a more general server
when it does not know a mapping, and if necessary, follow redirect
suggestions until it finds the correct answer (or determines that no
answer can be found, producing an error). When a local 'named' server
finds the answer to a DNS query, it caches that answer for a
configurable amount of time (typically on the order of hours, rather
than seconds or days). By caching DNS queries, the overall network
demand is lowered considerably, especially on top level domain (TLD)
servers. The article on DNS at Wikipedia,
http://en.wikipedia.org/wiki/Domain_Name_System, is an excellent
starting point for understanding the overall architecture. This
tutorial borrows a public domain diagram from that site.
An diagram of a hypothetical DNS query makes it easy to understand the
overall lookup process. Suppose your local machine wishes to contact
the symbolic domain name 'www.wikipedia.org'. To find the
corresponding IP address, your machine would first consult the local
nameserver you have configured for a client machine. This "local"
nameserve may run on the same machine as the client application; or it
may run on a DNS server on your local LAN; or may be provided by your
ISP. In almost all cases, it is an instance of BIND's 'named'. This
"local" nameserver will first check its cache, but assuming no cached
information is available, will perform steps like in the below
diagram:
{An example of DNS recursion:
http://gnosis.cx/publish/programming/Recursive_DNS.gif}
Understand for this diagram that the "DNS Recurser" is the actual DNS
server ('named'), not the client application that talk to it.
DNS uses TCP and UDP on port 53 to serve requests. Almost all DNS
queries consist of a single UDP request from the client followed by a
single UDP reply from the server.
How an application knows where to find a DNS server
Configuring client application access to its DNS server(s) is quite
straightforward. The entire configuration is contained in the file
'/etc/resolve.conf', whose job is principally to specify the IP
addresses for one or main "local" DNS servers. You may manually
configure '/etc/resolve.conf' with known DNS servers; however, if you
use DHCP to configure a client the DHCP handshaking process will add
this information to '/etc/resolve.conf' automatically (you may still
read it, or even modify it, after DHCP sets it up; but it will be
reset on reboot). The library code modified by '/etc/resolv.conf' is
called the "DNS resolver".
If more than one DNS server is configured in an '/etc/resolv.conf'
file, secondary and tertiary DNS servers will be consulted if the
primary server fails to provide an answer within the specified timeout
period. A maximum of three DNS servers may be configured.
The basic entry within an '/etc/resolv.conf' file are the 'nameserver
' entries. Some other entries let you modify returned
answers. For example, the directives 'domain' and 'search' let you
expand names without dots in them (e.g. machines on the local LAN).
The 'options' directive' lets you change timeouts per DNS server, turn
on debugging, decide when to append full domain names, and change
other aspects of DNS resolver behavior. For example, one of my
machines is configued with:
# cat /etc/resolv.conf
search gnosis.lan
nameserver 0.0.0.0
nameserver 192.168.2.1
nameserver 151.203.0.84
options timeout:3
The first directive lets this machine know that machines on the local
LAN use the private domain 'gnosis.lan', so the simple name 'bacchus'
may be resolved as 'bacchus.gnosis.lan'. More than one space-separated
domain may be listed in the 'search' directive. Next I list several
DNS servers to try. The first is the local machine itself, which can
be referred to either as '0.0.0.0' or by its official IP address, but
not with a loopback address. The next 'nameserver' directive lists my
home-office router that connects my LAN to the internet (and provides
DHCP and DNS services). The tertiary nameserver is one provided by my
ISP. I also set on option to use a three second timeout on each
nameserver rather than the default 5 seconds.
DNS client utilities
BIND9 comes with four main client utilities. Three of those, 'dig',
'nslookup', and 'host' perform similar functions, more or less in
descending order of detailedness. All three utilities are simply
command-line utilities to exercise the DNS resolver; what they do is
essentially what many client applications do internally, these
utilities simply provide output on the results of lookups on STDOUT.
The most powerful of the three utilities, 'dig', also has the most
options to limit or configure its output. These utilities are most
often used to lookup an IP address from a symbolic domain name, but
you may also perform reverse lookups or other record types other than
default "A" records. For example, the command 'host -t MX gnosis.cx'
will show you mail servers associated with 'gnosis.cx'. Some examples
help:
#---------------- 'host' query of google.com --------------------#
$ host google.com
google.com has address 72.14.207.99
google.com has address 64.233.187.99
#---------------- 'host' MX query of gnosis.cx ------------------#
$ host -t MX gnosis.cx
gnosis.cx mail is handled by 10 mail.gnosis.cx.
For 'nslookup':
#------- 'nslookup' using default (machine-local) server --------#
$ nslookup gnosis.cx
Server: 0.0.0.0
Address: 0.0.0.0#53
Non-authoritative answer:
Name: gnosis.cx
Address: 64.41.64.172
Or a reverse lookup using 'dig' and specifying a non-default
nameserver:
$ dig @192.168.2.2 -x 64.233.187.99
; <<>> DiG 9.2.4 <<>> @192.168.2.2 -x 64.233.187.99
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 3950
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;99.187.233.64.in-addr.arpa. IN PTR
;; AUTHORITY SECTION:
187.233.64.in-addr.arpa. 2613 IN SOA ns1.google.com. dns-admin.google.com.
2004041601 21600 3600 1038800 86400
;; Query time: 1 msec
;; SERVER: 192.168.2.2#53(192.168.2.2)
;; WHEN: Thu Nov 10 02:00:27 2005
;; MSG SIZE rcvd: 104
The remaining BIND9 utility to keep in mind is 'rndc'. The 'rndc'
utility controls the operation of a name server. It supersedes the
'ndc' utility that was provided in old BIND releases. If rndc is
invoked with no command line options or arguments, it prints a short
summary of the supported commands. See the 'man' page for 'rndc' for
full information on its use.
RUNNING A NAME SERVER
------------------------------------------------------------------------
BIND configurations
When you run the 'named' daemon to provide a DNS server, you may
choose from three modes of operation: master, slave, and caching-only.
The 'named' daemon itself looks in its configuration files to
determine its operating mode, chiefly '/etc/bind/named.conf'.
In master mode, the 'named' server acts as the authoritative source for
all information about its zone. Domain information provided by the
server is loaded from a local disk file that is manually modified or
updated. Each DNS zone should have exactly one master server.
In slave mode, the 'named' server transfers its zone information from
the master server for its zone. Technically, a multi-zone server can
be master of one zone and slave for another, but more commonly a LAN
installation will have a single hierarchy between master and slave or
caching-only servers. A slave mode server transfers complete zone
information to local files from its master server, so the answers
provided by a slave server are still considered authoritative.
In caching-only mode, the 'named' server keeps no zone files. Every
query relies on some other name server for an initial answer, but to
minimize bandwidth usage, previous queries are cached by the
caching-only server. However, any novel query must be answered by a
query sent over the network. Caching-only servers are most common on
local machines where client applications can often perform a lookup
without any network traffic.
In the '/etc/resolv.conf' configuration given as an example earlier,
'0.0.0.0' is a caching-only server, '192.168.2.1' is a slave server,
and '151.203.0.84' is a master server. You cannot tell this for
certain just based on the order or IP addresses used, but the use of
the local machine pseudo-IP address '0.0.0.0' is suggestive of it
running a caching-only server.
Configuring 'named.conf'
There are some standard features that pretty much every
'/etc/bind/named.conf' file will have. An initial 'options' directive
will configure some basic information. After that, several 'zone'
directives will provide information on how to handle various zone
requests. Domains given in 'zone' directives as IP address represent
intial portions of IP address ranges, but are indicated "backwards".
Symbolic names may define zones too, allowing further specified
subdomains.
A 'named.conf' file (and other BIND configuration files) follow
somewhat C-like formatting conventions. Both C-style block comments
('/* comment */') and C++-style line comments ('// comment') are
allowed; as are shell-style line comments ('# comment'). Directives
are followed by semi-colon devided statements surrounded by
curly-brackets. As a start, let us see some common options. My local
'/etc/bind/named.conf' begins with:
include "/etc/bind/named.conf.options";
But you may equally use the 'options' directive directly:
#---------------- Configuring 'named.conf' options --------------#
options {
directory "/var/bind";
forwarders { 192.168.2.1; 192.168.3.1};
// forward only;
}
This setup lets files specified without a full path be located in a
relative 'directory'; it also tells the local 'named' to look first in
'192.168.2.1' and '192.168.3.1' for non-cached results; the 'forward
only' directive (commented out here) says to only look in those
nameservers on the local LAN, rather than ask the root servers on the
internet.
A special 'zone' directive is present in nearly all 'named.conf'
files:
#----------------- Hint zone for root servers -------------------#
zone "." {
type hint;
file "/etc/bind/db.root";
};
The contents of 'db.root' (sometimes called 'named.ca' for "certifying
authority") is special. It points to canonical root servers, the
domain registars themselves. There values change rarely, but you
may obtain an official latest version from 'ftp.rs.internic.net'.
This is not a file a regular administrator will modify.
Beyond the root zone hint, a 'named.conf' file will contain some
master and/or slave zones. For example, for the local loopback:
#------------------- Loopback zone configuration ----------------#
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
More interestingly, a 'named' server might act as master for a domain
(and provide reverse lookup):
#--------------------- External zone configuration --------------#
zone "example.com" {
type master;
file "example.com.hosts"; // file relative to /var/bind
};
// Reverse lookup for 64.41.* IP addresses (backward IP address)
zone "41.64.in-addr.arpa" {
type master;
file "41.64.rev";
};
For a slave configuration, you might instead use:
#--------------- External zone configuration (slave) ------------#
zone "example.com" {
type slave;
file "example.com.hosts"; // file relative to /var/bind
masters { 192.168.2.1; };
};
// Reverse lookup for 64.41.* IP addresses (backward IP address)
zone "41.64.in-addr.arpa" {
type slave;
file "41.64.rev";
masters { 192.168.2.1; };
};
Other configuration files
The 'named.conf' file references a number of other configuration
files with the 'file' directive. These names are dependent on your
specific setup, but in general will contain various resource records,
that are defined in RFC 1033 ("Domain Adminstrators Operations
Guide"). The standard resource records are:
SOA: "Start of authority". Paramaters affecting an entire zone.
NS: "Nameserver". A domains name server.
A: "Address". Hostname to IP address.
PTR: "Pointer". IP address to hostname.
MX: "Mail exchange". Where to deliver mail for a domain.
CNAME: "Canonical name". Hostname alias.
TXT: "Text". Stores arbitrary values.
The format of a record is:
IN
The name and time-to-live are optional, and default to the last values
used. The literal string "IN" means internet, and is always used in
practice. The resource record files may also contain directives which
begin with a dollar sign. The most common of these is probably '$TTL'
which sets a default time-to-live. For example, a somewhat trivial
record file for the '127.*' localhost looks like:
# cat /etc/bind/db.127
; BIND reverse data file for local loopback interface
;
$TTL 604800
@ IN SOA localhost. root.localhost. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
1.0.0 IN PTR localhost.
Other directives are '$ORIGIN' which set the domain name used to
complete any relative domain name; '$INCLUDE' reads an external file;
'$GENERATE' creates a series of resource records covering a range of
IP addresses.
Reverse zone files
Reverse zone files (often indicated with a '.rev' extension) contain
mappings from zone-specific IP address to symbolic names. For
example, we might have a file '/var/bind/41.64.rev' that contains:
#--------------- Reverse zone file for 64.41.* ------------------#
$TTL 86400
; IP address to hostname
@ IN SOA example.com. mail.example.com. (
2001061401 ; Serial
21600 ; Refresh
1800 ; Retry
604800 ; Expire
900 ) ; Negative cach TTL
IN NS ns1.example.com.
IN NS ns2.example.com.
; Define names for 64.41.2.1, 64.41.2.2, etc.
1.2 IN PTR foo.example.com.
2.2 IN PTR bar.example.com.
3.2 IN PTR baz.example.com.
Forward zone files
Forward zone files (often named as 'domain.hosts') contain the crucial
'A' records for mapping symbolic names to IP address. For example, we
might have a file '/var/bind/example.com.hosts' that contains:
#------------- Forward zone file for example.com ----------------#
$TTL 86400
; Hostname to IP address
@ IN SOA example.com. mail.example.com. (
2001061401 ; Serial
21600 ; Refresh
1800 ; Retry
604800 ; Expire
900 ) ; Negative cach TTL
IN NS ns1.example.com.
IN NS ns2.example.com.
localhost IN A 127.0.0.1
foo IN A 64.41.2.1
www IN CNAME foo.example.com
bar IN A 64.41.2.2
bar IN A 64.41.2.3