Making the Conversion: From BIND to tinydns

Last week, we set up the dns caching server, appropriately named

dnscache. This week, we'll set up tinydns, the process that allows you

to serve your DNS data.

First, let's use the tinydns-conf program to set it up:

# tinydns-conf tinydns dnslog /etc/tinydns 127.0.0.6

Like last week, we'll set this up on an unused IP address for testing,

in this case 127.0.0.6. If you have an actual IP address that is not

currently running BIND or dnscache, then you can use that instead of

127.0.0.6.

tinydns-conf uses the same arguments, namely the user to run the server

(tinydns), the user to run the multilog program (dnslog), and the

directory tinydns will call home (/etc/tinydns). The /etc/tinydns

directory is set up almost exactly the same as /etc/dnscache from last

week, such as the env, log, and supervise directories. /etc/tinydns/root

will contain different data this time, of course.

Next, let's tell svscan that it should start up tinydns:

# ln -s /etc/tinydns /service

In five seconds or so, tinydns should be spawned; however, it doesn't

contain any data yet so let's learn how to put some in. Tinydns doesn't

have zone files like BIND. Instead, all the data resides in one big file

-- /etc/tinydns/root/data -- which is fairly readable by us humans.

Tinydns actually works on a compiled version of this file,

/etc/tinydns/root/data.cdb, which is in cdb (constant database) format

-- a very fast-access database format created by DJB. This file format

is so fast that tinydns never loads any of it's data into memory, unlike

BIND which must load everything to function at all. tinydns assumes the

kernel will keep frequently-accessed buffers in kernel memory (a good

assumption) so you don't hit the disk that often anyway. Tinydns can

keep answering queries even when the new data.cdb file is being updated.

So, lets see what's in the root directory:

# cd /etc/tinydns/root

# cat data

# make

/usr/local/bin/tinydns-data

# ls

Makefile add-host data

add-alias add-mk data.cdb

add-childns add-ns

Our data file currently doesn't have anything in it (no biggie), but we

recreated the data.cdb file with the 'make' command anyway. These add-*

files are simple shell scripts you can use to add new DNS records. Let's

create a new domain -- 'example.dom'[1] -- using these scripts and see

what the actual records look like in the data file:

# ./add-ns example.dom 127.0.0.6

# make

/usr/local/bin/tinydns-data

# cat data

.example.dom:127.0.0.6:a:259200

# host -t soa example.dom 127.0.0.6

example.dom SOA a.ns.example.dom. hostmaster.example.dom.

1027968095 16384 2048 1048576 2560

# host -t soa example.dom 127.0.0.6

example.dom name server a.ns.example.dom.

# host a.ns.example.dom 127.0.0.6

a.ns.example.dom has address 127.0.0.6

(Note that all of our 'host' commands must specify the tinydns server's

IP address, 127.0.0.6, since we're just testing this out.) The add-ns

script simply adds a line of the form to the data file:

.domain:ip_address:name:ttl

However, this one line is all that's needed to configure a domain's SOA

(start of authority) record, and set up an NS record and the associated

A record. Note that the default contact is hostmaster@example.dom. Make

sure this email address is valid.

The TTL for the SOA is set to three days by default (259200 seconds).

Instead of manually listing the NS host name, you simply provide the IP

address, and it dynamically creates the hostname 'a.ns.example.dom'. If

you want to add nameservers, simply call add-ns again:

# ./add-ns example.dom 127.1.1.1

# cat data

.example.dom:127.0.0.6:a:259200

.example.dom:127.1.1.1:b:259200

This command automatically creates a 'b.ns.example.dom' entry with the

new IP address. Since we're just testing here, you should delete that

last line for now using your favorite text editor.

# vi data

Ok, now it's time to add an 'actual' IP addresses. Let's assume we have

our fictitious servers on 192.168.1.0 network:

# ./add-host www.example.dom 192.168.1.1

# ./add-ns 1.168.192.in-addr.arpa 127.0.0.6

# cat data

.example.dom:127.0.0.6:a:259200

.1.168.192.in-addr.arpa:127.0.0.6:a:259200

=www.example.dom:192.168.1.1:86400

# make

/usr/local/bin/tinydns-data

# host www.example.dom 127.0.0.6

www.example.dom has address 192.168.1.1

# host 192.168.1.1 127.0.0.6

1.1.168.192.in-addr.arpa domain name pointer www.example.dom.

First we used add-ns to set up a zone for reverse DNS lookups (the

1.168.192.in-addr.arpa zone). The data line for our new IP address is of

the form:

=hostname:ip_address:ttl

This sets up both a forward (A) and reverse (PTR) record for this host,

as seen in the output of the two host commands. If we wanted only a

forward record, we could have instead used an entry of the form:

+hostname:ip_address:ttl

This entry is created with the 'add-alias' command instead of 'add-host.

We've seen how to create SOA, NS, A, and PTR records thus far, and all

using three different kinds of lines in the data file, which are pretty

easy to read. Other useful lines in data include:

@domain:IP.AD.DR.ES:name:dist

creates an MX record for example.dom pointing to ip_address

named 'name.mx.example.dom' of priority 'dist', and

the appropriate A record, for example

@example.dom:127.127.127.127:mail:10

# host -t mx example.dom 127.0.0.6

example.dom mail is handled by 10 mail.mx.example.dom.

# host mail.mx.example.dom 127.0.0.6

mail.mx.example.dom has address 127.127.127.127

Chostname1:hostname2

creates a CNAME for hostname1 pointing to hostname2, for example

Cftp.example.dom:www.example.dom

# host ftp.example.dom 127.0.0.6

ftp.example.dom is an alias for www.example.dom.

You can use other entries as well. These options can be found within the

documentation at http://cr.yp.to/djbdns/tinydns-data.html, or locally

with the command

# lynx /doc/commands.html

The nice thing about the data lines is that you can usually drop most of

the fields at the end. tinydns automatically will pick appropriate TTLs.

For example, you could use:

=www.example.dom:192.168.1.1

instead of

=www.example.dom:192.168.1.1:86400

At this point, you have all the info you need to create a new tinydns

data file to handle all the DNS data you currently use. You'll also find

that it is easier to read in general, and certainly easier for programs

to manipulate. Here's a quick summary of the line types, including some

I didn't discuss above:

Initial Char Mnemonic Purpose

. zone delimiter Create SOA and NS records

@ email delimiter Create MX records

= define/equal Create A and PTR records

+ Create A record only

C (C)name Create CNAME records

^ carat is pointy Create PTR record only

' text starts with quotes Create TXT record

Z (Z)one Create SOA record only

You can use a lot of different options for performing functions such as

creating different responses depending on the client IP address, similar

to BIND's views, or making records that are only good before or after a

certain time -- helpful for smoothly changing DNS data without

administrator interaction. Just for easy reference, here's a commented

example file:

# The example.dom domain:

.example.dom:127.0.0.6:a

# The reverse DNS entry

.1.168.192.in-addr.arpa:127.0.0.6:a

# A few host entries. (The '=' means PTR records are created too)

=www.example.dom:192.168.1.1

=ftp.example.dom:192.168.1.2

=shell.example.dom:192.168.1.3

=backupmail.example.dom:192.168.1.4

# Mail goes to primary first, backup if that fails

@example.dom:192.168.1.3:primary:10

@example.dom:192.168.1.4:backup:20

# Some CNAMES

Clogin.example.dom:shell.example.dom

Cmailserver.example.dom:shell.example.dom

So, your task this week is to convert some or all of your BIND datafile

to tinydns data format. Test things out on the temporary IP address,

127.0.0.6, and when you get all the bugs worked out, simply turn off

BIND (Forever! Huzzah!) and have tinydns listen on your actual IP

address.

If, for example, you were using 192.168.1.1 with BIND, then do the

following to have tinydns take over:

# echo '192.168.1.1' > /etc/tinydns/env/IP

# svc -d /etc/tinydns

# svc -u /etc/tinydns

Now you are 100% BIND free! Congratulations and welcome to the club of

the secure. Enjoy watching your friends run around like headless

chickens the next time BIND bugs are found as they frantically try to

upgrade machine after machine.

Though the native tinydns data file format is pretty painless and takes

up a lot less room than BIND zone files, you may have a lot of data to

convert. If that's the case, all is not lost. Next week, I'll show

you how you can quickly 'import' your old BIND zones into tinydns data

format.

NOTES

[1] Yes, '.dom' is not a valid DNS suffix. I'm intentionally

choosing something that will not clash with anything out in the real

world.

What’s wrong? The new clean desk test
Join the discussion
Be the first to comment on this article. Our Commenting Policies