Linux · December 26, 2006 7

How To: Setup a Local Domain Name Services (DNS) Server for your Intranet

This was another of my journeys into the deep dark dungeons of Linux. This time I managed to set-up a DNS server locally and got it resolving addresses over my intranet.

Experimentation Platform:

Intel P4 3.0Ghz (Intel MotherBoard)
2 x 80 GB HDD on RAID 1 (Disk Mirroring) – alloted entirely to Linux

Operating System:

Linux – Redhat Enterprise AS Server v3

Note: I was trying to setup the system so that later on when my server goes online, I don’t
have to modify much to make my nameservers work with the internet – so I used my registered domain “” and an internal IP: “” – as the server IP. In future when my server goes online, all I’ve to do is modify this IP to reflect the actual ISP alloted IP and all will be good. So throughout the tutorial you’ll find references to this domain and the IP. For your own case, just change to domain to whatever you feel like and choose a suitable IP to go with.

Setting up the DNS can get quite tricky – so you need to follow the tutorial closely and pay attention to all the points discussed here.

Also make sure the following services are up & running – because they’ll be the ones affected most due to the DNS setup.

  1. httpd
  2. ftpd
  3. MTU (Mail Transport Agent) like Postfix, Sendmail etc.

You can see a list of running services using…

shell> service --status-all | less

Right, lets get to business now. Once your system boots, either login as “root” or use any other login and use “sudo” to get root access.

Step 1 – Checking the NIC Card Functionality

Make sure your NIC (Network Interface Card) or Ethernet Card is up and running. You can check this with…

shell> ifconfig

This should display information about your primary NIC (called “eth0” and the local loopback interface called “lo“). The output should look similar to this…

eth0 Link encap:Ethernet HWaddr 00:0D:88:39:D2:69
inet addr: Bcast: Mask:
inet6 addr: fe80::20d:88ff:fe39:d269/64 Scope:Link
RX packets:24633 errors:0 dropped:0 overruns:0 frame:0
TX packets:32779 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2843295 (2.7 Mb) TX bytes:3524410 (3.3 Mb)
Interrupt:225 Base address:0xb800

Notice my MAC (Media Access Controller) address on the first line & my IP and Subnet Mask in the second line.

Step 2 – Configuring the “hosts” file

This file resides in the “/etc” directory and contains the localhost entry (a special entry that must be present) and any other entries that you care to enter. In fact this file alone can act like a simple DNS, if you compile a huge list of matching IP and domain names here as the system can resolve/lookup addresses easily from this. Each entry will take on this form:

"IP address" "Fully Qualified Domain Name (FDQN)" "alias"

The hosts file should look like… localhost.localdomain localhost getafix

This file should contain at least those two lines – the localhost is a necessity as well as your server IP and hostname.domainname. As for the spaces in between the fields make it a point to use ONE TAB STOP for each. getafix here is the name of my server or its hostname. You can set the hostname of your server using the hostname command.

Usage: hostname 

Alternatively, you can set your hostname by editing a file called “network” located in the /etc/sysconfig/ directory. The contents should look like…


Using the hostname command instead of editing the file manually essentially does the same.

Step 3 – Generating a rndc key-pair

Here’s what the linux man pages say about rndc

rndc controls the operation of a name server. It supersedes the ndc utility that was provided in old BIND releases. If rndc is invoked with no command line options or arguments, it prints a short summary of the supported commands and the available options and their arguments.

rndc communicates with the name server over a TCP connection, sending commands authenticated with digital signatures. In the current versions of rndc and named named the only supported authentication algorithm is HMAC-MD5, which uses a shared secret on each end of the connection. This provides TSIG-style authentication for the command request and the name server's response. All commands sent over the channel must be signed by a key_id known to the server.

As you can see, the rndc key’s are much required to control your nameserver. Here’s how to generate the rndc keys. There’s a file called rndc-confgen located in the /usr/sbin/ directory.

Simply run the file rndc-confgen

shell> rndc-confgen

… which will produce an output like …

# controls {
# inet port 953
# allow {; } keys { "rndckey"; };
# };

# Start of rndc.conf
key "rndckey" {
    algorithm hmac-md5;
    secret "RN5xaE0Yr7ar1v0sPugf2g==";

options {
    default-key "rndckey";
    default-port 953;
# End of rndc.conf

# Use with the following in named.conf, adjusting the allow list as needed:
# key "rndckey" {
# algorithm hmac-md5;
# secret "RN5xaE0Yr7ar1v0sPugf2g==";
# };
# controls {
# inet port 953
# allow {; } keys { "rndckey"; };
# };
# End of named.conf

Carefully notice the commented out block of code (the lines with the starting ‘#’) in the SECOND HALF of the block – from #Use with the following… till #End of named.conf. Save this output into another file. You are going to need it SOON. If you are using a terminal software like PuTTY to access your server your can simply drag your mouse over the desired area and highlight it. Then open a blank file in vi and right-click the mouse. That’ll paste your code in the file. Save and exit.

Step 4 – Editing /etc/named.conf

We’re going to step into some messy editing now. In your /etc/ folder there is a file named named.conf. Open the file in vi or whichever editor you are using …

shell> vi /etc/named.conf

The contents should look like …

options {
directory "/var/named";

// Uncommenting this might help if you have to go through a
// firewall and things are not working out. But you probably
// need to talk to your firewall admin.
// query-source port 53;

controls {
    inet allow { localhost; } keys { rndc_key; };

zone "." {
    type hint;
    file ""

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

Between the option { } section, AFTER the directory clause INSERT the following …

host-statistics no;
fake-iquery no;
version "Bind"; //This reports just Bind and not it's version to any would be hacker
recursion no;

Now DELETE the controls {} clause entirely, and in its place insert the rndc-confgen OUTPUT that you had saved earlier on.

Next scroll down below the section titled zone “.” {} till you reach the ending
brace “};” AFTER the zone “localhost” IN. Make sure you UNCOMMENT the lines starting at key “rndckey” { till the ending brace }; right before # End of rndc.conf. Put a blank line after it.

Then on a fresh line add in the following …

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

You should put in your own domain in place of “” (make sure you KEEP the quotes) and after the file clause. Make sure you keep the .zone part after it.

Below this insert another similar block but with a few modifications …

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

This is how you figure out what to include after the “zone” between the quotes. Say my IP here is:

  1. First, I’d write it backwards i.e.
  2. Then chop off the leading 5. leaving me with just 168.19.10
  3. To that I add, giving me a string – which is my reverse resolution zone.

As for the part beside the file clause, you can copy it from the zone above and just add the word reverse. (mind the “.”) in front of it. That should do.

Now the last bit of editing for this file.. Check if there are any more zones below this. There should be one like …

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

Do you notice any similarity here with the zone that you just created ? This is indeed the reverse lookup zone for your local loopback interface or localhost( If this zone is missing from the file, just COPY the above section and PASTE it – NO MODIFICATIONS NECESSARY.

Besides this, the last line in the file should be …

include "/etc/rndc.key";

If this line is missing, once again insert it blindly. Now save this file and quit the editor.

Step 5 – Creating the “forward” zone database

Recall the filenames that we specified for our forward and reverse zones in Step 4. We’re going to need them here. In this example, we’d specified …

file "";
file "";

These files must be created for the zones to read them and function properly. They don’t get generated by default.

We are going to create these files now. The default directory for the zone files (on a typical linux system) is /var/named/ or any directory that was specified as the DNS ROOT using the directory clause in the named.conf file. If you can’t recall, scroll back to the beginning of Step 4 and you’ll notice it right there …

options {
directory "/var/named";

Anyway, use your editor or use the touch (which creates blank files with specified time-date stamp) command to create two blank files in the directory /var/named


Now open the first file, Insert the following lines into the file, modifying wherever necessary and replacing my microsys domain & IPs with your own domain and IPs …

$TTL 604800
; Information about "forward" domain
@ IN SOA (
2004042601 ; serial
86400 ; refresh
7200 ; retry
1209600 ; expiry
604800 ) ; minimum

; Define name servers for this domain
; Define Mail Exchanger for this domain
IN MX 10

; Define name to address mapping for this domain
ns1 IN A
www IN A
ftp IN A
mail IN A

; Loopback domain
localhost IN A

One word about this file – notice the trailing dot (“.”) wherever I’ve specified a domain name – DO NOT MISS THE DOTS OUT AT ANY COST – OR THE WHOLE THING WILL COLLAPSE.

A little explanation here:

In the third line beside,, notice the This is in actuality the webmasters email address. Its really but in here the “@” is replaced with a “.“. The numerical values within the parenthesis can be modified as desired. They are mostly
time specifications converted to seconds.

The line …

; Define name servers for this domain

… sets up the nameserver for you. It means we are declaring as your nameserver. Don’t forget to replace my domain with yours after the ns1. and don’t forget the trailing “.” either. If you have more than one nameservers, insert similar lines below and instead of “ns1.” put “ns2.” and so on.



Next is your Mail Exchanger which is utilized by the Mail Transport Agents to forward mails to the correct domain.

; Define Mail Exchanger for this domain
IN MX 10

The number 10 means we setting a priority of 10 to the mail server. Since we only use one mail server the priority has no effect.

In the next line …


… means we are declaring a host with no hostname and by hence by default the domain will point to this IP.

Its useful when you configure your web server to load OR They both point to the same thing and will return the same web site. If you have an external ISP alloted IP you can replace this by it to hook your server up to the net. Otherwise, just use your internal IP like me.

The rest of the entries are the declared hosts (running various Network Services) along with their IPs. If you have more than one nameserver – it should get listed here along with its IP. Since they all share the same IP, each of those services will run from the same machine. If you have the mail server running on a different machine then you should substitute that machines IP address in place of

Now save this file and quit.

Step 6 – Creating the “reverse” zone database

It’s time to setup the reverse lookup zone for your IP. Open the blank file that you had created and insert the following lines …

; Information about "inverse" domain
@ IN SOA (
2004042601 ; serial (d. adams)
86400 ; refresh
7200 ; retry
1209600 ; expiry
604800 ) ; minimum

; Define name servers for this domain

; Define name to address mapping for this domain

Notice how the IP has been reversed and placed, as I taught you earlier. We had always truncated the last segment “.5” from the IP before adding it in as the reverse address – that’s what is mentioned in the last line – the beginning number. If you last IP segment is some other number, replace the 5 in the last line with that.

Now save the file and quit. We are almost done.

Step 7 – Creating the “reverse” zone database for localhost

You don’t really have to edit this file – it is created by BIND by default and placed is your DNSROOT, i.e. the directory containing the zone files, /var/named/ in this case. Look for a file called named.local. It should contain exactly the following lines …

$TTL 86400
@ IN SOA localhost. root.localhost. (
1997022700 ; Serial
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS localhost.

1 IN PTR localhost.

If the file is missing – just create one with the same name and insert the lines above. Save and quit.

Step 8 – Editing /etc/resolv.conf

Open your editor again and load the file called resolv.conf in your /etc/ directory. Insert the following lines …


Of course, replace the domain and IP with your own. Notice, only your first nameserver is being specified here and listed against its IP. The “search” clause tells the server to dig into the system if it can’t find the first nameserver and try to track the other ones. Also if you have more than one nameservers, you should list them serially here with multiple nameserver clauses, like …

nameserver xx.xx.xx.xx
nameserver yy.yy.yy.yy
nameserver zz.zz.zz.zz

… and so on. Save and quit.

Step 9 – Restarting “named” or the DNS Server

We are more or less done. All that remains now is to restart the name daemon to load the modified configuration info. Execute the following command …

shell> service named restart

Alternatively, you can use: /etc/rc.d/init.d/named restart

You should see something like …

Stopping named: [ OK ]
Starting named: [ OK ]

If you see this – we are ALL SET and ready to go. If you get an error message saying …

rndc: connect failed: connection refused

IGNORE that. It doesn’t really matter till you are hooked onto the outside world.

Step 10 – Final Step: Check your nameserver

Use the tools named nslookup and/or dig to check if your nameserver is resolving properly.

shell> dig


shell> nslookup

On my system, dig reports …

;; DiG 9.2.3
;; global options: printcmd
;; Got answer:
;; - HEADER - opcode: QUERY, status: SERVFAIL, id: 21513
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

; IN A

;; Query time: 1 msec
;; WHEN: Thu Feb 3 03:12:27 2005
;; MSG SIZE rcvd: 36

This means all is WELL 🙂 and we are DONE.

If you need clarifications on any part, please don’t hesitate to post a comment here and I’ll try to make suitable amends to the tutorial and reply to your query as well.

Have fun 🙂