Configuring a Master DNS Server

Configuring a Master DNS Server

If you've chosen to run your own DNS servers on your local network and you use Linux, you will probably want to set up BIND (Berkeley Internet Name Domain) to manage your DNS records. This configuration is quite detail oriented, and the smallest error can cause the entire service to grind to a halt. Pay attention while you're working, and make sure that you enable whatever security tools will safeguard your site most effectively.

Installing BIND on a Linux or UNIX machine can be a bit confusing, especially on Red Hat-based systems. While the general service is called the Domain Name Service, the actual RPM package is called bind:

  #  rpm -q bind

Even more confusing, the daemon is called neither bind nor DNS, but named! This can be very annoying, especially if you are an administrator who does not have regular responsibilities for DNS services but needs to troubleshoot an immediate crisis while your DNS guru is on vacation. Your immediate response might be

  #  service bind restart
  bind: unrecognized service

Obviously, this won't work. Instead, you need to issue this command:

  #  service named restart
  Stopping named:                             [ OK ]
  Starting named:                             [ OK ]

Just another one of those UNIX idiosyncrasies that enhances job security.


In this section, we assume that you have a domain name registered to you. If you don't have a domain name yet, see the Registering Domain Names sidebar earlier in this chapter.

BIND9 Directory Structure

Before you begin to configure BIND9 on your DNS server, take a moment to study the directory structure. BIND9 files live in the /bin directory:


If you are running BIND in chroot mode, all the files must be under /var/named/chroot/.If you are running in nonchrooted mode, all the files must be under /var/named.

The /bin/etc/named.conf file contains the configurations for the named daemon. If you choose to run BIND in chroot mode (the default, and most secure choice), as described later in the BIND9 Security section of this chapter, you will store zone files in the /var/named/ chroot subdirectory.


Read the BIND9 Bug sidebar later in this chapter to learn more about a serious security risk that may affect your installation. If you choose to run in chroot mode, you will need to copy some files into /var/named/chroot/ before you start the service.


The /etc/named.conf file handles all configurations for the name daemon, or named. In order for DNS service to work properly, you will need to make a number of changes to this file. If DNS isn't working for some reason, chances are that it's an error in /etc/named. conf that is causing the problem.


The named daemon is pronounced "name-dee," not "named" (as in "My geeky sister named her dog Denethor"). This is one of those Secret Passwords of UNIX Competence, like knowing how to pronounce Linus Torvalds.

In this section, we show you a complete /etc/named.conf file, interspersed with comments and explanations. If you have a running installation of BIND9 already, look at your own /etc/named. conf to see what configurations have already been made.


If you do not have an /etc/named.conf file and you're on a Red Hat-based system, then you must also install the caching-nameserver RPM package. This will create /etc/named. conf. Also be aware that if your BIND DNS server is running in chrooted mode, you may find the file under /var/named/chroot/etc/named.conf, which is installed by the related Red Hat package bind-chroot. On a Red Hat system, issue the command rpm -qa|grep -e ^bind -e nameserv to see the bind-related packages you have installed. On a non-Red Hat system that has been running for at least 24 hours, you can issue the command locate named. conf as root to help you find your named config file.

  // generated by

  options (
          directory "/var/named";

The directory setting determines the directory where all zone flies should be stored. If you store zone files in any other directory, DNS will break.

     * If there is a firewall between you and nameservers you
     * want to talk to, you might need to uncomment the query-
     * source directive below. Previous versions of BIND
     * always asked questions using port 53, but BIND 8.1 uses
     * an unprivileged port by default.
         // query-source address * port 53;

This block doesn't look like normal UNIX commenting. In /etc/named.conf, you will find three different comment methods:

  • C style: /* comment inside here */

  • C++ style: // to the end of line

  • Unix style: # to the end of line

You can probably determine what is commentary and what is not, but it's good to be aware of the various notations.

   // a caching only nameserver config
   controls {
           inet allow { localhost; } keys { rndckey;

The controls setting tells named how to run rndc, the BIND9 name server control utility.

The next sections contain the zone file definitions. Any line that says

   file ""

indicates that the zone file for this zone, or domain, is located at /var/named/somedomain . com. zone. Be sure that whatever you have in /etc/named. conf points to the actual file that you create. The name itself is irrelevant; it's the location and filename accuracy that matters.

   zone "." IN {
           type hint;
           file "";

The first line of the preceding section indicates that the section will define the root zone. The third line identifies the file that contains the root of the zone.

 zone "localhost" IN {             #<--Good to use as a template
         type master;                  #<-- The master zone
         file "";        #<--The name of zone file located
         allow-update {none; }; #          In /var/named/

This section is an excellent template for actual zone settings later in the file. The first line names the zone, the second line indicates that this is a master DNS server for that zone, and the third line specifies the location of the zone file in /var/named. To add your own zones, copy the preceding block in your named.conf file, paste it further down, and fill it in with your own zone file information.

  zone "" IN {
          type master;
          file "";
          allow - update { none; }


Whenever copying blocks like this, be sure to include the all-important closing }; characters.

As you can see here, the administrator has simply replaced the template information with actual zone information. Doing this through copy-and-paste is the safest way to be sure that your zone entries are formatted properly.

The next two blocks of information define how BIND handles reverse lookups for your domain:

  zone "0.0.12/.in" IN {
        type master;
        file "named.local";
        allow-update { none; }

The first configuration file block controls reverse lookups for your loopback device's IP.


Reverse lookups function like a phone book in reverse, to find a name associated with an IP address. The following entry, and its related zone file, is one that will allow anyone to nslookup the IP address 10.1.1.x. This zone will associate the IP back to a reverse (or PTR) name record.

  zone "" IN {
          type master;
          file "";
          allow-update { none; };


Just as you copied down the 0.0.127 block as a template within the named.conf file, you can also copy the actual zone file it references named.local (usually in /var/named/) to use for a new reverse zone file called for the 10.1.1.x IP block.

If you actually own the IP block that you use (unlikely, since most of us rent IP addresses from upstream providers), you would use the aforementioned configuration file block. Those who own an IP block control the reverse lookup authority for that entire block.

  include "/etc/rndc.key";

This final line contains a pointer to the Remote Name Daemon Controller configuration file, which sets up local and remote secure control for the BIND9 server. Unless you are prepared to research this key-based secure service thoroughly, it is recommended to not make any changes to this reference or the file it references.


Good information on implementing RNDC/TSIG can be found at

Now that you've seen an /etc/named.conf file in action, you can begin to edit your own. When adding your own zone blocks and file references, we strongly recommend typing the filename for new zones into named.conf, then copying it to the clipboard, and saving the filename from your paste. One of the most common errors is a typo in a zone filename, either in the named.conf file or in the /var/named/ filename itself. For example, if you use the vi text editor, you might issue the command

   # vi /var/named/paste-file-name-here

or just copy the named.local file as a template:

   # cp /var/named/namd.local /var/named/paste-file-name-here


More DNS-related problems are caused by typing errors than anything else. The entries in /etc/named. conf and the zone filename must be identical or named will fail.

After you have finished adding zone references to /etc/named.conf, it's time to create the actual zone files. Remember that you must store these files in the location you defined in /etc/named.conf. For example, in the /etc/named.conf file, we set up a zone reference for, which has its zone files stored at /var/named/

The Localhost Zone File

Before you begin creating zone files for actual domains, take a look at the localhost zone file. This defines information for your local machine, which uses the reserved IP address


There are two typographical conventions found in zone files. If a line has a space in its left-most column then that line's configuration adopts the domain name from the previous line. The @ symbol is used as a placeholder for the full domain or zone name defined in the /etc/named.conf file.

  # cat /var/named/
  $TTL    86400

This line defines the default zone TTL, or the length of time for which zone information is authoritative. TTLs are written in seconds, so the value 86400 equals 1 day. Caching name servers use this value to ignore or refresh their cached information about a given domain name.

  $ORIGIN localhost.

This line defines the domain name. The domain name must always end with a trailing dot. Later in, this line would read $ORIGIN (note the trailing dot).

  @     ID IN SOA     @ root (             \
          42            ; serial (d. adams)
          3H            ; refresh
          15M           ; retry
          1W            ; expiry
          1D )          ; minimum

This section creates the Start of Authority Record, or SOA. The SOA configures zone behavior and determines how the zone information may be pulled down by other name servers.

The serial number (42) found in the first indented line is used as a date stamp. It is written in the format YYYYMMDD##, where the ## is an actual number. Increment this number by one every time you make a change to the zone file (starting at 00 or 01). If you make a change to the zone file and do not increment this number, then caching name servers as well as your slave servers will ignore all following data and assume that their stored data is correct. For example, if today is January 16, 2008, and you are making the first change of the day, the serial number should be 20080011701. (Those of you who are Douglas Adams fans will be amused by the default placeholder for the serial number. It's set to 42 instead of the proper YYYYMMDD## date code.)


You can learn more about Start of Authority records and their construction at

                     1D IN NS             @
                     1D IN A    

Finally, these lines define the internet-type (IN) name server (NS) record for the domain this zone file represents. Written in an expanded format, these lines could also be

   localhost.       1D IN NS     localhost.
      ^^^           ^^ ^^ ^^       ^^^
   the domain       TTL         NameServer

The name server for the domain localhost. (represented by the unseen space at the front of the line) is the server FQDN, localhost.; that is, you can find the IP address assigned to this name server at the name server called localhost..

NS records declare the machines that provide DNS service for the zone in question. Even after the registrars have pointed requests to your DNS server, this is still required.

Because this zone file is authoritative for the loca1host domain (in this case, because localhost is always locally authoritative), you will also see the A record defined:

                           1D IN A

which could be rewritten as

   @                 1D IN A


   localhost.        1D IN A


An A record always points a name to an IP address. An NS record always points to whoever should be doing DNS for this domain (which in the case of localhost. will always be you).

Name Service Tools

If your DNS client is set to query your own machine before it queries the DNS server for the network, then your own name server will respond with this information:

   # nslookup localhost

   Name:   localhost


The nslookup command has been deprecated, and may be removed from future Red Hat releases. Consider using the dig or host programs instead. If you like using nslookup, run it with the silent option to prevent this message from appearing, as in nslookup-sil.

Note that in the preceding example ns1ookup did not actually query the name server running on the local machine. The Server and Address fields show that the resolver client went out and queried another DNS server running on IP In order to query your own DNS server directly, you must supply the correct IP address. Issue the command like this:

   # nslookup -sil localhost

   Name:   localhost
   Address: 127.0.0.]

This is much better. Now you're querying against your own machine (assuming that you are, and the output is correct. Compare the output from nslookup to the information you receive from the newer tools host and dig:

   # host  localhost
   Using domain  server:
   Address: # 53
   Aliases:localhost has address

The usage and output from host is generally the same as that from nslookup. With the dig command, however, you'll see quite different information. dig takes slightly different syntax to query a name server other than the default, with @nameserverIP rather than the plain IP address:

# dig localhost @

;<<>> DIG 9.2.2-P3 <<>> localhost @
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27676
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0

;localhost.                     IN      A

localhost.             86400    IN      A

localhost.             86400    IN      NS    localhost.

;; Query time: 2 msec
;; WHEN: Sat Jan 17 22:44:18 2004
;; MSG SIZE rcvd: 57

This is quite a bit more information than that from the other tools. The dig output contains data about the query itself and the various answers, as well as statistics about the queried domain, including its TTL and authoritative name server. With the information from the AUTHORITY section, you can use dig to "walk down the DNS tree" for a given domain.

For example, use dig to step down through the DNS tree for In the first query, use dig to find the gTLD name server(s) for the .com TLD:

   # dig com
   ; com.                          IN      A

   com.                    10737   IN      SOA     a.gtld- 2004011701 1800 900
   604800 86400

Next, query the gTLD server that you found in the first output for information about the domain:

   # dig
   ;                     IN         A

   ;; AUTHORITY SECTION:         172800 IN      NS         172800 IN      NS         172800 IN      NS         172800 IN      NS         172800 IN      NS

   ;; ADDITIONAL SECTION:     172800 IN      A     172800 IN      A     172800 IN      A     172800 IN      A     172800 IN      A

Here you see a request to the world gTLD name servers serving the .com TLD for the IP address of It gave back authoritative name servers and their IPs. In this output, you can see that there are a number of authoritative name servers for this domain.

Now you can ask one of those servers to answer your question about the domain directly:

# dig @

;<<>> DiG 9.2.2-P3 <<>> @
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5356
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 5

;                     IN      A

;; ANSWER SECTION:             1800     IN      A

;; AUTHORITY SECTION:             172800   IN      NS             172800   IN      NS

There you have it: the authoritative IP address for the domain as defined by its own DNS server's zone file.

This is the work that your ISP or network provider's DNS server does when it performs recursive requests for their clients. Name servers that recurse, or search, for domains on behalf of their client's requests are usually also set up as caching name servers. Caching servers retain the information they gather for a set period of time, defined by the remote domain's TTL setting in its own zone file. In this way, by running your own DNS server, not only do you control the IP addresses that people get resolved to but also (with the TTL) how long they can hold onto this information. This helps to speed up DNS and keep DNS chatter on the Internet to a minimum.


Learn more about recursive DNS requests at

Creating Your Own Zone Files

Now that you have your DNS server running and doing recursive lookups, be sure that /etc/named.conf points to the correct zone file for your domain. Once the pointer is in place, you can create the authoritative zone file. In this section, we set up a file for the fictitious domain

As we warned earlier, don't type in the name of this file manually when you save it for the first time. Cut and paste from your /etc/named.conf to save yourself from later work due to fumbling fingers. In fact, save yourself a lot of typing by using a template taken from the file. Issue this command:

#    cp -p /var/named/ /var/named/

Be sure to paste the copied zone filename at the end of the line, where we have italicized our zone filename.

Open this new file in your favorite text editor. If your text editor has search and replace capabilities, use it to replace every occurrence of localhost. with (If you don't have search and replace in your editor, you'll have to do this by eye.) Be sure to include those trailing dots. Check the default settings and see if you need to change them at this time:

   $TTL     86400

Is this TTL an appropriate length? 86400 seconds is 1 day. If you want caching name servers to hold your information longer, thus reducing load on your local machine, consider lengthening this setting:


Be sure that your domain name ends in a trailing dot.

   @                 1D IN S0A
   (                    2004011700         ;

Remember to change the name server for this domain ( and the e-mail address (without the @ here is Also, change the serial number to the date format YYYYMMDD##. Increment the serial number by one each time you make any changes to this file from now on.

                                3H             ; refresh
                                15M            ; retry
                                1W             ; expiry
                                1D )           ; minimum

   @                      1D IN NS
   @                      1D IN NS
   ns                      1D IN A                   1D IN A


The only reason that this sample zone file must have A records for its NS records is that the DNS servers for this domain exist inside the domain. That is, the DNS server exists inside the domain, which is being defined by this file. If the name servers were outside this domain (for example, in ns . mydns . com), you would not use A records in this zone file since this zone file is not authoritative for the domain

Since our name servers are also in this domain, we need to include A records that point to a specified IP address for the servers. There is an entry for the master name server and one for each slave server.


In the aforementioned example, the record for ns could also be written as or just as ns<space>, which expands out to the FQDN. Either of these work, but sometimes using just the last part of the hostname (ns in this case) is clearer and easier to read.

   www          1D IN CNAME @        ;
   ftp          1D IN CNAME @        ;
   mail         1D IN CNAME @        ;
   webdav       1D IN CNAME @        ;
   @            lD IN A ;

While A records point domain names to IP addresses (last line), CNAME records are aliases that point names to other names. These names must resolve to an A record (ultimately to a defined IP address).


The e-mail address for this domain is [email protected], and it can be found in the third line, expressed as This form is used because the @ symbol is used in zone files to represent the entire domain name. The standard syntax for e-mail addresses in zone files is user.domain.gtld.

Note that this zone file defines two name servers. The IPs you would use to define these servers are usually the primary and secondary servers that you provided when you registered your domain name. In this case, we used ns and This is a bit more complex than the usual practice of most DNS administrators, who would use the equally functional method:

   @              1D IN NS     ns
   @              1D IN NS     ns2
   ns             1D IN A
   ns2            ID IN A

This usage requires less typing, and thus less room for human error. However, while you're learning to set up zone files, there is something to be said for writing everything out at least once to get a feel for doing it correctly.

The only other element of note is that all the Canonical Name, or CNAME, entries point to the same server, @. Remember that @ is shorthand for the domain. It is only in the final record where the name is pointed to the IP address with an Address Resource record, or A record.

Defining Reverse Lookups

If you have control over your own IP space, as you would on a corporate LAN, you will need to be able to service reverse lookups. As we explained earlier, reverse lookups are queries that seek a domain name to match a known IP address, whereas forward lookups seek an IP address to match a known domain name. If you do forward lookups for your own IP space, then you need to do reverse lookups as well.

To set up reverse lookup resolution, open the /etc/named.conf file in your text editor of choice:

   zone "" IN {
           type master;
           file "";
           allow-update  { none ; };
           allow-transfer {;;; };

The zone file needs to have a name that means "/var/named/ for the IP block of 10.1.1.*", more precisely expressed as This file is most easily created by copying the existing file /var/named/named.local to the new zone filename, and then editing it as necessary. For example, the file named in the previous example might look like this if we started adding additional machines:

   $TTL   86400
   @      IN      SOA root.1ocalhost. {
                           2004011600 ; Serial
                           28800      ; Refresh
                           14400      ; Retry
                           3600000    ;   Expire
                           86400 )    ;   Minimum

          IN      NS
          IN      NS

   1      IN      PTR
   2      IN      PIR
   3      IN      PTR
   4      IN      PTR
   5      IN      PTR
   6      IN      PTR
   7      IN      PTR
   254    IN      PTR

The last block of records are PTR, or reverse, records. They simply point known IP addresses back to the associated domain name. Typically, only the owner of that IP network block is granted the authority to "do reverse" on a public IP address. In this situation, however, these are not public IP addresses. Rather, they are nonroutable from the 10.* class-A block. The only stipulation is that you must at least control the DNS servers on your network so that internal users look at the local DNS server for this block.


Remember that the default DNS server setting for every PC on your network is typically pushed out to the client PCs by your own network's DHCP server. If you issue your own IP addresses on your network, you control what DNS server(s) they go to. Instructions for pointing your DHCP clients to your DNS servers are beyond the scope of this chapter.

To test your configuration, use the host command to resolve an IP ( in this example) against your own name server:

   # host
   Using domain server:
   Aliases: domain name pointer


   #  host
   Using domain server:
   Aliases: domain name pointer

Set-Up Tips

As long as you remember a few basic pieces of information, configuring your local DNS server and zone files will be no problem:

  • The main configuration file /etc/named.conf (or if chrooted, /var/named/chroot/etc/named.conf) defines how the server runs and determines which zone files are loaded into memory.

  • The domains, or zone files, are stored in the /var/named/ directory. If you are running BIND9 in chroot mode, they are stored in /var/named/chroot/var/named/.

  • Know the difference between A records, NS records, and CNAMEs.

  • Terminate fully qualified domain names, or FQDNs, with a trailing dot. If not, your will become!

  • If you make a change to the zone file, increment the serial number by one. If you exit without changing the serial number, the changes will not take effect on all external name servers.

  • Whenever you make a zone addition or change, be sure to reload or restart the named daemon with the command /etc/init.d/named restart or service named reload.

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