DNS in Linux for System Administrator | Part 2

In today’s article we will show you how to install, configure and administer BIND 9 as a private DNS server.If you are interested in understanding the basic working of a DNS query and how a server responds to that query, or in other words, if you want to understand how a computer uses a DNS server to resolve domain names to IP addresses, then i will recommend reading previous blog.

Based on working method types of DNS are there, few are mentioned below

  1. Primary / Master DNS
  2. Slave DNS
  3. Forwarding DNS
  4. Caching DNS
  5. Authoritative-Only DNS

Some of the differences between DNS servers are purely functional. Most servers that are involved with implementing DNS are specialized for certain functions. The type of DNS server you choose will largely depend on your needs and what type of problem you are hoping to solve.


Caching DNS Server:

A caching DNS server is a server that handles recursive requests from clients. Almost every DNS server that the operating system’s stub resolver will contact will be a caching DNS server.

Caching servers have the advantage of answering recursive requests from clients. While authoritative-only servers may be ideal for serving specific zone information, caching DNS servers are more broadly useful from a client’s perspective. They make the DNS system of the world accessible to rather dumb client interfaces.

To avoid having to take the performance hit of issuing multiple iterative request to other DNS servers every time it receives a recursive request, the server caches its results. This allows it to have access to a broad base of DNS information (the entire world’s publicly accessible DNS) while handling recent requests very quickly.

A caching DNS server has the following properties:

  • Access to the entire range of public DNS data. All zone data served by publicly accessible DNS servers hooked into the global delegation tree can be reached by a caching DNS server. It knows about the root DNS servers and can intelligently follow referrals as it receives data.
  • Ability to spoon-feed data to dumb clients. Almost every modern operating system offloads DNS resolution to dedicated recursive servers through the use of stub resolvers. These resolving libraries simply issue a recursive request and expect to be handed back a complete answer. A caching DNS server has the exact capabilities to serve these clients. By accepting a recursive query, these servers promise to either return with an answer or a DNS error message.
  • Maintains a cache of recently requested data. By caching the results as it collects them from other DNS servers for its client requests, a caching DNS server builds a cache for recent DNS data. Depending on how many clients use the server, how large the cache is, and how long the TTL data is on the DNS records themselves, this can drastically speed up DNS resolution in most cases.

The first configuration will be for a caching DNS server. This type of server is also known as a resolver because it handles recursive queries and generally can handle the grunt work of tracking down DNS data from other servers.

When a caching DNS server tracks down the answer to a client’s query, it returns the answer to the client. But it also stores the answer in its cache for the period of time allowed by the records’ TTL value. The cache can then be used as a source for subsequent requests in order to speed up the total round-trip time.

Almost all DNS servers that you might have in your network configuration will be caching DNS servers. These make up for the lack of adequate DNS resolver libraries implemented on most client machines. A caching DNS server is a good choice for many situations. If you do not wish to rely on your ISPs DNS or other publicly available DNS servers, making your own caching server is a good choice. If it is in close physical proximity to the client machines, it is also very likely to improve the DNS query times.

INSTALLATION:

The Bind software is available within Ubuntu’s default repositories, so we just need to update our local package index and install the software using apt. We will also include the documentation and some common utilities:

sudo apt-get update
sudo apt-get install bind9 bind9utils
cd /etc/bind

We are not going to be concerned with the majority of the files in this directory. The main configuration file is called named.conf (named and bind are two names for the same application). This file simply sources the named.conf.options file, the named.conf.local file, and the named.conf.default-zones file.

For a caching DNS server, we will only be modifying the named.conf.options file. Open this in your text editor with sudo privileges:

sudo vim named.conf.options

We explicitly turned recursion on, and then configured the allow-query parameter to use our ACL specification. We could have used a different parameter, like allow-recursion to reference our ACL group. If present and recursion is on, allow-recursion will dictate the list of clients that can use recursive services.However, if allow-recursion is not set, then Bind falls back on the allow-query-cache list, then the allow-query list, and finally a default of localnets and localhost only. Since we are configuring a caching only server (it has no authoritative zones of its own and doesn’t forward requests), the allow-query list will always apply only to recursion. We are using it because it is the most general way of specifying the ACL.

caching server configuration:

acl goodclients {
        192.168.43.0/24;
        localhost;
        localnets;
};

options {
        directory "/var/cache/bind";

        recursion yes;
        allow-query { goodclients; };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

Before we take the plunge and restart the Bind server on our system, we should use Bind’s included tools to check the syntax of our configuration files.

We can do this easily by typing:

sudo named-checkconf

If there are no syntax errors in your configuration, the shell prompt will return immediately without displaying any output.

When you have verified that your configuration files do not have any syntax errors, restart the Bind daemon to implement your changes:

sudo service bind9 restart

Configure the Client Machine
Open the file with sudo privileges in your text editor:

sudo vim /etc/resolv.conf

he file will list the DNS servers to use to resolve queries by setting the nameserver directives. Comment out all of the current entries and add a nameserver line that points to your DNS server:

nameserver <your dns server IP>
# nameserver 8.8.4.4
# nameserver 8.8.8.8
ping ubuntu.com
dig ubuntu.com

Forwarding DNS:

This will be done within the options {} block. First, we create a block inside called forwarders that contains the IP addresses of the recursive name servers that we want to forward requests to. In our guide, we will use Google’s public DNS servers (8.8.8.8 and 8.8.4.4):

Forwarding DNS configuration:

acl goodclients {
       192.168.43.0/24;
        localhost;
        localnets;
};

options {
        directory "/var/cache/bind";

        recursion yes;
        allow-query { goodclients; };

        forwarders {
                8.8.8.8;
                8.8.4.4;
        };
        forward only;

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

Before we take the plunge and restart the Bind server on our system, we should use Bind’s included tools to check the syntax of our configuration files.

We can do this easily by typing:

sudo named-checkconf

If there are no syntax errors in your configuration, the shell prompt will return immediately without displaying any output.

If you have syntax errors in your configuration files, you will be alerted to the error and line number where it occurs. If this happens, go back and check your files for errors.

When you have verified that your configuration files do not have any syntax errors, restart the Bind daemon to implement your changes:

sudo service bind9 restart

Configure the Client Machine
Open the file with sudo privileges in your text editor:

sudo vim /etc/resolv.conf

he file will list the DNS servers to use to resolve queries by setting the nameserver directives. Comment out all of the current entries and add a nameserver line that points to your DNS server:

nameserver <your dns server IP>
# nameserver 8.8.4.4
# nameserver 8.8.8.8
ping ubuntu.com
dig ubuntu.com

Difference in query time:

;; Query time: 2715 msec - ubuntu.com -- cache DNS server
 ;; Query time: 1244 msec - ubuntu.com -- forward DNS server

Primary / Master DNS:
Two servers (ns1 and ns2) connected to a private network.

Install BIND on both servers:

# sudo apt-get install bind9 bind9utils

Set BIND to IPv4 mode
Set BIND to IPv4 mode, we will do that by editing the “/etc/default/bind9” file and adding “-4” to the OPTIONS variable:

# sudo nano /etc/default/bind9

The edited file should look something like this:

# run resolvconf?
RESOLVCONF=no

# startup options for the server
OPTIONS="-4 -u bind"

Now let’s configure ns1, our primary DNS server.

Configuring the Primary DNS Server:
Edit the named.conf.options file:

# sudo vim /etc/bind/named.conf.options

On top of the options block, add a new block called trusted.This list will allow the clients specified in it to send recursive DNS queries to our primary server:

rupin@ubuntu:~$ cat /etc/bind/named.conf.options
acl "trusted" {
 192.168.43.172;
 192.168.43.159;
 192.168.43.114; 
 192.168.43.113; 
};
options {
 directory "/var/cache/bind";

// If there is a firewall between you and nameservers you want
 // to talk to, you may need to fix the firewall to allow multiple
 // ports to talk. See http://www.kb.cert.org/vuls/id/800113

// If your ISP provided one or more IP addresses for stable 
 // nameservers, you probably want to use them as forwarders. 
 // Uncomment the following block, and insert the addresses replacing 
 // the all-0's placeholder.
recursion yes; # enables resursive queries
 allow-recursion { trusted; }; # allows recursive queries from "trusted" clients
 listen-on { 192.168.43.172; }; # ns1 private IP address - listen on private network only
 allow-transfer { none; }; # disable zone transfers by default

forwarders {
 8.8.8.8;
 8.8.4.4;
 };
 //========================================================================
 // If BIND logs error messages about the root key being expired,
 // you will need to update your keys. See https://www.isc.org/bind-keys
 //========================================================================

};
rupin@ubuntu:~$

If the “listen-on-v6” directive is present in the named.conf.options file, delete it as we want BIND to listen only on IPv4.

sudo vim /etc/bind/named.conf.local
rupin@ubuntu:~$ cat /etc/bind/named.conf.local
//
// Do any local configuration here
 //Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "test.example.com" { 
 type master;
 file "/etc/bind/zones/db.test.example.com"; # zone file path
 allow-transfer { 192.168.43.159; }; # ns2 private IP address – secondary
};

zone "43.168.192.in-addr.arpa" { 
 type master;
 file "/etc/bind/zones/db.192.168.43"; # 192.168.43.0/24 subnet
 allow-transfer { 192.168.43.159; }; # ns2 private IP address – secondary
};
rupin@ubuntu:~$

Creating the Forward Zone File:

Now we’ll create the directory where we will store our zone files in:

# sudo mkdir /etc/bind/zones

We will use the sample db.local file to make our forward zone file, let’s copy the file first:

# cd /etc/bind/zones
# sudo cp ../db.local ./db.test.example.com

Now edit the forward zone file we just copied:

# sudo vim /etc/bind/zones/db.test.example.com

 

rupin@ubuntu:~$ cat /etc/bind/zones/db.test.example.com
;
; BIND data file for local loopback interface
;
$TTL 604800
@ IN SOA ns1.test.example.com. admin.test.example.com. (
 3 ; Serial
 604800 ; Refresh
 86400 ; Retry
 2419200 ; Expire
 604800 ) ; Negative Cache TTL
;
; name servers - NS records
 IN NS ns1.test.example.com.
 IN NS ns2.test.example.com.

; name servers - A records
ns1.test.example.com. IN A 192.168.43.172
ns2.test.example.com. IN A 192.168.43.159

; 192.168.43.0/24 - A records
host1.test.example.com. IN A 192.168.43.114
host2.test.example.com. IN A 192.168.43.113
rupin@ubuntu:~$

Creating the Reverse Zone File:
We specify the PTR records for reverse DNS lookups in the reverse zone files. When the DNS server receives a PTR lookup query for an example for IP: “192.168.43.114”, it will check the reverse zone file to retrieve the FQDN of the IP address, in our case that would be “host1.test.example.com”.
We will create a reverse zone file for every single reverse zone specified in the named.conf.local file we created on ns1. We will use the sample db.127 zone file to create our reverse zone file:

# cd /etc/bind/zones
# sudo cp ../db.127 ./db.192.168.43

Edit the reverse zone file so it matches the reverse zone defined in named.conf.local:

sudo vim /etc/bind/zones/db.192.168.43
rupin@ubuntu:~$ cat /etc/bind/zones/db.192.168.43
;
; BIND reverse data file for local loopback interface
;
$TTL 604800
@ IN SOA test.example.com. admin.test.example.com. (
 3 ; Serial
 604800 ; Refresh
 86400 ; Retry
 2419200 ; Expire
 604800 ) ; Negative Cache TTL
;
; name servers - NS records
 IN NS ns1.test.example.com.
 IN NS ns2.test.example.com.
;
; PTR Records
172 IN PTR ns1.test.example.com. ; 192.168.43.172 
159 IN PTR ns2.test.example.com. ; 192.168.43.159
114 IN PTR host1.test.exaample.com. ; 192.168.43.114
113 IN PTR host2.test.example.com. ; 192.168.43.113
rupin@ubuntu:~$

Check the Configuration Files:

Use the following command to check the configuration syntax of all the named.conf files that we configured:

# sudo named-checkconf

If your configuration files don’t have any syntax problems, the output will not contain any error messages. However if you do have problems with your configuration files, compare the settings in the “Configuring the Primary DNS Server” section with the files you have errors in and make the correct adjustment, then you can try executing the named-checkconf command again.

The named-checkzone can be used to check the proper configuration of your zone files.You can use the following command to check the forward zone “test.example.com”:

# sudo named-checkzone test.example.com db.test.example.com

And if you want to check the reverse zone configuration, execute the following command:

# sudo named-checkzone 43.168.192.in-addr.arpa /etc/bind/zones/db.192.168.43

Once you have properly configured all the configuration and zone files, restart the BIND service:

# sudo service bind9 restart

Configuring the Secondary DNS Server:
Setting up a secondary DNS server is always a good idea as it will serve as a failover and will respond to queries if the primary server is unresponsive.

# sudo nano /etc/bind/named.conf.options
rupin@ubuntu:~$ cat /etc/bind/named.conf.options
acl "trusted" { 
 192.168.43.172;
 192.168.43.159;
 192.168.43.114;
 192.168.43.113;
};
options { 
 directory "/var/cache/bind";

recursion yes; # enables resursive queries
 allow-recursion { trusted; }; # allows recursive queries from "trusted" clients
 listen-on { 192.168.43.172; }; # ns2 private IP address - listen on private network only
 allow-transfer { none; }; # disable zone transfers by default

forwarders {
 8.8.8.8;
 8.8.4.4;
 };
};
rupin@ubuntu:~$

Now open the named.conf.local file for editing:

# sudo nano /etc/bind/named.conf.local
rupin@ubuntu:~$ cat /etc/bind/named.conf.local
// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";
zone "test.example.com" { 
 type slave;
 file "slaves/db.test.example.com";
 masters { 192.168.43.172; }; # ns1 private IP
};
zone "43.168.192.in-addr.arpa" { 
 type slave;
 file "slaves/db.192.168.43";
 masters { 192.168.43.172; }; # ns1 private IP
};
rupin@ubuntu:~$
# sudo named-checkconf

Then restart the BIND service:

# sudo service bind9 restart

Configure the DNS Clients:
Generally on the Ubuntu, Debian and CentOS distributions just edit the /etc/resolv.conf file, execute the following command as root:

# nano /etc/resolv.conf

Then replace the existing nameservers with:

nameserver 192.168.43.172 #ns1
nameserver 192.168.43.159 #ns2

Now save and exit the file and your client should be configured to use the ns1 and ns2 nameservers.

Then test if your clients can send queries to the DNS servers you just configured:

# nslookup host1.test.example.com

You can also test the reverse lookup by querying the DNS server with the IP address of the host:

rupin@L687:~$ nslookup host1.test.example.com
Server: 192.168.43.172
Address: 192.168.43.172#53

Name: host1.test.example.com
Address: 192.168.43.114

rupin@L687:~$
# nslookup 192.168.43.172
rupin@L687:~$ nslookup 192.168.43.172
Server: 192.168.43.172
Address: 192.168.43.172#53
172.43.168.192.in-addr.arpa name = ns1.test.example.com.
rupin@L687:~$

Adding a New Host to Your DNS Servers:

If you need to add a host to your DNS servers just follow the steps below:

On the ns1 nameserver do the following:

  • Create an A record in the forward zone file for the host and increment the value of the Serial variable.
  • Create a PTR record in the reverse zone file for the host and increment the value of the Serial variable.
  • Add your host’s private IP address to the trusted ACL in named.conf.options.
  • Reload BIND using the following command: sudo service bind9 reload

On the ns2 nameserver do the following:

  • Add your host’s private IP address to the trusted ACL in named.conf.options.
  • Reload BIND using the following command: sudo service bind9 reload

On the host machine do the following:

  • Edit /etc/resolv.conf and change the nameservers to your DNS servers.
  • Use nslookup to test if the host queries your DNS servers.

Athoritative-Only DNS Servers:

An authoritative-only DNS server is a server that only concerns itself with answering the queries for the zones that it is responsible for. Since it does not help resolve queries for outside zones, it is generally very fast and can handle many requests efficiently.

Authoritative-only servers have the following properties:

  • Very fast at responding to queries for zones it controls. An authoritative-only server will have all of the information about the domain it is responsible for, or referral information for zones within the domain that have been delegated out to other name servers.
  • Will not respond to recursive queries. The very definition of an authoritative-only server is one that does not handle recursive requests. This makes it a server only and never a client in the DNS system. Any request reaching an authoritative-only server will generally be coming from a resolver that has received a referral to it, meaning that the authoritative-only server will either have the full answer, or will be able to pass a new referral to the name server that it has delegated responsibility to.
  • Does not cache query results. Since an authoritative-only server never queries other servers for information to resolve a request, it never has the opportunity to cache results. All of the information it knows is already in its system.

Server configuration:-   https://do.co/2H4ps2J


DNS server and client side Troubleshooting:-

Testing:

The first step in testing BIND9 is to add the nameserver’s IP Address to a hosts resolver.The Primary nameserver should be configured as well as another host to double check things.check that the file /etc/resolv.conf contains (for this example):

nameserver	192.168.1.10
nameserver	192.168.1.11

Nameservers that listen at 127.* are responsible for adding their own IP addresses to resolv.conf (using resolvconf). This is done via the file /etc/default/bind9 by changing the line RESOLVCONF=no to RESOLVCONF=yes.
NOTE:- You should also add the IP Address of the Secondary nameserver in case the Primary becomes unavailable.

dig:

If you installed the dnsutils package you can test your setup using the DNS lookup utility dig:

  • After installing BIND9 use dig against the loopback interface to make sure it is listening on port 53. From a terminal prompt:

    dig -x 127.0.0.1
    

    You should see lines similar to the following in the command output:

    ;; Query time: 1 msec
    ;; SERVER: 192.168.1.10#53(192.168.1.10)
    
  • If you have configured BIND9 as a Caching nameserver “dig” an outside domain to check the query time:

    dig ubuntu.com
    

    Note the query time toward the end of the command output:

    ;; Query time: 49 msec
    

    After a second dig there should be improvement:

    ;; Query time: 1 msec
    

ping

Now to demonstrate how applications make use of DNS to resolve a host name use the ping utility to send an ICMP echo request. From a terminal prompt enter:

ping example.com

This tests if the nameserver can resolve the name ns.example.com to an IP Address. The command output should resemble:

PING ns.example.com (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.800 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.813 ms

named-checkzone

A great way to test your zone files is by using the named-checkzone utility installed with the bind9 package. This utility allows you to make sure the configuration is correct before restarting BIND9 and making the changes live.

  • To test our example Forward zone file enter the following from a command prompt:

    named-checkzone example.com /etc/bind/db.example.com
    

    If everything is configured correctly you should see output similar to:

    zone example.com/IN: loaded serial 6
    OK
    
  • Similarly, to test the Reverse zone file enter the following:

    named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192
    

    The output should be similar to:

    zone 1.168.192.in-addr.arpa/IN: loaded serial 3
    OK
    

The Serial Number of your zone file will probably be different.


Logging

BIND9 has a wide variety of logging configuration options available. There are two main options. The channel option configures where logs go, and the category option determines what information to log.

If no logging option is configured the default option is:

logging {
     category default { default_syslog; default_debug; };
     category unmatched { null; };
};

This section covers configuring BIND9 to send debug messages related to DNS queries to a separate file.

  • First, we need to configure a channel to specify which file to send the messages to. Edit /etc/bind/named.conf.local and add the following:

    logging {
        channel query.log {      
            file "/var/log/query.log";
            severity debug 3; 
        }; 
    };
    
  • Next, configure a category to send all DNS queries to the query file:

    logging {
        channel query.log {      
            file "/var/log/query.log"; 
            severity debug 3; 
        }; 
        category queries { query.log; }; 
    };
    

Note: the debug option can be set from 1 to 3. If a level isn’t specified level 1 is the default.

  • Since the named daemon runs as the bind user the /var/log/query.log file must be created and the ownership changed:

    sudo touch /var/log/query.log
    sudo chown bind /var/log/query.log
    
  • Before named daemon can write to the new log file the AppArmor profile must be updated. First, edit /etc/apparmor.d/usr.sbin.named and add:

    /var/log/query.log w,
    

    Next, reload the profile:

    cat /etc/apparmor.d/usr.sbin.named | sudo apparmor_parser -r
    
  • Now restart BIND9 for the changes to take effect:

    sudo systemctl restart bind9.service
    


END



 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s