D. J. Bernstein
Internet publication
djbdns
Frequently asked questions

DNS server


How do I configure a DNS server? I'm in charge of the heaven.af.mil and 1.2.3 networks. I'd like to run tinydns on IP address 1.2.3.5 to publish my host addresses through DNS.

Answer: This answer assumes that your boot scripts are already running svscan in a /service directory. tinydns relies on svscan to start it and to restart it at boot time.

You will have to make three decisions:

Create the service directory by running the tinydns-conf program, with your IP address at the end of the line:
     tinydns-conf tinydns dnslog /etc/tinydns 1.2.3.5
Tell svscan about the new service:
     ln -s /etc/tinydns /service
svscan will start the service within five seconds.

Now tell tinydns to answer questions about the heaven.af.mil and 3.2.1.in-addr.arpa domains, and to advertise 1.2.3.5 as the DNS server address for each domain:

     cd /service/tinydns/root
     ./add-ns heaven.af.mil 1.2.3.5
     ./add-ns 3.2.1.in-addr.arpa 1.2.3.5
     make
You can also add host addresses and mail-server addresses, as described below.

Finally, tell the parent administrators to delegate domains to your servers:


How do I tell tinydns about a host address? I have three computers: lion on IP address 1.2.3.4, tiger on IP address 1.2.3.5, and bear on IP address 1.2.3.6.

Answer:

     cd /service/tinydns/root
     ./add-host lion.heaven.af.mil 1.2.3.4
     ./add-host tiger.heaven.af.mil 1.2.3.5
     ./add-host bear.heaven.af.mil 1.2.3.6
     make
The ./add-host scripts edit the file /service/tinydns/root/data, which is in tinydns-data format. make runs the tinydns-data program to tell tinydns about the new information. If anything goes wrong, tinydns-data prints an error message, and tinydns continues providing the old information.

As an alternative to ./add-host, you can edit data manually, adding the following lines:

     =lion.heaven.af.mil:1.2.3.4
     =tiger.heaven.af.mil:1.2.3.5
     =bear.heaven.af.mil:1.2.3.6
But the ./add-host scripts will prevent you from accidentally reusing a previous host name, or reusing a previous host IP address. They're also very careful in how they write the new file to disk, so nothing can go wrong if there's a sudden power outage.
How do I check that tinydns is providing the right address for a host? I want to make sure that network-surveys.cr.yp.to has address 131.193.178.181.

Answer: First, check that the address is in data in tinydns-data format.

Second, check that the address is in data.cdb. There is a tinydns-get program that reads information from data.cdb in the current directory:

     # cd /service/tinydns/root
     # tinydns-get a network-surveys.cr.yp.to
     1 network-surveys.cr.yp.to:
     125 bytes, 1+1+2+2 records, response, authoritative, noerror
     query: 1 network-surveys.cr.yp.to
     answer: network-surveys.cr.yp.to 86400 A 131.193.178.100
     authority: yp.to 259200 NS a.ns.yp.to
     authority: yp.to 259200 NS b.ns.yp.to
     additional: a.ns.yp.to 259200 A 131.193.178.181
     additional: b.ns.yp.to 259200 A 131.193.178.181
     #
Look for an answer line showing the address. Common reasons for missing or obsolete information: you didn't run make after changing data; you don't have . lines (or Z lines) in data specifying relevant name servers.

Third, check that the tinydns service is up:

     # svstat /service/tinydns
     /service/tinydns: up (pid 18214) 131432 seconds
     #

Fourth, check that packets are routed properly to the IP address where tinydns is listening:

     # cat /service/tinydns/env/IP
     131.193.178.181
     # telnet 131.193.178.181
     Trying 131.193.178.181...
     telnet: connect to address 131.193.178.181: Connection refused
     #

Fifth, ask tinydns for the address you're checking:

     # dnsq a network-surveys.cr.yp.to 131.193.178.181
     1 network-surveys.cr.yp.to:
     125 bytes, 1+1+2+2 records, response, authoritative, noerror
     query: 1 network-surveys.cr.yp.to
     answer: network-surveys.cr.yp.to 86400 A 131.193.178.100
     authority: yp.to 259200 NS a.ns.yp.to
     authority: yp.to 259200 NS b.ns.yp.to
     additional: a.ns.yp.to 259200 A 131.193.178.181
     additional: b.ns.yp.to 259200 A 131.193.178.181
     # 

Sixth, ask your DNS cache for the address:

     # dnsqr a network-surveys.cr.yp.to
     1 network-surveys.cr.yp.to:
     58 bytes, 1+1+0+0 records, response, noerror
     query: 1 network-surveys.cr.yp.to
     answer: network-surveys.cr.yp.to 86400 A 131.193.178.100
     # dnsip network-surveys.cr.yp.to
     131.193.178.100
     # 
If dnscache can't find the address, the problem is almost certainly that the parent servers haven't delegated the relevant domains to your tinydns. Read the log in /service/dnscache/log/main/current to see which servers dnscache is contacting and what information they are providing. For a thorough debugging scan, use dnstrace:
     # dnstrace a network-surveys.cr.yp.to a.root-servers.net > /root/NSC &
     # sleep 300
     # dnstracesort < /root/NSC | less
     ...
     1 network-surveys.cr.yp.to 128.250.1.21     ALERT: took more than 1 second
     1 network-surveys.cr.yp.to 131.193.178.181  86400 A 131.193.178.100
     1 network-surveys.cr.yp.to 198.41.0.4       see to
     1 network-surveys.cr.yp.to 128.250.1.21     see yp.to
     1 network-surveys.cr.yp.to 128.250.22.2     see yp.to
     1 network-surveys.cr.yp.to 148.59.19.11     see yp.to
     1 network-surveys.cr.yp.to 193.0.0.193      see yp.to
     1 network-surveys.cr.yp.to 196.7.0.137      see yp.to
     1 network-surveys.cr.yp.to 196.7.0.139      see yp.to
     1 network-surveys.cr.yp.to 198.6.1.82       see yp.to
     1 network-surveys.cr.yp.to 206.184.59.10    see yp.to
     1 network-surveys.cr.yp.to 206.86.247.253   see yp.to
     ...

How do I tell tinydns about an alias? I already have lion.heaven.af.mil on IP address 1.2.3.4; I'd like www.heaven.af.mil to point to the same IP address.

Answer:

     cd /service/tinydns/root
     ./add-alias www.heaven.af.mil 1.2.3.4
     make
As an alternative to add-alias, you can edit data manually, adding the following line:
     +www.heaven.af.mil:1.2.3.4

How do I tell tinydns about a mail server address? I've set up an MTA on IP address 1.2.3.4 to handle incoming mail for heaven.af.mil.

Answer:

     cd /service/tinydns/root
     ./add-mx heaven.af.mil 1.2.3.4
     make
(mx stands for ``mail exchanger.'') As an alternative to add-mx, you can edit data manually, adding the following line:
     @heaven.af.mil:1.2.3.4:a
If you add several mail servers for heaven.af.mil, use a for the first, b for the second, etc. add-mx handles this automatically.
How do I replicate my DNS service? Right now IP address 1.2.3.5 is handling all heaven.af.mil queries and 3.2.1.in-addr.arpa queries. I'd like to provide identical information from another machine on IP address 1.2.3.6, so that DNS queries are answered even if one machine crashes.

Answer: First, use tinydns-conf to configure tinydns on 1.2.3.6:

     tinydns-conf tinydns dnslog /etc/tinydns 1.2.3.6
     ln -s /etc/tinydns /service

Next, use your favorite file-management tools in /service/tinydns/root/Makefile on 1.2.3.5 so that changes in /service/tinydns/root/data.cdb are automatically copied to 1.2.3.6:

     remote: data.cdb
             rsync -az -e ssh data.cdb 1.2.3.6:/service/tinydns/root/data.cdb

     data.cdb: data
             /usr/local/bin/tinydns-data

Now tell tinydns about the new server:

     cd /service/tinydns/root
     ./add-ns heaven.af.mil 1.2.3.6
     ./add-ns 3.2.1.in-addr.arpa 1.2.3.6
     make

Finally, tell the administrator of af.mil to add a delegation of heaven.af.mil to the server b.ns.heaven.af.mil running on IP address 1.2.3.6. Similarly, tell the administrator of 2.1.in-addr.arpa to add a delegation of 3.2.1.in-addr.arpa to the server b.ns.3.2.1.in-addr.arpa running on IP address 1.2.3.6.


Can the parent administrator use a different name for my server? We already have delegations to dns1.heaven.af.mil and dns2.heaven.af.mil, not a.ns.heaven.af.mil and b.ns.heaven.af.mil.

Answer: It is essential for your parent servers and your child servers to provide the same names for your child servers. Otherwise you will encounter a disastrous bug in BIND caches around the Internet; a BIND cache that receives a nasty sequence of queries, accidentally or deliberately, will then be unable to contact your servers for a few days.

You can edit data manually to match the names provided by your parent servers:

     .heaven.af.mil:1.2.3.5:dns1.heaven.af.mil
     .heaven.af.mil:1.2.3.6:dns2.heaven.af.mil
Omit the IP addresses for dns1 and dns2 if they appear elsewhere in data:
     .heaven.af.mil::dns1.heaven.af.mil
     .heaven.af.mil::dns2.heaven.af.mil
     +dns1.heaven.af.mil:1.2.3.5
     +dns2.heaven.af.mil:1.2.3.6

What other delegation rules do I have to watch out for? I've paid for this domain, but the parent administrator is refusing to delegate the domain to my servers.

Answer: If the parent has already delegated a domain to a server at the same IP address, it might insist that you use the same server name. The .com registrars do this, because their database can't handle anything else.

The parent might refuse to delegate if all the servers have the same first three address components. The .de registrars do this, because they don't understand the costs of third-party DNS service.

The parent might refuse to delegate to a server that does not have information about the root servers, localhost, and 127.0.0.1:

     &:198.41.0.4:a.root-servers.net
     &:128.9.0.107:b.root-servers.net
     &:192.33.4.12:c.root-servers.net
     &:128.8.10.90:d.root-servers.net
     &:192.203.230.10:e.root-servers.net
     &:192.5.5.241:f.root-servers.net
     &:192.112.36.4:g.root-servers.net
     &:128.63.2.53:h.root-servers.net
     &:192.36.148.17:i.root-servers.net
     &:198.41.0.10:j.root-servers.net
     &:193.0.14.129:k.root-servers.net
     &:198.32.64.12:l.root-servers.net
     &:202.12.27.33:m.root-servers.net
     .localhost
     .1.0.0.127.in-addr.arpa
     =localhost:127.0.0.1
The .fr registrars do this, because they don't understand how DNS works.

Let me know if you encounter other problems of this type.


How do I delegate a domain to another server? I'd like to delegate the elysium.heaven.af.mil domain to the server at IP address 1.2.3.144.

Answer:

     cd /service/tinydns/root
     ./add-childns elysium.heaven.af.mil 1.2.3.144
     make
As an alternative to add-childns, you can edit data manually, adding the following line:
     &elysium.heaven.af.mil:1.2.3.144:a
If you delegate heaven.af.mil to several IP addresses, use a for the first, b for the second, etc. add-childns handles this automatically.
How do I accept a reverse delegation? My parent server has delegated reverse lookups for 1.2.3.144 and 1.2.3.145 to my server at IP address 1.2.3.144.

Answer: If the parent server did

     ./add-childns 144.3.2.1.in-addr.arpa 1.2.3.144
     ./add-childns 145.3.2.1.in-addr.arpa 1.2.3.144
then you should do
     cd /service/tinydns/root
     ./add-ns 144.3.2.1.in-addr.arpa 1.2.3.144
     ./add-ns 145.3.2.1.in-addr.arpa 1.2.3.144
     make
to create the lines
     .144.3.2.1.in-addr.arpa:1.2.3.144:a
     .145.3.2.1.in-addr.arpa:1.2.3.144:a
in /service/tinydns/root/data.

Beware that your parent server might instead have done RFC 2317 ``classless'' reverse delegation, sending all of your reverse domains through a single delegation:

     C144.3.2.1.in-addr.arpa:144.144-145.3.2.1.in-addr.arpa
     C145.3.2.1.in-addr.arpa:145.144-145.3.2.1.in-addr.arpa
     &144-145.3.2.1.in-addr.arpa:1.2.3.144:a
     # or, in BIND master zone-file format:
     # 144.3.2.1.in-addr.arpa. CNAME 144.144-145.3.2.1.in-addr.arpa.
     # 145.3.2.1.in-addr.arpa. CNAME 145.144-145.3.2.1.in-addr.arpa.
     # 144-145.3.2.1.in-addr.arpa. NS a.ns.144-145.3.2.1.in-addr.arpa.
     # a.ns.144-145.3.2.1.in-addr.arpa. A 1.2.3.144
In this case your data file should contain lines such as
     .144-145.3.2.1.in-addr.arpa:1.2.3.144:a
     ^144.144-145.3.2.1.in-addr.arpa:phoenix.elysium.heaven.af.mil
     ^145.144-145.3.2.1.in-addr.arpa:bogey.elysium.heaven.af.mil
using the 144-145.3.2.1.in-addr.arpa domain selected by the parent. Normally ^ lines are unnecessary, because they are automatically generated by = lines, but classless reverse delegation breaks this feature.
How do I balance load among my web servers? I have 50 identical servers running on IP addresses 1.2.3.150, 1.2.3.151, and so on. I'd like to spread www.heaven.af.mil requests among those servers.

Answer: For versions 1.04 and above: Simply put all 50 addresses into data. tinydns will automatically return a random set of 8 addresses for each request.

For versions 1.03 and below: Delegate www.heaven.af.mil to pickdns.


How do I direct traffic away from a dead server? If one of my servers dies, I want tinydns to stop providing that server's IP address, so clients won't waste time trying that server.

Answer: The following answer is for versions 1.04 and above.

tinydns is designed to work with external programs that monitor the health of your servers. Specify each address as an alias with a 5-second TTL:

     +www.heaven.af.mil:1.2.3.150:5
     +www.heaven.af.mil:1.2.3.151:5
     +www.heaven.af.mil:1.2.3.152:5
An external program can remove an alias by simply changing + to - on the relevant line, then running make. Later, when that server has recovered, the program can change - back to +.

Note that standard client behavior is to try each of the addresses provided by tinydns, so a server outage will merely produce delays, not failures. To minimize the delay, smart clients will try each address with a two-second timeout before retrying each address with a long timeout.


How do I send different clients to different clusters of servers? I'd like our local users in 1.2.* and 1.5.* to be directed to a separate cluster of web servers.

Answer: For versions 1.04 and above, add location lines to data:

     %LU:1.2
     %LU:1.5
     %EX
     +www.heaven.af.mil:1.2.3.220:5::LU
     +www.heaven.af.mil:1.2.3.221:5::LU
     +www.heaven.af.mil:1.2.3.222:5::LU
     +www.heaven.af.mil:1.2.3.150:5::EX
     +www.heaven.af.mil:1.2.3.151:5::EX
     +www.heaven.af.mil:1.2.3.152:5::EX
Run make to tell tinydns about the new information. You can use tinydns-get to see the responses that will be provided to particular clients:
     tinydns-get a www.heaven.af.mil 1.5.7.11

Clients with IP addresses 1.2.* or 1.5.* are in location LU and will see addresses 1.2.3.220, 1.2.3.221, 1.2.3.222. Other clients are in location EX and will see addresses 1.2.3.150, 1.2.3.151, 1.2.3.152. Addresses without locations will be provided to all clients.

The location codes, such as LU and EX, must be 1 or 2 bytes long.

For versions 1.03 and below, use pickdns.


How do I answer TCP queries? Why does tinydns answer only UDP queries?

Answer: DNS-over-TCP is much slower than DNS-over-UDP and is inherently much more vulnerable to denial-of-service attacks. Most sites have no need to provide TCP service and should not set it up.

You will need to provide TCP service if you are allowing zone transfers, or if your registrar foolishly checks for TCP service, or if you want to provide record sets over 512 bytes (which won't work with most clients anyway).

To set up TCP service without allowing zone transfers, configure axfrdns with the following line in /etc/axfrdns/tcp:

     :allow,AXFR=""
axfrdns will answer TCP queries from the same database as tinydns.
How do I use nslookup with tinydns? Everyone around the net is able to reach my machine elysium.heaven.af.mil without trouble, but nslookup elysium.heaven.af.mil. 1.2.3.144 says *** Default servers are not available and dies without giving me the elysium address. I've checked that tinydns is running on 1.2.3.144.

Answer: Don't tell nslookup which server to use. It will use your local DNS cache, as specified in /etc/resolv.conf; your DNS cache will contact the appropriate DNS server. For example, to look up SOA records for the com domain:

     nslookup -type=soa com
Even better, use dnsqr instead of nslookup:
     dnsqr soa com

If you want to query a specific DNS server, use dnsq:

     dnsq soa com m.gtld-servers.net

If you really want to use nslookup to query a specific DNS server, do not specify that server on the command line. Use the server command instead:

     nslookup
     server m.gtld-servers.net
     set type=soa
     com.
     exit

nslookup does not work correctly if you specify a non-recursive server on the command line, no matter what software the server is using. For example, nslookup doesn't work with the .com servers:

     % nslookup -type=soa com. m.gtld-servers.net
     *** Can't find server name for address 202.153.114.101: No information
     *** Default servers are not available
BIND servers are recursive by default, so BIND administrators generally don't run into this problem unless they know that they should make their servers non-recursive. tinydns is non-recursive.

What exactly is nslookup doing wrong? Three things:

Everyone recommends against nslookup as a debugging tool. Even the BIND company, which maintains and distributes nslookup, says ``nslookup is deprecated and may be removed from future releases.''

If you really want to pander to nslookup elysium.heaven.af.mil. 1.2.3.144, add

     .144.3.2.1.in-addr.arpa:1.2.3.144
to data, and make sure that 1.2.3.144 appears in an = line.
How fast is tinydns? Can it handle a huge number of incoming queries?

Answer: One site reported receiving 500 queries per second per server at peak times for data from a 350-megabyte data.cdb. The tinydns process handled about 7000 queries per second of CPU time. The CPU was a Pentium III-550.

This example, and lab tests, suggest that tinydns can easily handle the .com server load. However, I don't have enough data on the distribution of .com queries to carry out a realistic experiment.


How long does tinydns take to load data before it answers queries?

Answer: No time at all. tinydns starts answering queries immediately. It loads data from disk on demand, relying on the UNIX kernel's buffer cache to keep frequently used data in memory. In contrast, BIND needs to load all your zone files into memory before it answers any queries.

While you're building a new data.cdb, tinydns continues answering queries from the old data.cdb; when the new data.cdb is complete, tinydns instantly switches to it.


How long does tinydns-data take to build data.cdb?

Answer: One site reported tinydns-data taking under a minute on a Pentium III-550 to create a 350-megabyte data.cdb covering almost 300000 domains.

I also tried the dul.maps.vix.com zone, which had 200000 records and occupied 15 megabytes in data format. tinydns-data took under 5 seconds on a Pentium II-350 to create a new 18-megabyte data.cdb and write it safely to disk.

Note that IP-address lists are much more efficiently handled by rbldns, which stores the same DUL information in just 0.15 megabytes.