Build a Domain Name Server






Build a Domain Name Server

Run your own DNS server to map hostnames to IP addresses.

The Domain Name System (DNS) is a distributed directory service that maps machine hostnames to IP addresses and vice versa. DNS allows hostnames to be just "pointers" to the actual network location of the server, providing a consistent human-readable hostname even if the actual IP address changes.

Understand DNS in 60 Seconds

The reason DNS is called a " distributed" service is that there is no single machine that contains a comprehensive lookup table for the entire Internet. Instead, DNS functions as a tree, with root servers distributed around the world that look after the top-level domains (TLDs) such as .com. You can find more information about the current root servers at http://www.root-servers.org. The area that each nameserver is responsible for is called a zone, and the details of each zone are typically stored in a configuration file called a zonefile.

At each level, a DNS server can delegate authority for part of its zone below itself, so the root servers delegate authority for .au to certain Australian nameservers, which in turn delegate authority for .com.au to other nameservers, which then delegate authority for .oxer.com.au to Jonathan Oxer's nameservers, which then manage specific host records such as jon.oxer.com.au and provide mappings to IP addresses. The system is very hierarchical and allows for the management of specific hostname data by delegating it right out to the edges of the Internet.

Note that there is nothing stopping you from setting up a domain name server and putting any data in it you like: you could put in an entry for www.microsoft.com that points to the www.oreilly.com server if you wanted to, and if you used that DNS server, that's exactly what you would see. However, unless your DNS server is part of the global namespace that comes under the authority of the root nameservers, nobody else will ever see the records you put in it. It's not enough to just set up a nameserver: you need to have domains "delegated" to your nameserver by the appropriate upstream authority so that other computers will know your server is authoritative for that domain. Otherwise, you are just running an orphan zone.

There are, however, complete alternative DNS namespaces that have been set up outside the usual root servers, but they are accessible only to people using nameservers that have been specially reconfigured. Using these alternative namespaces, you can register domains in .indy, .parody, .job, and even .www, but you'll be cut off from the vast majority of users on the Net.

One final point to be very careful of is that, strictly speaking, domains actually end in a "." (period) character, although the final dot is implied and most Internet users don't even realize that it should be there. Try it yourself: point your browser at www.oreilly.com., including the final dot, and see what happens. If everyone were being technically correct, that final dot would be included on all URLs, but things just work anyway because DNS servers assume we're just being lazy and treat our URLs as if the dot were silently appended. To most people, that's just a piece of useless Net trivia, but once you start configuring your own DNS server, it becomes criticalso keep it in mind.


DNS is actually a very complex subject that can't really be understood in a mere 60 seconds, but the critical things to remember are that it's structured as a hierarchical tree starting from ".", that zones are delegated down the nameserver hierarchy and become more specific at each level, and that zones can map hostnames to IP addresses and vice versa.

Authoritative and Recursive Lookups

When a computer needs to look up a hostname and convert it to an IP address, there are two types of lookups that can be performed.

An authoritative lookup is a query to a nameserver that can answer the request directly from its own knowledge of what does or does not exist in that zone. For example, if you queried the root nameservers for the host www.oreilly.com, they would not be able to answer authoritatively because they do not contain specific information about the hosts in that zone. However, a query to O'Reilly's own nameservers would return an authoritative answer. Nameservers at hosting companies typically spend most of their time providing authoritative answers about zones they manage.

A recursive lookup involves a query to a nameserver that does not specifically know about the requested hostname, but which can then work through the DNS tree to obtain the answer before returning it to the requesting computer. Nameservers at ISPs typically spend most of their time performing recursive lookups on behalf of users rather than serving authoritative answers.

Authoritative and recursive lookups are actually totally different operations, so there is specialized DNS server software available for each type of query. It's not uncommon for a DNS server to run two different packages to handle authoritative and recursive queries.

Install BIND9

For a general-purpose DNS server, a good software choice is BIND (the Berkeley Internet Name Daemon), which is a very popular DNS server that can handle both authoritative and recursive lookups natively:

$ sudo apt-get install bind9
            

If all you want is a recursive DNS service, that's actually all you need to do. If you look in /etc/bind/db.root, you'll find that BIND has been seeded with the latest IP addresses of the root nameservers, allowing it to look up delegation information and issue recursive lookup requests on behalf of other computers right out of the box.

You can test it from a Linux machine without changing your nameserver configuration by specifying the address of your DNS server and performing a manual lookup using the nslookup tool, which is in the dnsutils package:

[email protected]:~$ nslookup jon.oxer.com.au 192.168.0.2
Server:         192.168.0.2
Address:        192.168.0.2#53

Non-authoritative answer:
Name:   jon.oxer.com.au
Address: 202.91.207.154

As you can see, the result was returned nonauthoritatively because the server had to refer to an external source to obtain the answer. If that worked, you can edit /etc/resolv.conf on your workstations and have them use your DNS server for lookups.

Create an Authoritative Forward Zone

Authoritative nameservers come in two types: master and slave. A master nameserver is explicitly configured with all the details of the zones it manages, while a slave is simply told the names of the zones and pointed at a master to periodically refresh its locally cached copies of the zone by performing a zone transfer. In this hack, you'll learn how to configure a master nameserver.

In fact, there's nothing to stop you running all your nameservers as masters; as long as you keep all their configurations synchronized, everything will work fine. External machines doing lookups don't know the difference between a master and a slave: a master/slave setup is purely a convenience issue.


The most master BIND configuration file is /etc/bind/named.conf. Rather than modify it directly, though, it's best to keep your customizations in separate files and have them "included" into the main configuration. The default installation on Ubuntu includes /etc/bind/named.conf.local, which you can use to define your own zones.

To keep everything neat, create a subdirectory in which to store your actual zone files:

$ sudo mkdir /etc/bind/zones
            

Now create a zone file for your zone named after the zone itself, such as /etc/bind/zones/example.com.hosts, and put in the file something like the following:

example.com. IN      SOA     ns1.example.com. hostmaster.example.com. (
          2001061407  ; serial
          10800       ; refresh
          3600        ; retry
          432000      ; expire
          38400 )     ; ttl
example.com. IN      NS      ns1.example.com.
example.com. IN      NS      ns2.example.com.
example.com. IN      MX      30 mail.example.com.
www.example.com.     IN      A       202.91.207.152
mail.example.com.    IN      A       202.91.207.152

The first line specifies the zone, the Start Of Authority as the nameserver ns1.example.com, and the administrative contact as hostmasterexample.com. Notice that the @ symbol is replaced by a dot in the zone file: BIND treats the first item in the string as the username and the rest as the domain. The subsequent values specify how the zone should be treated by other nameservers, such as how long results can be cached.

The NS records specify the nameservers that are authoritative for this zone, the MX record specifies the mail exchange host for this domain along with a priority from 1 to 100 (lower numbers indicating higher priority), and the A records map specific hostnames to IP addresses.

Note that the full hostnames in the zone file all end in a period, and this is where properly specifying hostnames becomes critical. You might leave the dot off the end of URLs when you type them into your browser, but you can't be ambiguous in the zone file! If you leave the final dot off, BIND assumes the hostname has not been explicitly terminated and appends the domain to it, leaving you with addresses like www.example.com.example.com. You can take advantage of this behavior by deliberately leaving off the domain entirely and specifying just the first part of the hostname without a trailing dot:

www             IN      A 202.91.207.152

For BIND to know about your new zone file, you need to edit /etc/bind/named.conf.local and add an entry at the end similar to:

zone "example.com" {
        type master;
        file "/etc/bind/zones/example.com.hosts";
        };

Then restart BIND:

$ sudo /etc/init.d/bind9 reload
            

Now if you try a query against the nameserver for a host in your zone, you will see the result shows your IP address and isn't flagged as "nonauthoritative":

[email protected]:~$ nslookup www.example.com 192.168.0.2
Server:         192.168.0.2
Address:        192.168.0.2#53

Name:   www.example.com
Address: 202.91.207.152

Firewall Rules

If you set up a firewall [Hack #69], you will need to add specific rules to allow queries from external machines to reach it. DNS queries are sent on port 53 using UDP by default, falling back to TCP if the request packet exceeds 512 bytes in size. You therefore need to allow both UDP and TCP on port 53 through your firewall to your DNS server.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows