Quick & Dirty Guide to djbDNS

Introduction

djbDNS is Daniel J. Berstein's alternative to BIND. Along the philosophy of Qmail and Postfix, it is built around several small components instead of one big program.

Before installing and running djbDNS, you'll need two add-ons from Berstein: UCSPI-TCP (Unix Client-Server Program; includes xfrdns and axfr-get to perform zone transfers), and daemon-tools (to supervise services.)

djbDNS itself is built on several components:

For added security, Berstein also recommends that rsync and ssh be used to perform zone transferts. This is not a requirement, and djbDNS can work with a remote server running a different DNS server, eg. BIND, either as primary or secondary.

Installing daemon-tools

Daemontools installs svscan, which is a kind of enhanced init to monitor services. It is started from /service, where each subdirectory defines a service. Each service in /service is actually a symlink to the directory trees created by eg. dnscache-conf, tinydns-conf, etc. svscan runs under the control of yet another component called supervise.

  1. tar xzvf daemontools.tar.gz ; cd daemontools ; make setup check.

    Note: By default, binaries are installed in /usr/local/bin, so this location should be listed in the PATH environment variable. This target can be changed by editing conf-home before compiling.

  2. mkdir /service ; chmod 755 /service
  3. Svscan must be launched by init, so append the following to /etc/inittab:

    SV:123456:respawn:env - PATH=/usr/local/bin:/usr/sbin:/usr/bin:/bin svscan /service /dev/console 2>/dev/console

    ... and refresh init through killall -HUP init

    Note: svscan can also be launched manually through svscan /service &, and stopped through killall supervise tinydns svscan

    Check that svscan is running through ps ax | grep sv

Installing djbDNS

tar xzvf djbdns.tar.gz ; cd djbdns ; make setup check

Note: Once again, the target directory is /usr/local/bin/ by default, but can be changed by editing conf-home before running make.

Installing dnscache

  1. Create two system user accounts:

    useradd -d /var/dnscache -s /bin/false dnscache
    useradd -d /var/dnscache -s /bin/false dnslog

  2. If not done by useradd, create the home directory for the two system accounts above: mkdir /var/dnscache. Otherwise, empty that directory from stuff automatically copied into it by useradd, eg. Desktop, .bashrc, etc.
  3. Configure the cache: dnscache-conf dnscache dnslog /var/dnscache/dnscache 10.20.30.12, where 10.20.30.12 is the IP adress on which dnscache should listen for queries
  4. Allow the rest of your network to query dnscache: touch /var/dnscache/dnscache/root/ip/10.20.30
  5. Add dnscache to the list of services to be monitored by svscan: ln -sf /var/dnscache/dnscache /service/, and check that it now shows up through pstree -p
At this point, dnscache can query foreign domains, but you cannot send queries since your client host cannot be resolved through reverse-lookup. This will be solved in a minute by adding tinyDNS, the DNS in charge of our zone.

Installing tinyDNS

  1. Once again, we need two system user accounts:

    useradd -d /var/dnscache -s /bin/false tinydns
    useradd -d /var/dnscache -s /bin/false tinylog

  2. tinydns-conf tinydns tinylog /var/dnscache/tinydns 127.0.0.1

    Note: The reason we have tinyDNS listen on the loopback is that dnscache is already listening on the Ethernet interface. We will set up dnscache to query tinyDNS when it needs to resolve zones for which tinyDNS is authoritative.
    Also, if you want to have log files live in /var/spool/dnscache instead of /etc/tinydns/log/main, edit /etc/tinydns/log/run, and replace "./main" with /var/log/tinydns

  3. Add records:

    # cd /var/dnscache/tinydns/root
    # ./add-ns internal 10.20.30.12
    # ./add-ns 30.20.10.in-addr.arpa 10.20.30.12
    # ./add-mx internal 10.20.30.4
    # ./add-host ns.internal 10.20.30.12
    # ./add-host mail.internal 10.20.30.4
    # ./add-alias unagi.internal 10.20.30.4
    # make

    Note: The data file, /var/dnscache/tinydns/root/data, can also be edited manually. By design, djbDNS does not support CNAME records, so the last entry, unagi, is actually an A record pointing to the same address as mail.

  4. Start tinyDNS through ln -sf /var/dnscache/tinydns /service
  5. To let dnscache know how to query tinyDNS for zones for which tinyDNS is authoritative, create /var/dnscache/dnscache/root/servers/internal with the following line:

    127.0.0.1

    ... followed by:

    cp /var/dnscache/dnscache/root/servers/internal /var/dnscache/dnscache/root/servers/30.20.10.in-addr.arpa

  6. Refresh dnscache (su to root to get the right env't vars) : su - ; svc -t /service/dnscache/
  7. Update the client host to point to tinyDNS (eg. /etc/resolv.conf)
  8. Run nslookup, and send queries for our zone.

Installing ucspi-tcp

UCSPI defines a command-line structure and environment variable specifications for inter-process communications helper programs to make it easy to write clients and servers. It's basically a replacement for inetd/xinetd, SunOS' mconnect, socket, faucet/hose, netcat.

  1. Install ucspi : tar xzvf ucspi.tar.gz ; cd ucspi ; make setup check.

    Note: As before, this will install a bunch of binaries in /usr/local. You can change the target directory by editing the conf-home file.

  2. useradd -d /var/dnscache -s /bin/false axfrdns
    useradd -d /var/dnscache -s /bin/false axfrlog
  3. axfrdns-conf axfrdns axfrlog /var/dnscache/axfrdns /var/dnscache/tinydns 10.20.30.13
  4. Edit /var/dnscache/axfrdns/tcp to list hosts that are allowed to transfer zones:

    10.20.30.14:allow,AXFR="internal/204.200.10.in-addr.arpa"
    :deny

  5. Add axfrdns for svcan to handle: ln -sf /var/dnscache/axfrdns /service
  6. From the remote host 10.20.30.14 acting as the secondary, perform a zone transfer:

    cd /tmp ; tcpclient 10.20.30.13 53 axfr-get internal data data.tmp

    Voilą! The zone has been transfered into data. If the secondary is running BIND, you are on familiar ground.

Q&A

How can I remove a service run by svcan?

cd /service/myservice ; rm /service/myservice ; svc -dx . log

How does dnscache know how to query remote DNS servers?

TLD name servers live /var/dnscache/dnscache/root/servers

Svscan goes bersek!

If PATH does not include /usr/local/bin, svscan cannot run its pal supervise, and you'll get:
/service/dnscache: unable to open supervise/ok: file does not exist

If you launch svscan through /usr/local/bin/svscan instead of editing /etc/inittab followed by killall -HUP init, you'll get:

supervise: fatal: unable to start KDE/run: file does not exist etc.

How to stop svscan/supervise nicely?

The only way I found how to stop a service from being handled by svscan/supervise is to remove it from /service.

As for stopping svscan itself, I haven't found a better than killall svscan supervise tinydns dnscache.

Note: With just svscan running and inittab containing "SV:123456:respawn:/command/svscanboot", I don't know of a better way to kill this process than by commenting this line, running "killall -HUP init", and running "ps aux | grep sv" to check that svscan was finally put to rest.

I'm confused about on which IP address dnscache, tinydns, and axfrdns should listen ?

So am I. Some documentation says that dnscache should listen to the Ethernet address, while tinyDNS should listen on the loopback. "Life With djbdns" shows the use of two Ethernet addresses: dnscache on one address, and tinyDNS/axfrdns listening on a second address.

dnscache works fine with tinydns, but cannot resolve foreign hostnames

Make sure that the network configuration of the host running dnscache is OK (such as its route table).

Temp stuff

djbdns is a collection of Domain Name System tools. It includes several components:
The dnscache program is a local DNS cache. It accepts recursive DNS queries from local clients such as web browsers. It collects responses from remote DNS servers.
The tinydns program is a fast, UDP-only DNS server. It makes local DNS information available to the Internet. It supports load balancing and client differentiation.
The walldns program is a reverse DNS wall. It provides matching reverse and forward records while hiding local host information.
The rbldns program is an IP-address-listing DNS server. It uses DNS to publish a list of IP addresses, such as RBL or DUL.
The dns library handles outgoing and incoming DNS packets. It can be used by clients such as web browsers to look up host addresses, host names, MX records, etc. It supports asynchronous resolution.
The dnsfilter program is a parallel IP-address-to-host-name converter.
The dnsip, dnsipq, dnsname, dnstxt, and dnsmx programs are simple command-line interfaces to DNS.
The dnsq and dnstrace programs are DNS debugging tools.

tinydns handles basic DNS service. The tinydns-data file format combines the flexibility of zone files with the convenience of modern zone-building tools. Host information is stored in one file. PTR records are handled automatically. Changes can be scheduled in advance, with TTLs handled automatically.

tinydns has several load-balancing features. It automatically selects a random set of 8 servers from a cluster of any size. It allows easy removal of dead servers by external monitoring tools. It also supports client differentiation, checking the client's IP address and choosing one of several clusters accordingly.

walldns is a reverse DNS wall. It lets firewalled sites access name-checking servers without revealing true host information.

rbldns publishes lists of IP addresses, such as RBL or DUL, through DNS. This could be done with a general-purpose server, but rbldns uses much less memory and much less disk space.

Resources