BIND for the Small LAN
Paul Heinlein
First published on May 25, 2004
Last updated on May 24, 2007
Contents
Note: This article was written at the request of Carla Schroder, and portions of it appear by permission in edited form in her very fine volume, The Linux Cookbook (O’Reilly, 2004).
Why serve DNS locally?
There are two good reasons for putting a DNS server on your local network, even if your local server isn’t answering queries about your network coming from other hosts on the Internet:
-
It can speed up network operations like web browsing that involve frequent hostname lookups.
-
It can provide your network with a central repository of local machine information without having to copy files all around the network.
There’s a third reason: it can be educational and fun. Running a local server will teach you at least a little bit about DNS operations—learning that could possibly come in handy during job interviews—and it provides some satisfaction to those who like to build things themselves.
Building a caching nameserver
The easiest project is setting up BIND to do nothing but cache DNS information locally. A caching server doesn’t provide any authoritative information; it just remembers the answers to previous lookups in case the same lookup is performed again.
Consider the typical small office. It’s a good hunch that, during a typical workday, nearly every workstation will want to know the address of popular hosts like www.google.com. Rather than having every workstation ask Google’s name server for that information, they can ask the local caching nameserver, which only needs to ask for that information once every so often.
A caching nameserver handles three duties:
-
It looks up host information on the Internet and passes it back to the local network.
-
It tells your network clients the address of localhost.
-
It tells your network clients the hostname associated with the address 127.0.0.1.
On a Linux host, the information for the last two items are typically
managed by /etc/hosts
, but it’s prudent to provide information about
the loopback interface via DNS as well.
Using BIND, a caching nameserver will require four configuration files:
the main configuration file for named
, a list of the root name
servers, a definition of localhost, and a definition of the loopback
address, 127.0.0.1.
BIND configuration: named.conf
The main BIND configuration file is typically called named.conf
; it
usually lives in /etc
or thereabouts. Red Hat packages install it as
/etc/named.conf
. Gentoo, on the other hand, installs it as
/etc/bind/named.conf
.
BIND configuration is a subject unto itself, and this example configuration file will not employ all of BIND’s bells and whistles, but it will get you going.
The sample below defines where named
should find its configuration
files, the networks for which it can provide authoritative answers, and
how to find information for other networks.
//
// sample BIND configuration file
//
options {
// tell named where to find files mentioned below
directory "/var/named";
// on a multi-homed host, you might want to tell named
// to listen for queries only on certain interfaces
listen-on { 127.0.0.1; 10.11.12.0/24; };
};
// The single dot (.) is the root of all DNS namespace, so
// this zone tells named where to start looking for any
// name on the Internet
zone "." IN {
// a hint type means that we've got to look elsewhere
// for authoritative information
type hint;
file "named.root";
};
// Where the localhost hostname is defined
zone "localhost" IN {
// a master type means that this server needn't look
// anywhere else for information; the localhost buck
// stops here.
type master;
file "zone.localhost";
// don't allow dynamic DNS clients to update info
// about the localhost zone
allow-update { none; };
};
// Where the 127.0.0.0 network is defined
zone "0.0.127.in-addr.arpa" IN {
type master;
file "revp.127.0.0";
allow-update { none; };
};
The root nameservers: named.root
The first zone
definition listed in the example named.conf
tells
named
how to find information about foreign networks. In the example,
the file is called named.root
, though you can give it any name you
like. It lists the names and addresses of all the root name servers.
Unlike the other configuration files in this example, this file is
maintained by someone other than you. The folks at InterNIC make it
available via ftp: ftp://ftp.internic.net/domain/named.root
. This file
doesn’t change all that often, but you’ll want to check ftp.internic.net
every so often just to make sure.
; This file holds the information on root name servers needed to
; initialize cache of Internet domain name servers
;
; This file is made available by InterNIC
; under anonymous FTP as
; file /domain/named.root
; on server FTP.INTERNIC.NET
; -OR- RS.INTERNIC.NET
;
; last update: Jan 29, 2004
; related version of root zone: 2004012900
;
;
; formerly NS.INTERNIC.NET
;
. 3600000 IN NS A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
;
; formerly NS1.ISI.EDU
;
. 3600000 NS B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET. 3600000 A 192.228.79.201
;
; formerly C.PSI.NET
;
. 3600000 NS C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12
;
; formerly TERP.UMD.EDU
;
. 3600000 NS D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET. 3600000 A 128.8.10.90
;
; formerly NS.NASA.GOV
;
. 3600000 NS E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10
;
; formerly NS.ISC.ORG
;
. 3600000 NS F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241
;
; formerly NS.NIC.DDN.MIL
;
. 3600000 NS G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4
;
; formerly AOS.ARL.ARMY.MIL
;
. 3600000 NS H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET. 3600000 A 128.63.2.53
;
; formerly NIC.NORDU.NET
;
. 3600000 NS I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17
;
; operated by VeriSign, Inc.
;
. 3600000 NS J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30
;
; operated by RIPE NCC
;
. 3600000 NS K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129
;
; operated by ICANN
;
. 3600000 NS L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET. 3600000 A 198.32.64.12
;
; operated by WIDE
;
. 3600000 NS M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33
; End of File
Defining localhost
The third configuration file is much more cryptic than the first two. In
this example, it’s called zone.localhost
, but that name is arbitrary.
You could call it linux.rocks
if you were so inclined. It tells
named
that the address of localhost is 127.0.0.1.
;
; loopback/localhost zone file
;
$TTL 1D
$ORIGIN localhost.
@ IN SOA @ root (
1 ; Serial
8H ; Refresh
15M ; Retry
1W ; Expire
1D) ; Minimum TTL
IN NS @
IN A 127.0.0.1
Defining 127.0.0.1
The last config file tells named
that the hostname associated with the
IP address 127.0.0.1 is localhost.
;
; reverse pointers for localhost
;
$TTL 1D
$ORIGIN 0.0.127.in-addr.arpa.
@ IN SOA localhost. root.localhost. (
1 ; serial
8H ; refresh
15M ; retry
1W ; expire
1D ) ; minimum
IN NS localhost.
1 IN PTR localhost.
That’s about it. Put those files in place, start up named
and you’ve
got yourself a caching nameserver.
Running a local domain
If your local network consists only of a few stationary Unix hosts, then
the easiest way to distribute information about local hostnames is by
pushing a customized /etc/hosts
to each machine.
There are a few common situations in which that simple solution might not meet your needs:
-
You have transitory machines like laptops or LAN-party hosts that occasionally pop up on your network, and you want to manage their network presence with DHCP.
-
Your local network also contains a sprinking of machines running Microsoft Windows, and the local users don’t want to be bothered by copying some obscure text file deep into the bowels of their filesystem.
-
Your network is getting too big to push files around manually.
-
People off your network need your DNS information.
Once you’ve got a caching nameserver up and running, adding information
about your domain is fairly straightforward. You need to modify
named.conf
to tell it about your local domain, and you’ll need two
files to define the names and addresses of your hosts.
Our sample network
The following samples are based on a ficticious domain named schroder.net that lives on the 10.11.12.0 subnet. There are five hosts on our network:
- torvalds (10.11.12.1) for DNS, Mail
- stallman aka depot (10.11.12.2) for NFS/Samba file services
- cert aka www (10.11.12.3), our web server
- wall (10.11.12.4), a workstation
- walsh (10.11.12.5, a workstation
Beefing up named.conf
The example named.conf
listed above needs only two additional zone
blocks in order to know that it’s the authoritative source of
information about the schroder.net domain and the 10.11.12.0 subnet.
zone "schroder.net" IN {
// this is the authoritative server for
// schroder.net info
type master;
file "zone.net.schroder";
};
zone "12.11.10.in-addr.arpa" {
// this is the authoritative server for
// the 10.11.12.0 network
type master;
file "revp.10.11.12";
};
The net.schroder zone file
We’ve told named
that it’s the authoritative data source for the
schroder.net domain, so now it’s time to define it.
This zone file will be a bit more complex than the one we created for the localhost zone. It will have to have an entry for each host, plus it will have to define the name server and mail exchanges for the network.
;
; dns zone for for schroder.net
;
$ORIGIN schroder.net.
$TTL 1D
; any time you make a change to the domain, bump the
; "serial" setting below. the format is easy:
; YYYYMMDDI, with the I being an iterator in case you
; make more than one change during any one day
@ IN SOA torvalds hostmaster (
200405191 ; serial
8H ; refresh
4H ; retry
4W ; expire
1D ) ; minimum
; torvalds.schroder.net serves this domain as both the
; name server (NS) and mail exchange (MX)
NS torvalds
MX 10 torvalds
; define domain functions with CNAMEs
depot CNAME stallman
www CNAME cerf
; just in case someone asks for localhost.schroder.net
localhost A 127.0.0.1
; our hostnames, in alphabetical order
cerf A 10.11.12.3
stallman A 10.11.12.2
torvalds A 10.11.12.1
wall A 10.11.12.4
walsh A 10.11.12.5
The 10.11.12.0 reverse pointers
The reverse pointer file ensures that each host’s IP address points back to the correct hostname. The in-addr.arpa domain was established to provide address-to-host mapping. A host’s IP address is reversed to form its hostname in this domain, so, e.g., 10.11.12.1 would become 1.12.11.10.in-addr.arpa.
For our example domain, we’ll set up reverse pointers for the 10.11.12.0 subnet.
;
; reverse pointers for 10.11.12.0 subnet
;
$ORIGIN 12.11.10.in-addr.arpa.
$TTL 1D
@ IN SOA torvalds.schroder.net. hostmaster.schroder.net. (
200405190 ; serial
28800 ; refresh (8 hours)
14400 ; retry (4 hours)
2419200 ; expire (4 weeks)
86400 ; minimum (1 day)
)
; define the authoritative name server
NS torvalds.schroder.net.
; our hosts, in numeric order
1 PTR torvalds.schroder.net.
2 PTR stallman.schroder.net.
3 PTR cerf.schroder.net.
4 PTR wall.schroder.net.
5 PTR walsh.schroder.net.
Putting it all together
You’ve now got the six configuration files necessary to run your nameserver:
-
named.conf
, the main configuration file fornamed
, -
named.root
, containing the names and addresses of the Internet’s root nameservers, -
zone.localhost
, containing the address for localhost, -
revp.127.0.0
, containing reverse pointers for the 127.0.0.0 network, -
zone.net.schroder
, containing the addresses and hostnames for our sample domain, and -
revp.10.11.12
, containing reverse pointers for our domain’s IP address space.
The named.conf
gets installed into /etc
or thereabouts, while the
others all go into the the directory specified in named.conf
, which in
our example is /var/named
.
Once they’re all in place, start up named
and give it a whirl!
Adding a secondary nameserver
At some point, your network may grow large enough, or receive enough DNS traffic, that you’ll have to have a backup nameserver to relieve traffic on the main server and to have an alternative source for information when your primary nameserver is unavailable.
Once your primary nameserve is properly configured, adding a secondary isn’t terribly difficult. There are basically three steps:
-
Tweak the primary’s
named.conf
so that it’ll transfer information to the secondary and notify it when changes are made to the local domain. -
Tweak the zone and reverse-pointer configs for the local domain so that the secondary is listed as one of the authoritative nameservers for the domain.
-
Get a caching nameserver running on the host that will serve as secondary and then tweak the configs so that it’s aware of its role as secondary.
Configuring named.conf
to know about a secondary nameserver
Telling named
about a secondary is very easy: just add an
also-notify
block to zones for the local domain. The only information
you really need is the IP address of the secondary. For this example,
we’ll make cerf, the web server, our secondary.
Whenever you made a change to the local domain, just bump the serial
number and restart named
or tell it to reload its config files. A
notice will be sent, and the secondary, upon seeing a new, larger serial
number, will ask for a zone transfer to bring itself up to date.
zone "schroder.net" IN {
// this is the authoritative server for
// schroder.net info
type master;
file "zone.net.schroder";
// tell cerf when changes get made
also-notify { 10.11.12.3; }
};
zone "12.11.10.in-addr.arpa" {
// this is the authoritative server for
// the 10.11.12.0 network
type master;
file "revp.10.11.12";
also-notify { 10.11.12.3; }
};
Adding a second NS record
The second task in bringing a secondary online is to add a second NS
record, letting everyone know that both the primary and the secondary
nameservers are available to answer questions about your domain.
A simple one-line addition to both the zone and reverse-pointer configuration files is all that’s needed to define a second nameserver.
;
; dns zone for for schroder.net
;
$ORIGIN schroder.net.
$TTL 1D
; any time you make a change to the domain, bump the
; "serial" setting below. the format is easy:
; YYYYMMDDI, with the I being an iterator in case you
; make more than one change during any one day
@ IN SOA torvalds hostmaster (
200405191 ; serial
8H ; refresh
4H ; retry
4W ; expire
1D ) ; minimum
; torvalds and cerf are our name servers, while torvalds also
; serves as the mail exchange (MX)
NS torvalds
NS cerf
MX 10 torvalds
; define domain functions with CNAMEs
depot CNAME stallman
www CNAME cerf
; just in case someone asks for localhost.schroder.net
localhost A 127.0.0.1
; our hostnames, in alphabetical order
cerf A 10.11.12.3
stallman A 10.11.12.2
torvalds A 10.11.12.1
wall A 10.11.12.4
walsh A 10.11.12.5
;
; reverse pointers for 10.11.12.0 subnet
;
$ORIGIN 12.11.10.in-addr.arpa.
$TTL 1D
@ IN SOA torvalds.schroder.net. hostmaster.schroder.net. (
200405190 ; serial
28800 ; refresh (8 hours)
14400 ; retry (4 hours)
2419200 ; expire (4 weeks)
86400 ; minimum (1 day)
)
; define the authoritative name servers
NS torvalds.schroder.net.
NS cerf.schroder.net.
; our hosts, in numeric order
1 PTR torvalds.schroder.net.
2 PTR stallman.schroder.net.
3 PTR cerf.schroder.net.
4 PTR wall.schroder.net.
5 PTR walsh.schroder.net.
Configuring the secondary
Finally, we need to configure the secondary nameserver. You’ll want to follow the instructions for getting a caching nameserver up and running. Once that’s done, you’ll add zone records for the domain and reverse-pointer information.
The major difference between this configuration and the primary’s is
that the type
is set to “slave” and we have to tell named
where to
find the primary. Otherwise, this named.conf
looks similar to the one
we wrote for the primary.
//
// sample BIND configuration file
//
options {
// tell named where to find files mentioned below
directory "/var/named";
// on a multi-homed host, you might want to tell named
// to listen for queries only on certain interfaces
listen-on { 127.0.0.1; 10.11.12.0/24; }
}
// The single dot (.) is the root of all DNS namespace, so
// this zone tells named where to start looking for any
// name on the Internet
zone "." IN {
// a hint type means that we've got to look elsewhere
// for authoritative information
type hint;
file "named.root";
};
// Where the localhost hostname is defined
zone "localhost" IN {
type master;
file "zone.localhost";
// don't allow dynamic DNS clients to update info
// about the localhost zone
allow-update { none; };
};
// Where the 127.0.0.0 network is defined
zone "0.0.127.in-addr.arpa" IN {
type master;
file "revp.127.0.0";
allow-update { none; };
};
// serve as secondary for schroder.net domain
zone "schroder.net" IN {
type slave;
file "zone.net.schroder";
// where the primary nameserver lives
masters { 10.11.12.1; }
};
// serve as secondary for 10.11.12.0 net info
zone "12.11.10.in-addr.arpa" {
type slave;
file "revp.10.11.12";
masters { 10.11.12.1; }
};
And so much more
BIND has features out of the reach of this short introduction. The man pages and documentation that come packaged with your distribution probably provide a good starting point.
As you might guess, the Internet is also a fine source of information. Two works stand out:
O’Reilly & Associates has published the very fine DNS and BIND and the somewhat newer DNS & BIND Cookbook. Both of these titles are definitely worth a look-see.