DJBDNS: The pieces

DJBDNS has many separate pieces, not all of which you necessarily need.

The separate pieces include:

* dnscache -- This is the recursive caching name server, which

simply looks up the DNS records you request. It consults the

thirteen root DNS servers and winds it's way up to the answer.

You can also associate zones with name servers manually to support

non-official zones, such as internal networks. dnscache listens on

both TCP and UDP port 53.

* tinydns -- This is the DNS server you run to let others resolve

your hostnames and IP addresses. It will only serve the data that

you've given it, so you cannot point to it as your default name

server -- point to a dnscache IP address instead. tinydns listens

on UDP port 53.

* axfrdns -- This server allows authorized BIND secondary DNS

servers to mirror your zone files. The 'official' DJBDNS way to

synchronize zones is to simply rsync the files from the master to

the slaves. However, for compatibility with BIND's zone transfers,

you can run axfrdns. axfrdns listens to TCP port 53.

You may have noticed above that dnscache and tinydns both want to listen

on UDP port 53. That means that you cannot have both of these processes

listening on the same IP address. DJB's official retort is that you

should be using separate machines for this purpose anyway, which is

pretty much true. However, if you want to run both on the same machine,

then you can run each on it's own virtual IP address (eth0:0 vs eth0:1,

etc...) or you could run dnscache on localhost (available only to that

machine) and tinydns on the external interface. The network setup you

pick will depend on your needs.

Each of these servers are run through the supervise/svscan processes we

installed earlier. These processes require a special directory layout to

define the programs to run; however, you can run configuration programs

to handle the grunt work. Let's start off by setting up dnscache:

# dnscache-conf dnscache dnslog /etc/dnscache

The arguments are:

* dnscache -- The user the daemon will run as.

* dnslog -- the user the logging component will run as.

* /etc/dnscache -- The directory to set up for supervise.

* -- The IP address dnscache should listen on.

For now I'm setting the IP address to be because it's a

convenient way to test things.[1] If you already have BIND listening on

localhost ( then using won't conflict and we can

verify all is well before turning off BIND.

This creates the following directories inside /etc/dnscache:

* env/ -- Any files in here are environment variables that will be

set for the dnscache process. For example the file 'IP' contains

'' for our current setup. Dnscache uses environment

variables for all its configuration. Unless you have a good

reason, leave the other files as they are. IP is fair game to

change later on.

* log/ -- The logging for dnscache is handled by multilog (part of

daemontools), which will run in this directory.

* log/main/ -- The actual logs go here, automatically rotated for

you. The file 'log/main/current' is always the most current log.

* run -- The command that supervise runs to start dnscache.

* supervise/ -- A directory used by supervise to keep dnscache

running or restart when needed.

* root/ -- The directory into which dnscache will chroot upon


All DJBDNS software uses this same directory layout. However the stuff

that is in root differs from application to application. In the case of

dnscache, the root directory contains files that function as follows:

* root/ip/ -- Dnscache will not answer queries from unauthorized

hosts. If a machine with an IP address W.X.Y.Z contacts this

server, dnscache will answer if it finds a file in the root/ip/

directory named "W.X.Y.Z", "W.X.Y", "W.X", or "W". The presence of

an appropriate file is all that's required -- the contents of the

file are unimportant. (Typically you just create empty files, for

example 'touch 192.168' to grant access to all machines in


* root/servers/ This directory contains lists of servers to contact

for specific zones. By default a file named '@' is installed which

contains the IP addresses of the 13 root DNS servers. If you wish

to point to zones that would not be found by starting at the root

DNS servers, such as an internal network, then you'd create files

here to point to them.[2]

Dnscache-conf will automatically install a root/ip/ file, but

you'll need to add any additional files to allow other IPs or networks

to be allowed. For now, since we are running dnscache on port,

no other machines could connect anyway.[3] If you have any internal

domains that'd you'd need to point to manually, create the appropriate

files in root/servers/.

Now we need to tell svscan to start dnscache:

# ln -s /etc/dnscache /service

In five seconds, svscan should start up dnscache. (Remember, it's

watching that /service directory.) It's now time to see if things are

working correctly. First, do a quick lookup of your favorite hostname

against your current DNS server[4]:

$ host has address

Then verify that dnscache is providing the same data:

$ host has address

This time I hard-coded the address to query against our local

dnscache process. Make sure to check any internal domains, including

reverse lookups. If you're only using BIND for a DNS cache, not serving

local DNS data, then you can turn BIND off and put dnscache into

production. Just make sure to change the env/IP file to have the correct

IP address on which dnscache should listen, and be sure to add the

appropriate files in root/ip to make sure local clients can connect.

If you are serving DNS data with BIND, then you may be able to separate

things by having dnscache listen on an IP address not in use by BIND

(set BIND's listen-on directive in /etc/named.conf) until you can

configure tinydns to serve up the data, at which point you can be BIND


Worst case scenario, you should be able to have BIND listen only on your

external IP address:

listen-on { IP.AD.DR.ES; };

and have dnscache on localhost

# echo > /etc/dnscache/env/IP

and point this machine to dnscache instead of BIND:

$ cat /etc/resolv.conf

search domain.dom


So, let's restart BIND:

# killall -HUP named

and then stop/restart the dnscache program on the new IP address.

# svc -d /etc/dnscache

# svc -u /etc/dnscache

That's it. Next week: tinydns.


[1] Although folks usually think of localhost as, all of

the 127.x.y.z network is locally usable as well, without any

additional configuration or ifconfig commands. Cool, eh?

[2] Examples: If you had an internal zone '' that

is served by and, then create a file

named '' with those two IP addresses each on

their own line. If you want to point to those machines for the

reverse DNS entries for the 192.168.1.x network, put those IP

addresses in a file named If you've

administered DNS before, this backwards notation should look


[3] Assuming you have appropriate kernel ACLs in place

(ipchains/iptables) to disallow connections to localhost from

external interfaces. This is a *really* good idea....

[4]'s IP address may change by the time you read this,

or they delete the A record entirely. I don't know why they

ever gave it one in the first place....

ITWorld DealPost: The best in tech deals and discounts.
Shop Tech Products at Amazon