Postfix Virtual



            Many administrators usually do not care much about DNS system. Once DNS doesn't
  work, you understand its meaning. Even if your IP structure works, it makes no sense. 
So we have to care DNS more than we do (deal?). Let's begin with a brief introduction
telling what DNS looks like ?

            In daily Internet usage, we use letters to write e-mail and web page addresses.
Internet is managed by routers (devices or software on a computer) and these devices control
the flow of information by examining the fields of IP packets, which designate where the packet
comes from and goes to .

If you don't know how a packet resembles, here is the well known IP Packet Header :)










   You see that there are two fields "Source IP Address" and "Destination IP Address"
in the IP packet. These source and destination fields can only have 32 bit addresses in IPv4.
In another word, these fields cannot be composed of letters. This means
that we should find a way of converting these human readable words and letters
(web page addresses, email domains) to the the form where routers can understand
to route the packet to its intended destination.
       Have you ever asked where these IP addresses come from and let the routing
       In this stage, DNS acts the leading role which makes this conversion possible. When you
write a web page address such as into your browser, here what happens;
(As a side note: We assume that you write this URL in a browser in Linux, since it
seems that Windows doesn't respect TTL(Time To Live) values and cache responses from
DNS server for a constant periof of 24 Hours. For a more detailed explanation visit this page )
if you want to learn someting how a browser in linux cache data visit this page

How does name resolution work ?
Assume we have written in our browser

1) The application first checks some special database. For example, if you use a web browser,
your browser first check its internal memory cache before asking the query to DNS server.
if there is an answer, no need to ask further.
2) Application checks /etc/resolv.conf file for nameserver entries to perform the query.
3) Lets say that application got nameserver addresss as
4) name server first checks its cache whether there is an entry with the 
     related query or not. If it has the answer, no further query
5) Then name server checks to determine that this domain is local or not. Meaning
     that, this ns server is responsible for that domain or not.
6) If not, ns server takes Top Level Domain (TLD) part .tr and queries a root server
     for this .tr domain to learn which server is responsible for it and got the answer with IP address of
7) Then the process is going on like a chain. name server then askes for
     domain for that, who is responsible for This goes on until reaching the final
     name server which has the authoritive answer for
8) After receiving final record answer name server caches this data for further

            Now we are going to install BIND ( Berkeley Internet Name Daemon) and create our
domains for our Postfix virtual system to work. Since running this daemon as root can be dangerous,
we will put this daemon into a jail environment.( In this environment, daemon is restricted to live
in a predefined directory location like a prisoner in jail:)

#cd /usr/local/src
#wget -c
#tar zxf bind-9.3.2.tar.gz
#cd bind-9.3.2
#./configure --prefix=/usr/local/bind
#make install
#mkdir -p /usr/local/bind/{etc,namedb,dev,var/run}
(The above command creates all necessary directories in one step - You can use curly brackets for this purpose)

For SElinux systems, I have seen that  installation differs. You must be so careful about SElinux systems.
When above stages are finished, BIND is installed into /usr/local/bind base directory.
Now create configuration files(depicted as red paths) of BIND below


options {
        directory "/namedb";
        version "I do not give any version info";
         pid-file "/var/run/";
         allow-transfer { none ;};

zone "." IN {
        type hint;
        file " /etc/named.root";

Create this /usr/local/bind/etc/named.conf file which is the main configuration file for BIND
We will write all instructions into this file.  Options block is for general settings and zone blocks are for setting values for our domains. Specified file PATHs in named.conf file are relative to /usr/local/bind directory. e.g directory "/namedb"   line actually refers to /usr/local/bind/namedb directory, not /namedb directory . Another example, /var/run/ file is actually the file /usr/local/bind/var/run/ I hope it is clear now.Don't forget that bind is in a jail environment.
So you should think every path relative.
        In the named.conf file in zone "." section, there is a file called " named.root " . This is the file which contains all IP addresses of root servers . Rarely, root server IP addresses change.
You can obtain the latest named.root file from address. Lets download named.root file to /usr/local/bind/etc directory

#cd /usr/local/bind/etc

We have completed main configuration file a little bit, now create jail directories and
system account for bind.

#groupadd named
#useradd named -d /usr/local/bind -s /bin/false -g named -c "DNS Jail User"
#mknod /usr/local/bind/dev/null c 1 3
#mknod /usr/local/bind/dev/random c 1 8
#cp /etc/localtime /usr/local/bind/etc/

Since we have installed this system into a jail environment, we will have some problems while logging
dns records. Linux perform this logging by sending records to /dev/log socket but this location is out of our
jail :(  Let's make some tricks.. and change syslog behaviour. Below is an explanation about how you
can change syslogd configuration. Be careful that, lines that have to be changed are not in syslog
daemon configuration file . You must make modification in startup configuration of syslog daemon
program and this startup location differs as distribution differs as defined below;

Startup file for syslog daemon in Redhat is at location " /etc/rc.d/init.d/syslog ".
(If it didn't change after my last use of Redhat). Change your line into this;

daemon syslogd -m 0 -a /usr/local/bind/dev/log

Add  "-a /usr/local/bind/dev/log" in /usr/bin/syslogd line in /etc/rc.d/rc.inet2  file

Sysklogd startup file is " /etc/init.d/sysklogd ". Edit file and change line SYSLOGD=""
to SYSLOGD="-a /usr/local/bind/dev/log" . Thanks to William Golden for debian setup
and correction about var directory permission.

NOTE: "- a" switch in syslogd startup lines doesn't mean that syslogd will do logging
to /usr/local/bind/dev/log, it defines an additional socket that syslogd has to listen

Make directories more secure

#chown named:named /usr/local/bind
#chown -R named:named /usr/local/bind/var
#chmod 700 /usr/local/bind

Start DNS Server
#/usr/local/bind/sbin/named -u named -t /usr/local/bind -c /etc/named.conf

Check that daemon is started or not
#ps aux | grep -v grep | grep named

If you see the output which says that daemon is is great you did it.

If you reach this point without any problem, let's do your first query in your DNS server.
#host has address

You will probably have a similar output like above. Your dns server is working and
answer your queries. Now we are going to create a sample domain with you.

   Let's say that you have bought a domain name called from a registery such as , etc. and you want to accept e-mails for this domain in your mail server.
Do you want to learn ? keep reading then :)

      You must create an entry in named.conf file for each of your domain. For this,
Add  the lines below  to the bottom of /usr/local/bind/etc/named.conf file. This way you tell
that you have a domain called which has the domain configuration file

      This file will be located under /usr/local/bind/namedb/ . Remember!!! there is a
directory section in named.conf file. It defines where zone files are located.


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

Now after defining the named of the configuration file it is time to create the content of zone file
for domain


$TTL 14400

@               IN SOA (
                        2005030601      ; serial
                        7200           ; Refresh
                        7200            ; Retry
                        604800          ; Expire
                        86400 )         ; Minimum                            IN      NS                            IN      A                    IN      A                   IN      A                             IN     MX 5              IN     A  IN     A

This is our zone file. Zone files need TTL (time to live) values. These values define
how long other DNS servers should cache your name information without asking your
DNS server again. If this TTL value is 86400 secs  , once a name server  asks  IP address
of, it will not ask your server for the next 86400 secs (1 day :) in SOA line is the name server responsible for this domain name and is the
administrator e-mail address for this domain. Be careful it is an e-mail address (
but you must put "." instead of @ character.
       Another thing, you have to increment serial number by one in each change of this file.
Important line for our mail server is ;                IN      MX 5

  This line says that mails sent for domain must be sent to
machine which has the IP address of  . Number 5 is the priority value and it is only
meaningful when there are two mail servers co-exist. Now....increment your serial number for the
first time and reload your bind DNS server. Let's do it..

#kill -1 `pidof named`

Informational Note: For those who are new to Linux,  I would like to explain  the command issued above. Backtick
sign ( ` ) in linux allows you to run a command. This allows you to take output of a command and use that
output as an input of an another command. In the example above, pidof command is the command which gives
the process ID of named program. Output of `pidof named` command becomes an input for kill -1 command.
By this way, you don't have to write " ps ax " and learn process ID of the program and use kill command.
This saves your time.

    We have sent a HUP signal to named daemon and dns server reloaded its configuration file.
Now it knows what the mail exchanger (responsible mail server) is for domain .
Let's ask it to new dns server whether it knows or not.

#host -t mx mail is handled by 5

We have asked for the mail exhanger of and DNS server said that is
responsible for domain. Now we have a fully functional DNS server which can
answer for our new domain.We can go to the next step to accept mail in our mail server.

(If you don't need a secondary DNS server please skip this step too)

        If one of your aims is to become a good DNS Administrator, you should read RFC1034
and 1035 after reading this tutorial. How DNS works is explained in detail in those documents.
As for our document, RFC says that if you have an authoritive DNS server for a domain, you must
locate your DNS servers in physically different networks. If one of your servers is in one ISP,
you should put your secondary server in another ISP, if you have no tolerance for network failures.
This is just for high availability purposes. If you have a small site, probably, you will not need any one
of these.
       Secondary DNS server is a server transferring domain information from the master one at a
predefined time interval. In fact, there is no difference between a master and slave server from the point
of resolver (e.g you)  . When you try to access a site called and if there are two servers serving
that domain, one of the DNS servers will give dns reply to you resolver. If one server is down for any reason,
the other one continues to answer queries. You must understand that none of these servers are redundant.
They both answer queries for the zones that they are responsible for.
       In my document, both slave server and secondary server have the same meaning. Additionally,
master server and primary servers have also the same meaning so don't confuse when I interchange words.
       After giving a brief introduction about DNS system, let's configure our secondary server.

  In your second linux server, install bind, like the one above BUT do not create any zone file. Since secondary
will transfer zone files from the master.
      Only difference will be in named.conf configuration file. For our setup, ( is
your master DNS server and ( is your slave DNS server.

Now, create the named.conf file below in your second linux server.

options {
        directory "/namedb";
        version "I do not give any version info";
         pid-file "/var/run/";
         allow-transfer { none ;};

zone "." IN {
        type hint;
        file "named.root";
zone "" {
        type slave ;
         masters {; };
        file "";
        allow-query {any;};
        allow-update { none; };  

Have you noticed the change in named.conf file?  This time, instead of writing " master " to the
type line, we have written " slave " since this domain is slave and retrieve its record sets from the
master server.
        Ok ... we have set up our secondary server and it is ready for transferring zone information but
Is master server ready for accepting zone transfer requests coming from this secondary server ?
No.. we should tell the master server to accept AXFR (transfer type) requests originated
  from IP address. Now open named.conf file in the primary server and change ;

allow-transfer { none ;};

to >>>

allow-transfer { ;};

This line permits transfer requests from secondary name server. When you make any
little change to domain in the primary server, change will be reflected to the secondary server
  as a notify. So you will not have to make the same change on the secondary server.
    When you add another domain to the primary server, you have to add configuration lines for
your new domain to the named.conf file of secondary server as mentioned above. Reload servers and
you will see that secondary server copies zone files from the master and write those new zone files
under /namedb directory. It is amazing , isn't it ? :)


I would want to do more on security of these primary and secondary server setups but I know that
when I add more functionality, things are getting more complex and the probability of making mistakes
increases:) I don't want this document to be a error-rich document. I just would like to tell some parts that
you should consider below;

1) RFCs suggest that you should not provide caching services on the server that provides
    authoritive data for zones. Your cache-only server and authoritive server serving your zones
    should not be on the same server. For example, you should not use these authoritive servers
    in your /etc/resolv.conf files for cache purposes. This is not recommended from the security
    point of view. You can read requirements for root servers RFC.

2) We have installed our DNS servers to serve both authoritive data and cache information. I have just
     done this to demonstrate how this system works. To disable caching service of these servers
     you can remove;
zone "." IN {
                         type hint;
                        file "named.root";

     these lines. When you remove these lines, DNS server will not be aware of root servers' IP addresses
     and can not answer for NS queries for zones that it is not currenly authoritive for. It is a nice trick right :)

3) You should also disable recursive queries on your DNS server. You don't have to make all queries
       recursively. Your servers don't have to do all the stuff for queries. This will also save bandwidth, if you
       have lack of it. Add this line to named.conf in between options block.  

allow-recursion { none; } ;

        This way, you will not provide recursive service to any resolver and every resolver will only
         receive NS IP addresses of the next responsible  DNS server for that zone and not the answer of
         the query.

4)    If you are a ultra secure person :) , you can also disable any query except your zone files from any client.
      This way, your server will  say "CONNECTION REFUSED" to the resolvers which want to query other
       domains that you are not responsible for. If you had paid attention there is a line
allow-query {any;};
      in every zone block that I have added. This says that, server allows any query for this domain. When you add
allow-query { none; };
      line to options block of named.conf file , DNS server will not allow any query other than your domains and
      refuse connections.

I know that these options have close relations when doing their task. When you mainly use DNS, you can discover
how they are needed.

           One of my aims was to write a good "Secure DNS" document. I hope I did small percent of what I wanted...
I think this DNS information is a little more for a postfix document but I believe that when DNS is not configured
properly, there is no way of a MTA to work.

About Me |Contact Me | ©2006 Genco (Please refer my page if you use any document in this site) (update 03.06.2006)