Installing and configuring a DNS server

Domain Name System (DNS) makes navigating networked resources much easier. Unless you have a very small network, it's unlikely that you'll remember which IP addresses belong to which machines. DNS helps by mapping names to IP addresses, so you can refer to computers by their hostname and DNS will do the work of translating that back to the IP address.

DNS is one of those things that virtually everyone with a network connected device uses all the time, regardless of whether or not the user realizes it. Computers, servers, smart phones, tablets, smart appliances, and more all utilize DNS. Whenever you look up a service on the Internet, such as a website or a remote resource, DNS translates the name of the resource to the IP address.

Though the idea of DNS and what it does for us may be common knowledge, it's one of those things that are easy to take for granted. DNS is one of those mythical things that works in the background and makes our lives much easier. Most of us use it, but very few of us actually understand how it works. Whenever you connect to an Internet Service Provider (ISP), you're typically assigned a DNS server or two that you will use for your connection. The cleverer users out there will often bypass the ISP assigned DNS servers, to third-party servers such as those used by Google or OpenDNS in an attempt to squeeze additional performance.

DNS can also prove useful within your internal network as well. Most companies with more than a handful of workstations will set up DNS, and rightfully so. It makes navigating your network a cinch. For example, it's easier to refer to your local color printer as hp-color-01 than it would be to remember an IP address, such as 10.19.89.40. In this case, adding the printer would be easy. Just have your operating system browse to it by name. Any resource on your network can be named and creating a consistent and predictable naming scheme for all your networked resources is a great idea. So, let's do exactly that.

As is typical, the naming of the required packages is a bit different on Debian-based distributions than CentOS. In Debian, the package you'll want to install is bind9. CentOS simply calls their bind. If you were wondering, BIND stands for Berkeley Internet Name Domain (named after where it was developed, namely the University of California at Berkeley). This is the most popular name server on the Internet, so you'll definitely want to familiarize yourself with it. While you're at it, I recommend installing bind-utils if you are running through this activity on a CentOS system. This gives us the dig command, which will be useful for our purposes.

The first step is to install the required package on your server, and then all you'll need to do is start it and ensure that it's enabled to run at startup. Debian already takes care of starting the daemon and enabling it for us. You can confirm this with the following command:

# systemctl status bind9

CentOS doesn't configure the bind daemon to autostart, and it does not start it up for you. If CentOS is your distribution of choice, you'll want to execute the following command to enable bind and start it up:

# systemctl enable named
# systemctl start named

With this done, you actually have a working DNS server. Of course, we didn't configure anything, so our DNS server is not actually doing much for us. But now that we have it installed, we can add records to it and build our configuration.

First, let's take a look at the default configuration file. Debian stores the default configuration file for bind at /etc/bind/named.conf. CentOS stores theirs at /etc/named.conf (it doesn't have its own directory). Go ahead and take a gander at this file to get a feel for how the configuration works. We're going to use our own configuration file, so I recommend you to back up the default files and we'll install our own.

First, let's create a fresh named.conf file in our distribution's default directory (/etc/bind/named.conf in Debian and /etc/named.conf in CentOS). Regardless of which distribution you're using, we'll make the file the same. If this file already has text in it, copy it to a backup or empty it, as the following two lines are the only text we need in this file:

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";

Here, we're going to include two additional files (which we will create, very soon). As you can see, our named.conf file is simply calling these files and contains no other configuration. This way, we can create our own standard place to find these files. /etc/bind is already the default location in Debian, but by calling out this directory in CentOS, we can force it to look for the configuration in the same place. But with CentOS, you'll need to create the /etc/bind directory. The command is as follows:

# mkdir /etc/bind

Next, let's create our /etc/bind/named.conf.options file and customize it:

options {
    forwarders {
        8.8.8.8; 8.8.4.4;
    };
};

Here, we're creating an options block with some code sandwiched in between curly braces, which then includes an additional set of curly braces where we identify our forwarding addresses. Since this DNS server is for locating resources within our internal network, the forwarders block tells our DNS server where to send requests, should it be unable to find what it's looking for locally. Your DNS server will likely still function perfectly fine without this, as in most cases it will still attempt another DNS server further down the chain. But setting the forwarders here allows us to force where we would like DNS lookups to go, in case we're looking for something externally. In this sample, I'm using Google's public DNS servers. However, you can choose your own. Some additional DNS servers (which are typically better) can be found at www.opennicproject.org, which is also a good choice if you're concerned about privacy or tracking.

Our next file is /etc/bind/named.conf.local, which contains the following code:

zone "local.lan" IN {
    type master; file "/etc/bind/net.local.lan";
};

zone "96.10.10.in-appr.arpa" {
    type master; notify no; file "/etc/bind/revp.10.10.96";
};

zone "97.10.10.in-appr.arpa" {
    type master; notify no; file "/etc/bind/revp.10.10.97";
};

zone "98.10.10.in-appr.arpa" {
    type master; notify no; file "/etc/bind/revp.10.10.98";
};

zone "99.10.10.in-appr.arpa" {
    type master; notify no; file "/etc/bind/revp.10.10.99";
};

In this file, we start of by identifying our domain name. Here, I chose local.lan. As this server is not authoritative of anything on the Internet, this name works well. Within this block, we're calling out another file, /etc/bind/net.local.lan. In fact, as you can see, there are several files being called out here (five in total). The first is our main DNS zone, and it's the most important of these. Those that follow are where we configure reverse DNS lookups. Essentially, DNS allows us to not only map hostnames to IP addresses, but we can also do the reverse (look map IP addresses back to hostnames). You may not need all the files that I created in my example. With mine, I am creating a reverse lookup file for each of my four subnets. If you aren't creating multiple subnets, you'll only need to create one. The naming convention of these is revp, followed by the network portion of the IP address. So, for example, the reverse lookup file for my 10.10.99.0 network is revp.10.10.99. These files will also be stored in /etc/bind as well.

Now, let's take a look at our master record, the /etc/bind/net.local.lan file:

;
; dns zone for for local.lan
;

$TTL 1D

@ IN SOA local.lan. hostmaster.local.lan. (

201507261 ; serial

8H ; refresh
4H ; retry
4W ; expire
1D ) ; minimum
IN A 10.10.96.1
;
@ IN NS hermes.local.lan.
ceres           IN      A   10.10.98.1
euphoria        IN      A   10.10.97.4
galaxy          IN      A   10.10.96.4
hermes          IN      A   10.10.96.1
puppet      CNAME galaxy
;
; dns zone for for local.lan
;

First, I placed some generic comments, with lines beginning with a semicolon. If a line begins with a semicolon, it is ignored by bind. Comments can be a good method of leaving notes or facts regarding the configuration. However, comments aren't used very often in bind. Next, we set our Time To Live (TTL) to one day:

$TTL 1D

This value governs how long other DNS servers would be able to cache each record. After this period, any servers that have cached one of these records must discard them. For the purposes of setting up an internal DNS server, this value doesn't affect us a great deal. However, if you're setting up multiple DNS servers, this might be an important value to configure. One example of where the TTL value might prove useful is changing an address record to a different IP address. Suppose you're switching your e-mail host to another provider. In that case, you would change the address record accordingly. However, before you enact this change, you may lower your TTL to something much less, such as one hour, and do this before you make this change. Then, servers are forced to discard this zone and refresh it, causing it to see your change in e-mail providers much quicker. When you are done, you would change this back. With the following line, we are identifying a Start of Authority (SOA):

@ IN SOA local.lan. hostmaster.local.lan. (

In this case, we are identifying that this DNS server has the authority for the local.lan domain. We also clarify that hostmaster.local.lan is responsible for it. Although it may not look like it, hostmaster.local.lan is actually an e-mail address in the format that bind prefers. However, this is obviously a fake address, which doesn't matter for our internal DNS server. At the end of this line, we are opening a configuration block, in this case with an opening parenthesis. The following line represents our serial, and it's a very important concept to understand in order for our DNS server to work properly:

201507261 ; serial

Each time our bind daemon is restarted, it will reload this file. But when it does, the serial number is the first thing it will look at. If it is the same, it will likely not load in any changes. Thus, every time you change a zone file in bind, you must change this serial number as well. In this example, the current date is being used without hyphens or spaces. The last digit is just a revision number for that day, if the file is changed multiple times in one day. You can use whatever scheme you'd like. But using the date is a very popular approach. Regardless of the format you use, always ensure you increment the serial by 1 with every change you make. You'll save yourself frustration wondering why newly created records aren't taking affect.

8H ; refresh
4H ; retry
4W ; expire
1D ) ; minimum

These values dictate how often slave DNS servers will be told to check for updates. The first value will configure slaves to refresh zone records from the master (this server) every eight hours. In regards to retry, we're letting slaves know that should there be a problem connecting, check back in this amount of time. Finally, we're setting our minimum age of zone records to one day, and the maximum to four weeks. Configuring slave DNS servers is beyond the scope of this book, but having this configuration in place doesn't hurt anything in case you do decide to configure slave DNS servers later on.

@ IN NS hermes.local.lan.

Here, we're identifying this name server. In my case, I'm calling it hermes and its full domain name is hermes.local.lan.

galaxy        IN    A   10.10.96.4
hermes        IN    A   10.10.96.1

Finally, in this sample configuration, four address records are called out. This basically means that any time someone is looking for one of these hosts, the request is mapped to the listed domain name. These can be among multiple subnets or a single subnet. In my case, these hosts are on different subnets:

puppet      CNAME galaxy

The final line of this configuration contains a Canonical Name (CNAME) record. Basically, this allows us to refer to a server by another name. In this example, galaxy is also used for software known as puppet, so a CNAME record has been set up for it. This way, if someone were to try to access galaxy.local.lan or puppet.local.lan, their request would resolve to the same IP address (10.10.96.4). A CNAME records can be very useful if a single server provides more than one service to the network.

Earlier, I called out four reverse lookup records, /etc/bind/revp.10.10.96, /etc/bind/revp.10.10.97, /etc/bind/revp.10.10.98, and revp.10.10.99. Next, I'm going to demonstrate one of these files (in this case, for the 10.10.96.0 network):

$TTL 1D
@ IN SOA hermes.local.lan. hostmaster.local.lan. (
201507261 ; serial
28800 ; refresh (8 hours)
14400 ; retry (4 hours)
2419200 ; expire (4 weeks)
86400 ; minimum (1 day)
)
;
@ NS hermes.local.lan.
1    PTR    hermes.local.lan.
3    PTR    nagios.local.lan.
4    PTR    galaxy.local.lan.

With this configuration, you'll notice we have a start of authority record as with our master zone, and we also have a serial number. The same idea applies here. Whenever you update any record (including reverse lookup records), you should update the serial number of the file. The start of authority entry works the same as earlier, no surprises here. Where the file differs is how the hosts are called out. Rather than calling out an entire IP address, we only need to identify the last octet since the entire file is dedicated to reverse IP address lookups from the 10.10.96.0 network. For each of your subnets, you'll need to create a similar file. Again, in our sample configuration there are four subnets, but you don't need that many. It was only provided in this way in order to provide an example of how to handle separate subnets, should you need to do so.

With our configuration in place, feel free to restart the bind service on your DNS server and test it out. We can restart bind with the systemctl command, as before.

For Debian, use the following command:

# systemctl restart bind9

For CentOS, use the following command:

# systemctl restart named

One way we can test our DNS server is via the dig command. With Debian, you should already have this package installed. CentOS requires the installation of the bind-utils package. dig (domain information groper) is a utility that allows us to request information from a DNS server. To give it a shot, try it out with an internal hostname:

dig myhostname.local.lan

If your DNS server comes up under SERVER in the output, then your DNS server is functioning properly. If for some reason it doesn't, verify what you've typed, your serial number, and whether or not you have restarted bind since your last configuration change.

Feel free to practice setting up additional nodes and records within your DNS server. Setting up bind can be frustrating at first, but stick with it and you'll be a pro in no time. Using examples from this section, you should have a working skeleton you can use to set up a DNS server within your environment. Make sure that you change the hostnames and IP addresses contained within the configuration files to those that match your network. In addition, make sure you set up bind to match your subnets, or remove mentions of other subnets if you don't have any. To be safe, instead of copying the configuration directly from this book, it's usually better to type everything manually just in case.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset