7.2. Domain name system (DNS)

The function of the DNS service (as we explained in the unit on network administration) is to translate the machine names (legible and easy to remember for users) into IP addresses or vice-versa.

Example 7-1. Example

When we ask the IP address of pirulo.remix.com is, the server will respond 192.168.0.1 (this process is known as mapping); likewise, when we request an IP address, the service will respond with the name of the machine (known as reverse mapping).

Important

The domain name system (DNS) is a tree architecture that avoids duplicating information and makes any searches easier. For this reason, a single DNS makes no sense unless it is part of the architecture.

The application that provides this service is called named, it is included in most GNU/Linux distributions (/usr/sbin/named) and it is part of the package called bind (currently version 9.x) coordinated by the ISC (Internet software consortium). The DNS is simply a database, which means that the people that modify it have to be aware of its structure, as, otherwise, the service will be affected. As a precaution, special care must be taken to save copies of the files to avoid any interruption in the service. The package in Debian comes as bind and bind.doc. [LN01, Deb03c, IET03]. The configurations are similar, as they are FC, but you will have to install bind, bind-utils and caching-nameserver which will be managed by the yum for example.

7.2.1. Cache names server

Firstly, we will configure a DNS server to resolve requests, which will act as a cache for name queries (resolver, caching only server). In other words, the first time, the appropriate server will be consulted because we are starting with a database that contains no information, but all subsequent times, the cache names server will respond, with the corresponding decrease in response times. To configure the cache names server, we need the /etc/bind/named.conf file (in Debian), which has the following (the original comments within the file, indicated with //, have been respected):

options { 
directory "/var/cache/bind"; 
            // query-source address * port 53;
            // forwarders { 
            //    0.0.0.0;
            //
            }; 
            auth-nxdomain no; # conform to RFC1035
            }; 
// prime the server with knowledge of the root servers}
zone "." { 
            type hint; 
            file "/etc/bind/db.root"; };
            // be authoritative for the localhost forward and reverse zones, and for 
            // broadcast zones as per RFC 1912
            }
zone "localhost" { 
            type master; 
            file "/etc/bind/db.local"; 
            };
zone "127.in-addr.arpa" { 
            type master; 
            file "/etc/bind/db.127"; 
            };
zone "0.in-addr.arpa" { 
            type master; 
            file "/etc/bind/db.0"; 
            };
zone "255.in-addr.arpa" { 
            type master; 
            file "/etc/bind/db.255"; 
            };
// add entries for other zones below here
}

The directory sentence indicates where we will find the remaining configuration files (/var/cache/bind in our case). The /etc/bind/db.root file will contain something similar to the following (only the first lines, which are not comments indicated by a ';', are shown, and care must be taken with the dots [.]) at the beginning of some lines –they can be obtained and updated directly from the Internet–):

...
; formerly NS.INTERNIC.NET
;
. 3600000 IN NS A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
;
; formerly NS1.ISI.EDU
;
. 3600000 NS B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET. 3600000 A 128.9.0.107
;
; formerly C.PSI.NET
;
. 3600000 NS C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12
;
...

This file described the root name servers in the world. These servers change, which means that the file must be updated regularly from the Internet. The following sections are the zones; the localhost and 127.in-addr.arpa zones, that link the files to the etc/bind/db.local and /etc/bind/db.127 directories, refer to the direct and inverse resolution for the local interface. The following zones are for the broadcast zones (see RFC 1912) and the appropriate zones should be added at the end. For example, the db.local file could be (';' means 'comment'):

; BIND reverse data file for local loopback interface 
$TTL 604800 
@   IN   SOA    ns.remix.bogus.   root.remix.bogus. (
         1                        ; Serial 
         604800                   ; Refresh 
         86400                    ; Retry 
         2419200                  ; Expire 
         604800)                  ; Negative Cache TTL
@        IN          NS           ns.remix.bogus.
1.0.0    IN          PTR          localhost.

We will explain how it is used later. The next step is to put the name server in /etc/resolv.conf:

search subdomain.your-domain.domain your-domain.domain
# for example search remix.bogus bogus
nameserver 127.0.0.1

Where we will have to replace the subdomain.your-domain.domain with the appropriate values. The search line indicates which domains will be searched for any host that wants to connect (it is possible to replace search with domain, although they behave differently) and the name server specifies the address of the name server (in this case, your actual machine, which is where the naming process will execute). The search behaves as follows: if a client is searching for the machine called pirulo, first, the pirulo.subdomain.your-domain.domain will be searched, then pirulo.your-domain.domain and finally, pirulo. This means that the search will take some time; however, if pirulo will be in subdomain.your-domain.domain, it is not necessary to enter the rest.

The next step is to start up named and look at the results of the execution. To start up the daemon, we can directly use the /etc/init.d/bind9 start startup script (if the named is already executing, go to /etc/init.d/bind9 reload) or, if not, /usr/sbin/named. If we look at the system log in /var/log/daemon.log, we will see something similar to:

Sep 1 20:42:28 remolix named[165]: starting BIND 9.2.1 \\
Sep 1 20:42:28 remolix named[165]: using 1 CPU \\
Sep 1 20:42:28 remolix named[167]: loading configuration from '/etc/bind/named.conf'

The server's startup and the error messages will appear here (if there were any errors, in which case they must be corrected and the process started again). We can now verify the configuration with commands such as nslookup (original and easy but obsolete according to the programmers), host or dig (recommended). The output of dig -x 127.0.0.1 will be something like:

#dig -x 127.0.0.1
;; <<>> DiG 9.2.1 <<>> -x 127.0.0.1
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31245
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION: ;1.0.0.127.in-addr.arpa. IN PTR
;;ANSWER SECTION: 1.0.0.127.in-addr.arpa. 604800 IN PTR localhost.
;; AUTHORITY SECTION: 127.in-addr.arpa. 604800 IN NS ns.remix.bogus.
;; Query time: 1 msec
;; SERVER: 127.0.0.1 #53(127.0.0.1)
;; WHEN: Mon Sep 1 22:23:35 2003
;; MSG SIZE rcvd: 91

Where we can see that the query has taken 1 millisecond. If you have an Internet connection, you can search for a machine within your domain and see the server performance and behaviour. In BIND9 there is the lwresd (lightweight resolver daemon), which is the daemon that provides naming services to clients that use the BIND9 lightweight resolver library. It is essentially a cache server (like the one we have configured) that makes the queries using BIND9 lightweight resolver protocol instead of the DNS protocol. This server listens through interface 127.0.0.1 (which means it only attends to processes in the local host) in UPD and port 921. The client requests are decrypted and resolved using the DNS protocol. When responses are obtained, the lwresd encodes them in the lightweight format and returns them to the client that has requested them.

Finally, as we have mentioned, the kernel uses various sources of information, which, for the network, are obtained from /etc/nsswitch.conf. This file indicates from where we obtain the source of information and there is a section, for machine names and IPs, such as:

hosts: files dns

This line (if it is not there, it should be added) indicates that whoever needs a machine name or IP should first check /etc/hosts and then in DNS, in accordance with the domains indicated in /etc/resolv.conf.

7.2.2. Forwarders

In networks with a large workload, it is possible to balance the traffic using the section on forwarders. If your Internet Service Provider (ISP) has one or more stable name servers, it is advisable to use them to decongest the requests on the server. For this, we must delete the comment (//) from each line in the forwarders section of the /etc/bind/named.conf file and replace the 0.0.0.0 with the IPs of the name servers of our ISP. This configuration is advisable when the connection is slow, when using a modem, for example.

7.2.3. Configuration of an own domain

DNS possesses a tree structure and the origin is known as '.' (see /etc/bind/db.root). Beneath the '.' there are the TLDs (top level domains) such as org, com, edu, net etc. When searching in a server, if the server does not know the answer, the tree will be searched recursively until it is found. Each '.' in an address (for example, pirulo.remix.com) indicates a different branch of the DNS tree and a different scope for requesting (or responsibility) that will be followed recursively from left to right.

Another important aspect, apart from the domain, is in-addr.arpa (inverse mapping), which is also nested as the domains and serves to obtain names when requesting by IP address. In this case, the addresses are written the other way round, in accordance with the domain. If pirulo.remix.com is 192.168.0.1, it will be written as 1.0.168.192, in accordance with pirulo.remix.com.

We must then configure the actual remix.bogus domain in file /etc/bind/db.127 [LN01]:

; BIND reverse data file for local loopback interface 
$TTL 604800 
@ IN SOA ns.remix.bogus. root.remix.bogus. (
      1                  ; Serial 
      604800             ; Refresh 
      86400              ; Retry 
      2419200            ; Expire
      604800 )           ; Negative Cache TTL
@     IN      NS        ns.remix.bogus.
1.0.0 IN      PTR       localhost.

The '.' must be taken into account at the end of the domain names. The origin of a zone's hierarchy is specified by the identification of the zone, which in our case, is 127.in-addr.arpa. This file (db.127) contains 3 registries: SOA, NS, PTR. The SOA (start of authority) must be in all of the zone files, at the beginning, after TTL and the @ signifies the origin of the domain; NS, the name server for the domain and PTR (domain name pointer), which is host 1 in the subnet (127.0.0.1) and is called local host. This is the series 1 file and root@remix.bogus (last space in the SOA line) is in charge of it. We could now restart the named as shown above and, using dig -x 127.0.0.1, we could see how it works (identically to that shown previously).

We would then have to add a new zone in named.conf:

zone "remix.bogus" {
    type master;
     notify no;
     file "/etc/bind/remix.bogus";
     };

We must remember that in named.conf, the domains appear without the '.' at the end. In the file remix.boguswe will put the hosts of which we will be in charge:

; Zone file for remix.bogus 
$TTL       604800 
@          IN       SOA      ns.remix.bogus. 	root.remix.bogus. (
           199802151         ; serial, todays date + todays serial 
           604800            ; Refresh
           86400             ; Retry
           2419200           ; Expire 
           604800 )          ; Negative Cache TTL
@          NS       ns       ; Inet Address of name server 
           MX       10       mail.remix.bogus.  ; Primary Mail Exchanger
localhost           A        127.0.0.1
ns                  A        192.168.1.2
mail                A        192.168.1.4 
                    TXT "Mail Server"
ftp                 A        192.168.1.5 
                    MX       10 mail
www                 CNAME    ftp

A new MX registry, the Mail exchanger, appears here. This is the place to which the emails that arrive will be sent, someone@remix.bogus, and they will be sent to mail.remix.bogus (the number indicates the priority if we have more than one MX). Always remember the '.' that is necessary in the zone files at the end of the domain (if these are not entered, the system will add the SOA domain at the end, which would transform mail.remix.bogus, for example, into mail.remix.bogus.remix.bogus, which would be incorrect). CNAME (canonical name) is used to give a machine one alias or various aliases. As of this moment, we would be able (after the /etc/init.d/bind9 reload) to test, for example, dig www.remix.bogus .

The last step is to configure the inverse zone, in other words, so that IP addresses can be changed into names, for example, adding a new zone:

zone "192.168.1.in-addr.arpa" {
     type master;
     notify no;
     file "/etc/bind/192.168.1";
     };

And the file /etc/bind/192.168.1 similar to the preceding one:

$TTL 604800 
@    IN    SOA       ns.remix.bogus. root.remix.bogus. ( 
     199802151       ; serial, todays date + todays serial 
     604800          ; Refresh
     86400           ; Retry
     2419200         ; Expire 
     604800 )        ; Negative Cache TTL
@    NS              ns.remix.bogus.
2    PTR             ns.remix.bogus
4    PTR             mail.remix.bogus
5    PTR             ftp.remix.bogus

This can be tested again with dig -x 192.168.1.4. We must remember that these examples are on private IPs, in other words, not on Internet IPs. Another important point is that we must not forget the notify no, as otherwise, our experiments with the DNS will spread to the servers through the DNS tree (possibly even modifying the DNS of our provider or institution). These should only be modified when we are sure that it works and we are certain about the changes we want to make. To look at a real example, please see DNS-HOWTO at http://tldp.org/HOWTO/DNS-HOWTO-7.html.

Once we have created a master server, we must create a slave server for security, which is identical to the master, except in that the zone in the place of the type master must have a slave and the IP of the master. For example:

zone "remix.bogus" {
     type slave;
     notify no;
     masters {192.168.1.2; }
     };