2015-02 Bind 9.7.2 on CentOS 6.2
Introduction
These are the class notes and assignments to learn the basics of setting up DNS & BIND in a Linux environment.
All of the work in this exercise will be done on the CentOS 6.2 x86-64 virtual machine provided to the class. BIND is relatively common, so these instructions should work on other Linux machines with minor modifications.
We assume that all work is done on an isolated network like the one present in our classroom laboratory.
Good References:
- Cricket Liu & Paul Albitz, DNS and BIND, fifth edition, O’Reilly, 2006. (publisher site)
- Quick HOWTO : Ch18 : Configuring DNS
Basic System configuration
To start, perform the basic configuration steps listed for system setup in the notes for a CentOS 6.2 system. For reference in this example, our system is
- OS: CentOS 6.2 (x64)
- Hostname: acheron.cosc.tu
- IP Address: 10.0.2.100
- Netmask: 255.255.255.0
- Gateway: 10.0.2.254
- User: zathras
These settings are correct for the instructor subnet in the classroom. When you build your system, be sure to change these as appropriate.
Installing Software on CentOS 6.2
Linux systems use a variety of automated package management solutions to install, configure, and remove software. On CentOS systems, this tool is called yum
. By default, that system will go online to obtain the latest version of each package and its dependencies when called upon to install software. Since we are working in a closed laboratory (and don’t want to update the system), we’ll need to modify that behavior.
The locations yum
uses to select software are called repositories, and they are configured in the directory /etc/yum.repos.d
. The online repositories are configured in the file CentOS-Base.repo
, while local sources, including the install disc, are configured in CentOS-Media.repo
. To install from the install discs, we need to make two changes to that file; we need to set the enabled flag to 1, and we provide the proper path to the media in the baseurl directive. The final result should look like
# CentOS-Media.repo # # This repo is used to mount the default locations for a CDROM / DVD on # CentOS-6. You can use this repo and yum to install items directly off the # DVD ISO that we release. # # To use this repo, put in your DVD and use it with the other repos too: # yum --enablerepo=c6-media [command] # # or for ONLY the media repo, do this: # # yum --disablerepo=\* --enablerepo=c6-media [command] [c6-media] name=CentOS-$releasever - Media baseurl=file:///media/CentOS_6.2_Final gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
If you are using the base image provided in class, then you do not need to make any changes to this file, as I have already made them for you. (See, I can be nice!) The default CentOS 6.2 file has the media disabled, and leaves a couple of incorrect values for baseurl.
Before we can use yum
to install software though, we also need to make sure that the virtual machine’s optical drive points to the installation disc. From the menu of VMWare Workstation, select VM → Settings. From the Hardware tab, select CD/DVD, and be sure that the device is "connected" and that it points to an ISO Image file for CentOS; those image files are online on the lab server. You should end up with something like
With the install disc mounted, and the changes made to the yum
configuration, the installation is a simple one-line command to install BIND.
[root@acheron yum.repos.d]# yum --disablerepo=\* --enablerepo=c6-media install bind Loaded plugins: fastestmirror, refresh-packagekit, security Loading mirror speeds from cached hostfile Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package bind.x86_64 32:9.7.3-8.P3.el6 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================== Package Arch Version Repository Size ============================================================================== Installing: bind x86_64 32:9.7.3-8.P3.el6 c6-media 3.9 M Transaction Summary ============================================================================== Install 1 Package(s) Total download size: 3.9 M Installed size: 7.0 M Is this ok [y/N]: y Downloading Packages: Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : 32:bind-9.7.3-8.P3.el6.x86_64 1/1 Installed: bind.x86_64 32:9.7.3-8.P3.el6 Complete!
Notice that we used the command structure described in CentOS-Media.repo
which disabled the online repositories. If we did not do this, then on our closed network yum
would have to time out waiting for the network to fail to respond, something which we would like to avoid.
DNS server with BIND: The basics
Now that we have installed BIND, check that it was properly installed:
[root@acheron yum.repos.d]# named -v BIND 9.7.3-P3-RedHat-9.7.3-8.P3.el6
Namespaces
Namespaces can be considered as a directed graph of domains and hosts. You are familiar with the top level domains like .com and .org that live under the root domain ".". In our class, our laboratory is separated from the internet, so we will use ".tu" as our canonical top-level domain.
You have a great deal of flexibility in selecting and defining your namespace(s). In these notes, I will use "cosc.tu" as the primary top-level domain, and when I need a second example I will use "class.tu". Each team is free to select their own namespace(s) and structure. One option would be for each student on a team to select their own sub-namespace, like "alice.team1.tu", "bob.team1.tu" "chris.team1.tu" and so on; then they can name their hosts how they wish. You could instead develop a functional model, so if you are simulating the Acme corporation, you may want a subdomain "sales.acme.tu" but you may want your web presence to be simply "www.acme.tu".
The Forward Zone
The forward zone is used to map human readable names to numerical IP addresses.
With the namespace structure of our class set, let us start to configure the DNS server to return the appropriate IP addresses whenever it is queried- our forward zone.
Start by create the zone file /var/named/db.cosc.tu. We can name this file anything we want, and even put it in any location that we want, but this is a canoncial location for a zone file, and naming the zone file after the domain will make subsequent administration simpler. This file should be created by root; if any authenticated user can make changes to your DNS records, well, that might be amusing. Briefly.
It should be noted that installing BIND has also installed some pre-existing configuration files (in /var/named) and some samples (in /usr/share/doc/bind-9.7.3/sample); we shall not use any of these files.
We begin the file with the following directives
; $TTL 5m ; cosc.tu. IN SOA acheron.cosc.tu. zathras.cosc.tu. ( 1 ; Serial 5m ; Refresh after 5 minutes 3m ; Retry after 3 minutes 30m ; Expire after 30 minutes 5m ) ; Negative TTL of one week
This begins with a time-to-live directive. This will be supplied with any query response, and will let the requester know how long they may cache the results. On an Internet facing system, you probably want this larger- from a few hours up to a few days. In our lab environment, things are much more dynamic, with systems getting built and taken down all of the time, so it makes sense to use a much smaller value. This does result in more traffic to and from the server, but the sizes of our network are such that this should not be a concern.
Next is a record, called a start of authority record, or SOA. It must start in the left column with the namespace that is being configured; in this case it is "cosc.tu.". Notice the trailing dot- this is essential! Remember that the top level of the name space is just ".", so this is the way to tell BIND that this is the FQDN, rather than just an abbreviation.
The record continues with "IN" telling us that this is data for the Internet. All of the examples we will consider will be Internet data.
It continues with "SOA", telling us that this is a start of authority record. Only one SOA record can be in a file.
Next is the FQDN for the host that will act as the primary nameserver for the zone. In this case it is acheron.cosc.tu, and again we end the FQDN in the directive with a period to indicate that this is not an abbreviation.
After the name of the primary nameserver comes the email address of the person responsible for maintaining the zone. At first glance, it does not look like an email address, but the key here is that the first "@" in the email address is replaced by a ".". Thus, our example record states that the email address of the person responsible for the zone in zathras@cosc.tu.
The open parentheses lets us continue the directive on to subsequent lines. The remainder of the record is used primarily for the configuration of any slave nameservers that get their information from this one.
The serial number is just that- a serial number. You can set it to any integer value you want. When a slave nameserver checks the master for an update, if the serial number on the master is greater than the serial number on the slave, then the slave will update its local data. There is no requirement that serial numbers be assigned consecutively- as long as the new data has a higher serial number that the old data, you are fine. Remember to actually do the update though- many students run into trouble with their DNS changes not propagating to their slaves, and forgetting to update the serial number is often the cause.
Next up is the refresh value; this determines how often a slave nameserver will query the master to see if it has the current data. What happens if the slave is unable to reach the master? Then it will try again after the retry interval.
Next we tell the slave how long it can hold on to the data on the assumption that it cannot reach the master. Last is the negative TTL; this is how long a slave should cache answers from the master that say that a particular name does not exist.
Note that the values in this example are tuned for our classroom laboratory environment. Data will update quickly, but will also time out quickly. Keep that in mind as you are setting up your systems. These are probably not suitable for a system meant to function on the wider Internet. Suggestions for more reasonable values can be found many places; you may want to start with
- TTL- 3 hours
- Refresh- 3 hours
- Retry- 1 hour
- Expire- 1 week
- Negative cache- 1 hour
We conclude the zone configuration file with a number of additional records- name server records (NS), Address records (A), and alias records (CNAME).
; ; Name Servers ; cosc.tu. IN NS acheron.cosc.tu. ; ; Address Records ; localhost.cosc.tu. IN A 127.0.0.1 acheron.cosc.tu. IN A 10.0.2.100 damocles.cosc.tu. IN A 10.0.2.101 achilles.cosc.tu. IN A 10.0.2.3 agamemnon.cosc.tu. IN A 10.0.2.4 agrippa.cosc.tu. IN A 10.0.2.5 alexander.cosc.tu. IN A 10.0.2.6 anubis.cosc.tu. IN A 10.0.2.7 apollo.cosc.tu. IN A 10.0.2.8 cadmus.cosc.tu. IN A 10.0.2.9 cerberus.cosc.tu. IN A 10.0.2.10 charon.cosc.tu. IN A 10.0.2.11 churchill.cosc.tu. IN A 10.0.2.12 delphi.cosc.tu. IN A 10.0.2.13 excalibur.cosc.tu. IN A 10.0.2.14 furies.cosc.tu. IN A 10.0.2.15 heracles.cosc.tu. IN A 10.0.2.16 hermes.cosc.tu. IN A 10.0.2.17 hydra.cosc.tu. IN A 10.0.2.18 juno.cosc.tu. IN A 10.0.2.19 medusa.cosc.tu. IN A 10.0.2.20 nemesis.cosc.tu. IN A 10.0.2.21 nimrod.cosc.tu. IN A 10.0.2.22 olympic.cosc.tu. IN A 10.0.2.23 orion.cosc.tu. IN A 10.0.2.24 persephone.cosc.tu. IN A 10.0.2.25 pollux.cosc.tu. IN A 10.0.2.26 roanoke.cosc.tu. IN A 10.0.2.27 talos.cosc.tu. IN A 10.0.2.28 theseus.cosc.tu. IN A 10.0.2.29 vesta.cosc.tu. IN A 10.0.2.30 zeus.cosc.tu. IN A 10.0.2.31 gw.cosc.tu. IN A 10.0.2.254 ; ; Aliases ; dns.cosc.tu. IN CNAME acheron.cosc.tu.
The nameserver records indicate which name servers are authoritative for this zone. Usually you want at least two hosts (what if one fails!). For now, since we are still setting up our first server, we only have one.
Next, the file sets up the host name records, or address records (A) for each host. These match the hostname on the left with the IP address on the right.
Finally, the file ends with a list of aliases records (CNAME). These are used when you want a multiple names to refer to the same IP address. This configuration file gives a second name (dns.cosc.tu) to the name server (acheron.cosc.tu).
The Reverse Zone
Now we set up the address to name mappings, this is called a reverse zone. Though our server (almost) knows how to return the IP address given a hostname, it does not know how to reverse the process. In fact, a completely separate configuration file is used for the reverse zone. In this example, we will create a reverse zone for the entire 10.0.2.0/24 subnet.
Using the same naming convention, we now create the file /var/named/db.10.0.2
in the following form:
$TTL 5m ; 2.0.10.in-addr.arpa. IN SOA acheron.cosc.tu. zathras.cosc.tu. ( 1 ; Serial 5m ; Refresh after 5 minutes 3m ; Retry after 3 minutes 30m ; Expire after 30 minutes 5m ) ; Negative TTL of one week ; ; Name Servers ; 2.0.10.in-addr.arpa. IN NS acheron.cosc.tu. ; ; Address Records ; 100.2.0.10.in-addr.arpa. IN PTR acheron.cosc.tu. 101.2.0.10.in-addr.arpa. IN PTR damocles.cosc.tu. 3.2.0.10.in-addr.arpa. IN PTR achilles.cosc.tu. 4.2.0.10.in-addr.arpa. IN PTR agamemnon.cosc.tu. 5.2.0.10.in-addr.arpa. IN PTR agrippa.cosc.tu. 6.2.0.10.in-addr.arpa. IN PTR alexander.cosc.tu. 7.2.0.10.in-addr.arpa. IN PTR anubis.cosc.tu. 8.2.0.10.in-addr.arpa. IN PTR apollo.cosc.tu. 9.2.0.10.in-addr.arpa. IN PTR cadmus.cosc.tu. 10.2.0.10.in-addr.arpa. IN PTR cerberus.cosc.tu. 11.2.0.10.in-addr.arpa. IN PTR charon.cosc.tu. 12.2.0.10.in-addr.arpa. IN PTR churchill.cosc.tu. 13.2.0.10.in-addr.arpa. IN PTR delphi.cosc.tu. 14.2.0.10.in-addr.arpa. IN PTR excalibur.cosc.tu. 15.2.0.10.in-addr.arpa. IN PTR furies.cosc.tu. 16.2.0.10.in-addr.arpa. IN PTR heracles.cosc.tu. 17.2.0.10.in-addr.arpa. IN PTR hermes.cosc.tu. 18.2.0.10.in-addr.arpa. IN PTR hydra.cosc.tu. 19.2.0.10.in-addr.arpa. IN PTR juno.cosc.tu. 20.2.0.10.in-addr.arpa. IN PTR medusa.cosc.tu. 21.2.0.10.in-addr.arpa. IN PTR nemesis.cosc.tu. 22.2.0.10.in-addr.arpa. IN PTR nimrod.cosc.tu. 23.2.0.10.in-addr.arpa. IN PTR olympic.cosc.tu. 24.2.0.10.in-addr.arpa. IN PTR orion.cosc.tu. 25.2.0.10.in-addr.arpa. IN PTR persephone.cosc.tu. 26.2.0.10.in-addr.arpa. IN PTR pollux.cosc.tu. 27.2.0.10.in-addr.arpa. IN PTR roanoke.cosc.tu. 28.2.0.10.in-addr.arpa. IN PTR talos.cosc.tu. 29.2.0.10.in-addr.arpa. IN PTR theseus.cosc.tu. 30.2.0.10.in-addr.arpa. IN PTR vesta.cosc.tu. 31.2.0.10.in-addr.arpa. IN PTR zeus.cosc.tu. 254.2.0.10.in-addr.arpa. IN PTR gw.cosc.tu.
Like the forward zone, we have set the time to live to a short five minutes.
Next comes a start of authority record (SOA) with the same structure we saw for the forward zone. The difference here is we want the zone to named after the address space 10.0.2.0/24. This is what occurs in our file, though it may not be clear at first reading. To construct the name, take the IP range in octet form, reverse the numbers, and end with ".in-addr.arpa.". This convention is a leftover from the original (1980s) days of the Internet as it evolved from the Defense Advanced Research Project Agency (DARPA). If the subnet in question was 192.168.0.0/16, then we would use 168.192.in-addr.arpa and so on.
[My smart students are now asking a deep question- what if we want to create a lookup zone for a smaller address space- say 10.0.2.80/28 (10.0.2.80 – 10.0.2.95)? Yeah, we aren’t going to go there. This is possible, sort of, with a few hacks. Take a look at DNS & BIND by Liu & Albitz, pp. 215 ff.]
The values in the IN SOA record have already been explained and follow the same convention. Similarly, the required Internet nameserver (IN NS) record is as it was before.
The remaining records are Internet pointer (IN PTR) records. The left side is the IP address, written in the reversed ".in-addr.arpa" form, while the right side is the full domain name at that address.
These records should match the forward zone records. Though you can set up more than one host name to point to a single IP address, in the reverse zone there should be only one name for any single IP address.
Scripting
Now for any reasonably sized domain, like the ones that we are going to see in our exercises, the number of hosts becomes quite large. Typing them all in the forward zone is a pain, but then needing to do almost the same thing again, without making any typographical errors is just an accident waiting to happen.
Here is a perfect chance to learn a bit of scripting. Suppose that you already have written the forward zone as it is above, with more that 30 hosts. Let’s just copy the address records to another file, and call it forward.txt
. It is just the work of a moment to craft a Python script that will turn this into the corresponding reverse zone. Consider
#!/usr/bin/python input_file_name = "forward.txt" output_file_name = "reverse.txt" infile = open(input_file_name,"r") ofile = open(output_file_name,"w") for line in infile: [host,protocol,record,ipaddr] = line.split() [i1,i2,i3,i4] = ipaddr.split('.') # Split ip address on dots revaddr = i4 + '.' + i3 + '.' + i2 + '.' + i1 + '.in-addr.arpa.' size = 34 - len(revaddr) padding = ' ' * size ofile.write(revaddr + padding + "IN PTR " + host + '\n') infile.close() ofile.close()
If this is made executable, then it will open the file forward.txt
, then split each line into four parts- the host name, the protocol ("IN") the record ("A") and the IP address. The IP address is then split on each octet.
The reversed IP address is built, ending with ".in-addr.arpa." as required. The size of the address string is determined, so we can pad it out so all of the columns are aligned, then the required information is written back out to another output.txt
.
Easy! And much less work that doing this all by hand! You should get in the habit or writing your own scripts for simple tasks like this. There are any number of languages that are worth learning- Bash, Powershell, Windows batch scripts, Python, and Perl all come quickly to mind. Personally, I like Python, but you should learn at least a couple of these; this investment will pay dividends in time and effort throughout your career.
Loopback
Returning to the nameserver, we should also handle name server lookups on the loopback address. Admittedly, this is not strictly necessary, as it can be handled by the host rather than by the DNS server. Still- why not be careful?
Create the file /var/named/db.127.0.0 as follows:
$TTL 5m ; 0.0.127.in-addr.arpa. IN SOA acheron.cosc.tu. zathras.cosc.tu. ( 1 ; Serial 5m ; Refresh after 5 minutes 3m ; Retry after 3 minutes 30m ; Expire after 30 minutes 5m ) ; Negative TTL of one week ; 0.0.127.in-addr.arpa. IN NS acheron.cosc.tu. ; 1.0.0.127.in-addr.arpa. IN PTR localhost
Root Hints
If we were connected to the Internet, we would also need a root hints file from http://www.internic.net/zones/named.root. An older version of this file is actually present on the VM provided to class. We will not even configure this feature.
named.conf
Finally, we set up the file /etc/named.con
f, which configures the name server itself, rather than the individual zones. You may wish to keep a copy of the original file /etc/named.conf
provided as part of the system’s initial installation. Using the file names chosen above, we create the file as follows.
// BIND Configuration File options { directory "/var/named"; }; zone "cosc.tu" in { type master; file "db.cosc.tu"; }; zone "2.0.10.in-addr.arpa" in { type master; file "db.10.0.2"; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; };
If we wanted to configure the root hints file for an Internet accessible server, we would add
zone "." in { type hint; file "db.root.hints"; };
to the above, were the file db.root.hints is the root hints file we downloaded.
Running and Testing
To start your server, run
[root@acheron ~]# /etc/init.d/named start Starting named: [ OK ]
Be sure to correct any errors that appear! You should be sure to check the system log files as well (e.g. /var/log/messages
), as not every error will be reported back to and through the initialization script.
You should see a line in the log file like
Jan 25 11:57:03 acheron named[8347]: starting BIND 9.7.3-P3-RedHat-9.7.3- 8.P3.el6 -u named
showing that named
was started. You should also find lines like
Jan 25 11:57:03 acheron named[8347]: zone 2.0.10.in-addr.arpa/IN: loaded serial 1 Jan 25 11:57:03 acheron named[8347]: zone 0.0.127.in-addr.arpa/IN: loaded serial 1 Jan 25 11:57:03 acheron named[8347]: zone cosc.tu/IN: loaded serial 1
that show that your three zones loaded succesfully. Finally, you should see
Jan 25 11:57:03 acheron named[8347]: running
telling you that the service is running.
You will see some messages about the rndc key file not being found; these can be ignored for the moment; we will take care of them as we continue to configure the server.
As your first test, from the DNS server, run nslookup from the command line, specifying a host name that appears in your forward zone and the IP address of the name server:
[zathras@acheron ~]$ nslookup zeus.cosc.tu 10.0.2.100 Server: 10.0.2.100 Address: 10.0.2.100#53 Name: zeus.cosc.tu Address: 10.0.2.31
Next, check that the reverse zone is functioning by checking an IP address:
[zathras@acheron ~]$ nslookup 10.0.2.31 10.0.2.100 Server: 10.0.2.100 Address: 10.0.2.100#53 31.2.0.10.in-addr.arpa name = zeus.cosc.tu.
It would be convenient as we test our setup further if we did not have to manually specify the location of the DNS server each time. Recall how we set up the system in the first place, and go back and modify the network settings for the system so that it now uses itself for DNS; you can do this by editing /etc/sysconfig/network-scripts/ifcfg-eth0
.
Check again that things are as they ought to be:
[zathras@acheron ~]$ nslookip nemesis bash: nslookip: command not found [zathras@acheron ~]$ nslookup juno Server: 10.0.2.100 Address: 10.0.2.100#53 Name: juno.cosc.tu Address: 10.0.2.19 [zathras@acheron ~]$ nslookup 10.0.2.9 Server: 10.0.2.100 Address: 10.0.2.100#53 9.2.0.10.in-addr.arpa name = cadmus.cosc
Note that errors can sometimes be caught with these tests. Suppose for example, that you accidentally left off the tailing period in your reverse zone, so that you wrote
24.2.0.10.in-addr.arpa. IN PTR orion.cosc.tu
instead of
24.2.0.10.in-addr.arpa. IN PTR orion.cosc.tu.
Then your reverse zone lookups would give you incorrect results in the form
[zathras@acheron ~]$ nslookup 10.0.2.24 Server: 10.0.2.100 Address: 10.0.2.100#53 24.2.0.10.in-addr.arpa name = orion.cosc.tu.2.0.10.in-addr.arpa.
I can’t emphasize strongly enough how important it is to be thorough and careful, and to check your work regularly as you proceed. You cannot "zoom through" this in a hurry. Students have tried, oh they have tried. They usually finish a few hours after the folks who are slow, careful and thorough. Check your work after each step, and be critical- look for errors, instead of being happy that nothing seemed wrong.
To ensure the DNS server starts on boot, you can use the menu and navigate System → Administration → Services. Scroll through the list of services to named, and set it to enabled. This method also be used to start & stop the service. The command line equivalent of this tool is chkconfig; see man chkconfig for its use.
Be sure to open a hole in your firewall to allow for the necessary traffic. DNS runs on UDP 53, with some traffic (e.g. zone transfers) on TCP 53. You can do this from the menu; navigate System → Administration → and Firewall.
Reboot the system, and test that everything starts as it ought; check that you can use other systems to query the nameserver via the nslookup
command. [This command is even available on Windows systems, on the command line.]
Setting up a slave nameserver
Why do we want to set up a second nameserver? Well, if the primary goes down and you have no backup, then you are having a bad day!
Start with a new CentOS machine, and configure its hostname and network connection appropriately. In this example, we give it the hostname "damocles.cosc.tu" and the IP address 10.0.2.101. Note that this name/IP combination is already included in DNS zone data for our master nameserver. We do need to modify that file though, to indicate that damocles.cosc.tu should be considered a nameserver for cosc.tu as well. Both the forward zone (in db.cosc.tu) and the reverse zone (in db.10.0.2) need to be updated.
For example, the nameserver section in db.cosc.tu
should be updated to read
; ; Name Servers ; cosc.tu. IN NS acheron.cosc.tu. cosc.tu. IN NS damocles.cosc.tu.
while the corresponding section in db.10.0.2
becomes
; ; Name Servers ; 2.0.10.in-addr.arpa. IN NS acheron.cosc.tu. 2.0.10.in-addr.arpa. IN NS damocles.cosc.tu.
The slave named.conf file
With the new system built and the appropriate entries made to our master DNS server, it is time to configure the slave.
First we create a new /etc/named.conf
file on the slave as follows:
// BIND Configuration File options { directory "/var/named/slaves"; }; zone "cosc.tu" in { type slave; file "bak.cosc.tu"; masters {10.0.2.100; }; }; zone "2.0.10.in-addr.arpa" in { type slave; file "bak.10.0.2"; masters {10.0.2.100; }; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; };
Notice that instead of "type master" they are set to "type slave". For each slave zone, the configuration specifies a set of masters for that zone.
Note however, that the server should still be the master for its own localhost; thus we create the file db.127.0.0
in the same fashion as we did for the master. Because we have set the directory to /var/named/slaves
though, then that is the location that file should be kept.
Now when the name server starts on the slave, it will load the necessary data from the master. This way the authoritative data is kept in only one location. There is no need to manually ensure that the servers are in agreement.
Because the name server is going to be writing data, we need to make sure that the directories have the proper permissions set- this is the reason we use the directory /var/named/slaves, as it already has the proper permissions set.
Starting the slave
Start the slave server using /etc/init.d/named
as we did for the master, being sure to check for errors, both at the command line and in the log file /var/log/messages
.
The log file, /var/log/messages
should contain lines like the following that indicate the transfer has occurred:
Jan 25 12:33:03 damocles named[7859]: zone cosc.tu/IN: Transfer started. Jan 25 12:33:03 damocles named[7859]: transfer of 'cosc.tu/IN' from 10.0.2.100#53: connected using 10.0.2.101#35283 Jan 25 12:33:03 damocles named[7859]: zone cosc.tu/IN: transferred serial 1 Jan 25 12:33:03 damocles named[7859]: transfer of 'cosc.tu/IN' from 10.0.2.100#53: Transfer completed: 1 messages, 38 records, 931 bytes, 0.001 secs (931000 bytes/sec) Jan 25 12:33:03 damocles named[7859]: zone cosc.tu/IN: sending notifies (serial 1) Jan 25 12:33:04 damocles named[7859]: zone 2.0.10.in-addr.arpa/IN: Transfer started. Jan 25 12:33:04 damocles named[7859]: transfer of '2.0.10.in-addr.arpa/IN' from 10.0.2.100#53: connected using 10.0.2.101#50428 Jan 25 12:33:04 damocles named[7859]: zone 2.0.10.in-addr.arpa/IN: transferred serial 1 Jan 25 12:33:04 damocles named[7859]: transfer of '2.0.10.in-addr.arpa/IN' from 10.0.2.100#53: Transfer completed: 1 messages, 35 records, 920 bytes, 0.001 secs (920000 bytes/sec)
Check that the zone files have been downloaded and now reside in the directory /var/named/slaves
. They have the same basic structure we saw before, but a number of shortcuts and abbreviations that we did not discuss are used.
[root@damocles ~]# cat /var/named/slaves/bak.cosc.tu $ORIGIN . $TTL 300 ; 5 minutes cosc.tu IN SOA acheron.cosc.tu. zathras.cosc.tu. ( 1 ; serial 300 ; refresh (5 minutes) 180 ; retry (3 minutes) 1800 ; expire (30 minutes) 300 ; minimum (5 minutes) ) NS acheron.cosc.tu. NS damocles.cosc.tu. $ORIGIN cosc.tu. acheron A 10.0.2.100 achilles A 10.0.2.3 agamemnon A 10.0.2.4 agrippa A 10.0.2.5 alexander A 10.0.2.6 anubis A 10.0.2.7 apollo A 10.0.2.8 cadmus A 10.0.2.9 cerberus A 10.0.2.10 charon A 10.0.2.11 churchill A 10.0.2.12 damocles A 10.0.2.101 delphi A 10.0.2.13 dns CNAME acheron excalibur A 10.0.2.14 furies A 10.0.2.15 gw A 10.0.2.254 heracles A 10.0.2.16 hermes A 10.0.2.17 hydra A 10.0.2.18 juno A 10.0.2.19 localhost A 127.0.0.1 medusa A 10.0.2.20 nemesis A 10.0.2.21 nimrod A 10.0.2.22 olympic A 10.0.2.23 orion A 10.0.2.24 persephone A 10.0.2.25 pollux A 10.0.2.26 roanoke A 10.0.2.27 talos A 10.0.2.28 theseus A 10.0.2.29 vesta A 10.0.2.30 zeus A 10.0.2.31
[root@damocles ~]# cat /var/named/slaves/bak.10.0.2 $ORIGIN . $TTL 300 ; 5 minutes 2.0.10.in-addr.arpa IN SOA acheron.cosc.tu. zathras.cosc.tu. ( 1 ; serial 300 ; refresh (5 minutes) 180 ; retry (3 minutes) 1800 ; expire (30 minutes) 300 ; minimum (5 minutes) ) NS acheron.cosc.tu. $ORIGIN 2.0.10.in-addr.arpa. 10 PTR cerberus.cosc.tu. 100 PTR acheron.cosc.tu. 101 PTR damocles.cosc.tu. 11 PTR charon.cosc.tu. 12 PTR churchill.cosc.tu. 13 PTR delphi.cosc.tu. 14 PTR excalibur.cosc.tu. 15 PTR furies.cosc.tu. 16 PTR heracles.cosc.tu. 17 PTR hermes.cosc.tu. 18 PTR hydra.cosc.tu. 19 PTR juno.cosc.tu. 20 PTR medusa.cosc.tu. 21 PTR nemesis.cosc.tu. 22 PTR nimrod.cosc.tu. 23 PTR olympic.cosc.tu. 24 PTR orion.cosc.tu. 25 PTR persephone.cosc.tu. 254 PTR gw.cosc.tu. 26 PTR pollux.cosc.tu. 27 PTR roanoke.cosc.tu. 28 PTR talos.cosc.tu. 29 PTR theseus.cosc.tu. 3 PTR achilles.cosc.tu. 30 PTR vesta.cosc.tu. 31 PTR zeus.cosc.tu. 4 PTR agamemnon.cosc.tu. 5 PTR agrippa.cosc.tu. 6 PTR alexander.cosc.tu. 7 PTR anubis.cosc.tu. 8 PTR apollo.cosc.tu. 9 PTR cadmus.cosc.tu.
As before, ensure that the DNS server starts on boot, is enabled, and that the firewall will allow traffic to and from the server.
Update each client to use both master and slave as their DNS server. Now the resolver file /etc/resolv.conf will have two entries, not just one.
Check that the slave nameserver is functioning. First try the nslookup command from a client that specifies the nameserver you want. Then shutdown the master and check that the client is still able to resolve both names and addresses.
Windows Weirdness
Suppose we specify 10.0.2.100 as the primary nameserver and 10.0.2.101 as the alternate nameserver on a Windows system- say a Windows 7 (though I have seen this on most other versions as well). Then, if the primary goes down, nslookup commands will fail:
C:\Users\zathras>nslookup acheron DNS request timed out. timeout was 2 seconds. Server: UnKnown Address: 10.0.2.100 DNS request timed out. timeout was 2 seconds. DNS request timed out. timeout was 2 seconds. *** Request to UnKnown timed-out
This does not mean that the slave nameserver has failed; you can check by directly querying the slave nameserver
C:\Users\zathras>nslookup acheron 10.0.2.101 Server: damocles.cosc.tu Address: 10.0.2.101 Name: acheron.cosc.tu Address: 10.0.2.100
The weirdness is that, even though nslookup will fail, you can still use the backup nameserver, for example for pings
C:\Users\zathras>ping acheron Pinging acheron.cosc.tu [10.0.2.100] with 32 bytes of data: Reply from 10.0.2.100: bytes=32 time<1ms TTL=64 Reply from 10.0.2.100: bytes=32 time<1ms TTL=64 Reply from 10.0.2.100: bytes=32 time<1ms TTL=64 Reply from 10.0.2.100: bytes=32 time<1ms TTL=64 Ping statistics for 10.0.2.100: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 0ms, Average = 0ms
Why does Windows behave this way? Beats me. This is why I labelled this behavior "weird". Linux systems don’t act this way, and nslookup commands will properly fall through to the alternate if the primary is down. It can trip you up as a student though, when you are first getting nameservers up and running.
Timeout Errors
Remember that we set the timing values for the slaves to be qute short. For example, with the given settings if your primary nameserver is down for more than 30 minutes, then your slave namersvers will no longer respond, as you will have exceeded the TTL, even if the slave is otherwise fully functional. On a Linux system, you would see errors of the form
zathras@acheron ~]$ nslookup damocles ;; Got SERVFAIL reply from 10.0.2.101, trying next server ;; connection timed out; no servers could be reached
while on a Windows system you may end up with
C:\Users\zathras>nslookup damocles DNS request timed out. timeout was 2 seconds. Server: UnKnown Address: 10.0.2.100 DNS request timed out. timeout was 2 seconds. DNS request timed out. timeout was 2 seconds. *** Request to UnKnown timed-out
These errors are not immediately fixed if the master starts, as it takes more time for the slave to freshen its data with the (now started) master.
Controlling the nameserver
The tool rndc can be used to control the state of a nameserver- either located locally or on another server. If you were smart and have been paying attention, you will have noticed some unusual warnings as the nameserver was configured; if you ask the initialization script for the status of the nameserver, you are presented with a warning about rndc:
[root@acheron ~]# /etc/init.d/named status rndc: neither /etc/rndc.conf nor /etc/rndc.key was found named (pid 3744) is running...
We will now solve these problems and correctly configure rndc.
We start by running the tool rndc-confgen, and storing the results in the file rndcconf
[root@acheron ~]# rndc-confgen > rndconf
Taking a look at the contents of this file, we are presented with something like the following:
# Start of rndc.conf key "rndc-key" { algorithm hmac-md5; secret "FaL1U0WjL4nh3z898cY6fg=="; }; options { default-key "rndc-key"; default-server 127.0.0.1; default-port 953; }; # End of rndc.conf # Use with the following in named.conf, adjusting the allow list as needed: # key "rndc-key" { # algorithm hmac-md5; # secret "FaL1U0WjL4nh3z898cY6fg=="; # }; # # controls { # inet 127.0.0.1 port 953 # allow { 127.0.0.1; } keys { "rndc-key"; }; # }; # End of named.conf
When rndc is used, it authenticates to BIND via the use of a pre-shared secret; this is one of the purposes of the rndc-confgen script. It has generated a pre-shared secret for us and moreover provided the different components that can simply be copied into the proper files.
We do not need to create the file rndc.conf
. Instead we start by creating the file /etc/rndc.key
with the copied contents
key "rndc-key" { algorithm hmac-md5; secret "FaL1U0WjL4nh3z898cY6fg=="; };
Now if this file is world readable, then, well it is not much good as a shared "secret" is it? The whole point of a "secret" is that we aren’t going to tell everyone right? Well, take a look at the defaults…
[root@acheron ~]# ls -l /etc/rndc.key -rw-r--r--. 1 root root 77 Jan 25 14:01 /etc/rndc.key
Not so secret, as it is world readable. Still, a little change, and we should be good to go
[root@acheron ~]# chmod o-r /etc/rndc.key [root@acheron ~]# ls -l /etc/rndc.key -rw-r-----. 1 root root 77 Jan 25 14:01 /etc/rndc.key
Good to go? Well, not so much. On the one hand, now only root can read the rndc.key file, but the thing is the named server also has to be able to read it. We handle this by changing the group owner of the file to the group named, which includes the user named which runs the named service. [At least they were consistent with their nameds, umm names.]
[root@acheron ~]# chown root:named /etc/rndc.key [root@acheron ~]# ls -l /etc/rndc.key -rw-r-----. 1 root named 77 Jan 25 14:01 /etc/rndc.key
Next we update the primary configuration file /etc/named.conf
. In the case of the master, the file now becomes
// BIND Configuration File options { directory "/var/named"; }; zone "cosc.tu" in { type master; file "db.cosc.tu"; }; zone "2.0.10.in-addr.arpa" in { type master; file "db.10.0.2"; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; }; include "/etc/rndc.key"; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; };
The changes occur at the bottom of the file. First is the inclusion of the key file we just created. That key file defines the key "rndc-key" with the secret "FaL1U0WjL4nh3z898cY6fg==". The second change is the controls section; this tells the server to open up TCP port 953 on localhost (127.0.0.1) only and to require that connections to that control provide the key named "rndc-key".
At this point you can re-start the named server, and there should no longer be any mention of rndc warnings.
[root@acheron ~]# /etc/init.d/named status version: 9.7.3-P3-RedHat-9.7.3-8.P3.el6 CPUs found: 1 worker threads: 1 number of zones: 19 debug level: 0 xfers running: 0 xfers deferred: 0 soa queries in progress: 0 query logging is OFF recursive clients: 0/0/1000 tcp clients: 0/100 server is up and running named (pid 3972) is running...
The modification of the named.conf file for a slave server is done in precisely the same fashion.
Oh yes, one more thing. You did remember to delete that file rndcconf
right? That file contains our secret, and it better not be world readable, or all of this work is for naught.
With rndc correctly configured, we can query and control the behavior of the named server. We can run rndc status
to get the same status for the server we saw above.
Logging queries
Suppose that you want to know more about the queries that your DNS server receives? Did you notice the line
query logging is OFF
when you ran rndc status
? We can set that variable to on
[root@acheron ~]# rndc querylog on
and verify the change
[root@acheron ~]# rndc status version: 9.7.3-P3-RedHat-9.7.3-8.P3.el6 CPUs found: 1 worker threads: 1 number of zones: 19 debug level: 0 xfers running: 0 xfers deferred: 0 soa queries in progress: 0 query logging is ON recursive clients: 0/0/1000 tcp clients: 0/100 server is up and running
Now every time the server receives a DNS request, the information will be stored in the logs
Jan 25 14:13:03 acheron named[3972]: received control channel command 'querylog on' Jan 25 14:13:03 acheron named[3972]: query logging is now on Jan 25 14:13:18 acheron named[3972]: client 10.0.2.8#51734: query: 100.2.0.10.in-addr.arpa IN PTR + (10.0.2.100) Jan 25 14:13:18 acheron named[3972]: client 10.0.2.8#51735: query: cerberus.cosc.tu IN A + (10.0.2.100) Jan 25 14:13:18 acheron named[3972]: client 10.0.2.8#51736: query: cerberus.cosc.tu IN AAAA + (10.0.2.100) Jan 25 14:13:40 acheron named[3972]: client 10.0.2.101#22509: query: 2.0.10.in-addr.arpa IN SOA -E (10.0.2.100) Jan 25 14:14:24 acheron named[3972]: client 10.0.2.8#51737: query: 100.2.0.10.in-addr.arpa IN PTR + (10.0.2.100) Jan 25 14:14:24 acheron named[3972]: client 10.0.2.8#51738: query: orion.cosc.tu IN A + (10.0.2.100) Jan 25 14:14:24 acheron named[3972]: client 10.0.2.8#51739: query: orion.cosc.tu IN AAAA + (10.0.2.100)
You can see how this would be helpful. Just remember that this will log all of the requests, and this could put a strain on resources on a busy server.
Updating Zone Data
Suppose we add a new host to our zone files- say we add the line
clarkstown.cosc.tu. IN A 10.0.2.32
to our db.cosc.tu file for the forward zone, updating the serial number in the file, and we add the corresponding line
32.2.0.in.in-addr.arpa. IN PTR clarkstown.cosc.tu.
to the file db.10.0.2 for the reverse zone and again updating the serial number in that file. How do we tell the BIND to reload the configuration? We could use the startup scripts in /etc/init.d
, but it is simpler to just use rndc and tell the server to reload its data:
[root@acheron ~]# nslookup clarkstown Server: 10.0.2.100 Address: 10.0.2.100#53 ** server can't find clarkstown: NXDOMAIN [root@acheron ~]# nslookup 10.0.2.32 Server: 10.0.2.100 Address: 10.0.2.100#53 ** server can't find 32.2.0.10.in-addr.arpa.: NXDOMAIN [root@acheron ~]# rndc reload server reload successful [root@acheron ~]# nslookup clarkstown Server: 10.0.2.100 Address: 10.0.2.100#53 Name: clarkstown.cosc.tu Address: 10.0.2.32 [root@acheron ~]# nslookup 10.0.2.32 Server: 10.0.2.100 Address: 10.0.2.100#53 32.2.0.10.in-addr.arpa name = clarkstown.cosc.tu.
What happens on the slave? Provided we updated the serial number (don’t forget!) the slaves will be notified by the master that new zone files are available. Now the slave does not necessarily immediately download the new zone data, as the slave determines when that should be scheduled. However because we are using such aggressive timing, this happens almost immediately. Here are the logs (/var/log/messages) for the master:
Jan 25 16:15:21 acheron named[3972]: received control channel command 'reload' Jan 25 16:15:21 acheron named[3972]: loading configuration from '/etc/named.conf' Jan 25 16:15:21 acheron named[3972]: using default UDP/IPv4 port range: [1024, 65535] Jan 25 16:15:21 acheron named[3972]: using default UDP/IPv6 port range: [1024, 65535] Jan 25 16:15:21 acheron named[3972]: reloading configuration succeeded Jan 25 16:15:21 acheron named[3972]: reloading zones succeeded Jan 25 16:15:21 acheron named[3972]: zone 2.0.10.in-addr.arpa/IN: loaded serial 3 Jan 25 16:15:21 acheron named[3972]: zone cosc.tu/IN: loaded serial 3 Jan 25 16:15:21 acheron named[3972]: zone 2.0.10.in-addr.arpa/IN: sending notifies (serial 3) Jan 25 16:15:21 acheron named[3972]: zone cosc.tu/IN: sending notifies (serial 3) Jan 25 16:15:21 acheron named[3972]: client 10.0.2.101#31567: query: 2.0.10.in-addr.arpa IN SOA -E (10.0.2.100) Jan 25 16:15:21 acheron named[3972]: client 10.0.2.101#42366: query: 2.0.10.in-addr.arpa IN IXFR -T (10.0.2.100) Jan 25 16:15:21 acheron named[3972]: client 10.0.2.101#42366: transfer of '2.0.10.in-addr.arpa/IN': AXFR-style IXFR started Jan 25 16:15:21 acheron named[3972]: client 10.0.2.101#42366: transfer of '2.0.10.in-addr.arpa/IN': AXFR-style IXFR ended Jan 25 16:15:22 acheron named[3972]: client 10.0.2.101#49703: transfer of 'cosc.tu/IN': AXFR-style IXFR started Jan 25 16:15:22 acheron named[3972]: client 10.0.2.101#49703: transfer of 'cosc.tu/IN': AXFR-style IXFR ended
You can see that the reload took place at 16:5:21, two notifies (one for the changed forward zone and one for the changed reverse zone) took place almost immediately thereafter, and the zone transfers right after that. The slave’s logs show the same process from that perspective:
Jan 25 16:15:21 damocles named[9745]: client 10.0.2.100#2774: received notify for zone '2.0.10.in-addr.arpa' Jan 25 16:15:21 damocles named[9745]: zone 2.0.10.in-addr.arpa/IN: Transfer started. Jan 25 16:15:21 damocles named[9745]: transfer of '2.0.10.in-addr.arpa/IN' from 10.0.2.100#53: connected using 10.0.2.101#42366 Jan 25 16:15:21 damocles named[9745]: zone 2.0.10.in-addr.arpa/IN: transferred serial 3 Jan 25 16:15:21 damocles named[9745]: transfer of '2.0.10.in-addr.arpa/IN' from 10.0.2.100#53: Transfer completed: 1 messages, 37 records, 962 bytes, 0.001 secs (962000 bytes/sec) Jan 25 16:15:21 damocles named[9745]: zone 2.0.10.in-addr.arpa/IN: sending notifies (serial 3) Jan 25 16:15:22 damocles named[9745]: client 10.0.2.100#18094: received notify for zone 'cosc.tu' Jan 25 16:15:22 damocles named[9745]: zone cosc.tu/IN: Transfer started. Jan 25 16:15:22 damocles named[9745]: transfer of 'cosc.tu/IN' from 10.0.2.100#53: connected using 10.0.2.101#49703 Jan 25 16:15:22 damocles named[9745]: zone cosc.tu/IN: transferred serial 3 Jan 25 16:15:22 damocles named[9745]: transfer of 'cosc.tu/IN' from 10.0.2.100#53: Transfer completed: 1 messages, 39 records, 958 bytes, 0.001 secs (958000 bytes/sec) Jan 25 16:15:22 damocles named[9745]: zone cosc.tu/IN: sending notifies (serial 3)
Setting up forwarders
On the internet, if the name server is unable to answer a query it sends the request on to one of the root nameservers, and gets its results. In our lab, we don’t have access to the Internet. Suppose that team 1 and team 2 each set up their own nameservers. How do we let team 1 query the nameserver for team 2 whenever it is given a name from team 2? One answer is to use a forwarder.
Suppose that team 1 is using the namespace .team1.tu, while team 2 is using the namespace .acme.tu. We also suppose that the nameserver for team 2 is located at 10.0.4.77. Then in the named.conf file for team 1, we add the lines:
zone "acme.tu" in { type forward; forwarders {10.0.4.77; }; };
Now when a machine that is using the team 1 DNS server is asked for an address from team 2- say http://www.acme.tu- that request will be forwarded to the nameserver 10.0.4.77 maintained by team 2, and the nameserver for team 1 will cache the reply and send the result back to the requestor.
Common DNS commands
nslookup
For each example, run the command & understand the output. [Use windows and/or linux versions.]
nslookup "hostname
“nslookup "IP_address"
nslookup -type=ns "yourdomain."
nslookup "hostname" "IP_address_of_other_server"
Run nslookup with no arguments to get the nslookup shell. Run each of these commands from within the nslookup shell. [Use the linux version.]
[root@acheron ~]# nslookup > set all Default server: 10.0.2.100 Address: 10.0.2.100#53 Default server: 10.0.2.101 Address: 10.0.2.101#53 Set options: novc nodebug nod2 search recurse timeout = 0 retry = 3 port = 53 querytype = A class = IN srchlist = cosc.tu
This shows the nslookup options currently set. Options include
- [no]vc- Use UDP (no) or TCP (yes).
- [no]debug- Hmmm- can we guess what this option is?
- [no]d2- Debugging at level 2.
- [no]search- when on, add the domain name if the hostname does not end with a .
- [no]recurse- default is to use recursive queries
The Windows equivalent is similar; here is the output from a Windows 8 PowerShell prompt:
PS C:\Users\zathras>nslookup Default Server: acheron.cosc.tu Address: 10.0.2.100 > set all Default Server: acheron.cosc.tu Address: 10.0.2.100 Set options: nodebug defname search recurse nod2 novc noignoretc port=53 type=A+AAAA class=IN timeout=2 retry=1 root=A.ROOT-SERVERS.NET. domain=cosc.tu MSxfr IXFRversion=1 srchlist=cosc.tu >
From within the nslookup shell, you can get information about a host by simply giving the name like the following:
[root@acheron ~]# nslookup > apollo Server: 10.0.2.100 Address: 10.0.2.100#53 Name: apollo.cosc.tu Address: 10.0.2.8
Do so. Do the same with an IP address, e.g.
PS C:\Users\zathras> nslookup Default Server: acheron.cosc.tu Address: 10.0.2.100 > 10.0.2.7 Server: acheron.cosc.tu Address: 10.0.2.100 Name: anubis.cosc.tu Address: 10.0.2.7
dig
Another important command to be comfortable using is dig. Unlike nslookup, this is not available by default on Windows systems. However it is available as part of the BIND package for Windows available at ISC; I will make a copy available on the lab share.
It is simplest to use when your resolv.conf uses the nameserver you want to test. Here is an example from a Windows 8 system
PS C:\Users\zathras> cd .\Desktop\BIND9.9.2-P1 PS C:\Users\zathras\Desktop\BIND9.9.2-P1> .\dig.exe -x 10.0.2.100 ; <<>> DiG 9.9.2-P1 <<>> -x 10.0.2.100 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34072 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;100.2.0.10.in-addr.arpa. IN PTR ;; ANSWER SECTION: 100.2.0.10.in-addr.arpa. 300 IN PTR acheron.cosc.tu. ;; AUTHORITY SECTION: 2.0.10.in-addr.arpa. 300 IN NS acheron.cosc.tu. 2.0.10.in-addr.arpa. 300 IN NS damocles.cosc.tu. ;; ADDITIONAL SECTION: acheron.cosc.tu. 300 IN A 10.0.2.100 damocles.cosc.tu. 300 IN A 10.0.2.101 ;; Query time: 0 msec ;; SERVER: 10.0.2.100#53(10.0.2.100) ;; WHEN: Sat Jan 25 21:12:59 2014 ;; MSG SIZE rcvd: 150
The syntax and results on a Linux system would be the same.
We performed a full reverse lookup on this address; note that we got quite a bit more data than simply the hostname that lives at 10.0.2.100.
We can also try a forward query; here is an example using the Linux version of the tool
[zathras@acheron ~]$ dig heracles.cosc.tu ; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6 <<>> heracles.cosc.tu ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49001 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2 ;; QUESTION SECTION: ;heracles.cosc.tu. IN A ;; ANSWER SECTION: heracles.cosc.tu. 300 IN A 10.0.2.16 ;; AUTHORITY SECTION: cosc.tu. 300 IN NS damocles.cosc.tu. cosc.tu. 300 IN NS acheron.cosc.tu. ;; ADDITIONAL SECTION: acheron.cosc.tu. 300 IN A 10.0.2.100 damocles.cosc.tu. 300 IN A 10.0.2.101 ;; Query time: 0 msec ;; SERVER: 10.0.2.100#53(10.0.2.100) ;; WHEN: Sat Jan 25 18:17:39 2014 ;; MSG SIZE rcvd: 127
Again, the Windows version of the tool returns the same data.
It is possible to use dig to pull the entire zone from a host, and you don’t even need to use it as your nameserver. [Hmmm. How could this be handy in a live-fire exercise?] Here is a Kali host (getting its IP from DHCP and with no name server) finding out all there is to know about the cosc.tu namespace:
root@kali32:~# dig @10.0.2.100 cosc.tu axfr ; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @10.0.2.100 cosc.tu axfr ; (1 server found) ;; global options: +cmd cosc.tu. 300 IN SOA acheron.cosc.tu. zathras.cosc.tu. 3 300 180 1800 300 cosc.tu. 300 IN NS acheron.cosc.tu. cosc.tu. 300 IN NS damocles.cosc.tu. acheron.cosc.tu. 300 IN A 10.0.2.100 achilles.cosc.tu. 300 IN A 10.0.2.3 agamemnon.cosc.tu. 300 IN A 10.0.2.4 agrippa.cosc.tu. 300 IN A 10.0.2.5 alexander.cosc.tu. 300 IN A 10.0.2.6 anubis.cosc.tu. 300 IN A 10.0.2.7 apollo.cosc.tu. 300 IN A 10.0.2.8 cadmus.cosc.tu. 300 IN A 10.0.2.9 cerberus.cosc.tu. 300 IN A 10.0.2.10 charon.cosc.tu. 300 IN A 10.0.2.11 churchill.cosc.tu. 300 IN A 10.0.2.12 clarkstown.cosc.tu. 300 IN A 10.0.2.32 damocles.cosc.tu. 300 IN A 10.0.2.101 delphi.cosc.tu. 300 IN A 10.0.2.13 dns.cosc.tu. 300 IN CNAME acheron.cosc.tu. excalibur.cosc.tu. 300 IN A 10.0.2.14 furies.cosc.tu. 300 IN A 10.0.2.15 gw.cosc.tu. 300 IN A 10.0.2.254 heracles.cosc.tu. 300 IN A 10.0.2.16 hermes.cosc.tu. 300 IN A 10.0.2.17 hydra.cosc.tu. 300 IN A 10.0.2.18 juno.cosc.tu. 300 IN A 10.0.2.19 localhost.cosc.tu. 300 IN A 127.0.0.1 medusa.cosc.tu. 300 IN A 10.0.2.20 nemesis.cosc.tu. 300 IN A 10.0.2.21 nimrod.cosc.tu. 300 IN A 10.0.2.22 olympic.cosc.tu. 300 IN A 10.0.2.23 orion.cosc.tu. 300 IN A 10.0.2.24 persephone.cosc.tu. 300 IN A 10.0.2.25 pollux.cosc.tu. 300 IN A 10.0.2.26 roanoke.cosc.tu. 300 IN A 10.0.2.27 talos.cosc.tu. 300 IN A 10.0.2.28 theseus.cosc.tu. 300 IN A 10.0.2.29 vesta.cosc.tu. 300 IN A 10.0.2.30 zeus.cosc.tu. 300 IN A 10.0.2.31 cosc.tu. 300 IN SOA acheron.cosc.tu. zathras.cosc.tu. 3 300 180 1800 300 ;; Query time: 5 msec ;; SERVER: 10.0.2.100#53(10.0.2.100) ;; WHEN: Sat Jan 25 21:21:03 2014 ;; XFR size: 39 records (messages 1, bytes 958)
From this, we see that we have enumerated the entire network! We did so by asking the DNS server for a full zone transfer.
There is some nice (old) documentation for dig at http://www.madboa.com/geek/dig/
Security
Zone Transfers
Why is allowing a zone transfer a bad idea?
Suppose that we want the master name server to only allow zone transfers to the slave, which we have set at 10.0.2.101. Then in the zone section of /etc/named.conf we add the allow-transfer directive, and specify a semicolon denumerated list of allowable addresses that can request a zone transfer.
Adding this to our existing file, we end up with a named.conf file for the master like
// BIND Configuration File options { directory "/var/named"; }; zone "cosc.tu" in { type master; file "db.cosc.tu"; allow-transfer {10.0.2.101;} ; }; zone "2.0.10.in-addr.arpa" in { type master; file "db.10.0.2"; allow-transfer {10.0.2.101;} ; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; }; include "/etc/rndc.key"; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; };
Once this is implemented, our zone transfer request from the attacker’s Kali box will fail:
root@kali32:~# dig @10.0.2.100 cosc.tu axfr ; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @10.0.2.100 cosc.tu axfr ; (1 server found) ;; global options: +cmd ; Transfer failed.
The slave should not be transferring its zone to anyone, so we secure it:
options { directory "/var/named/slaves"; }; zone "cosc.tu" in { type slave; file "bak.cosc.tu"; masters {10.0.2.2; }; allow-transfer{ none; }; }; zone "2.0.10.in-addr.arpa" in { type slave; file "bak.10.0.2"; masters {10.0.2.2; }; allow-transfer{ none; }; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; }; include "/etc/rndc.key"; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; };
Ran into a little trouble while I was working on BIND with forwarders; nslookup of an address that would be forwarded to another DNS was working on the local network, but as soon as I was querying from outside the network (specifically on nagios), I was getting the error: ” server can’t find x.x.x.10.in-addr.arpa name: REFUSED”.
If you turn query logging on, in the /var/messages file you’ll see something like “clientip#blahblah: query (cache) ‘hostname/A/IN’ denied.”
After some research and help from Dr. O’Leary, we found that the issue is in the named.conf file. In order for the forwarding process to work properly when querying from outside a network, we need to allow recursion. In order to do this, all we have to do is add an extra line in the ‘options’ section of our BIND named.conf. The line is:
” allow-recursion { any; }; “
recursion is off, obviously, so the dns server can’t be used for DDoS attack via DNS amplification…
“attacker sending a DNS name lookup request to an open DNS server with the source address spoofed to be the target’s address. When the DNS server sends the DNS record response, it is sent instead to the target. Attackers will typically submit a request for as much zone information as possible to maximize the amplification effect. In most attacks of this type observed by US-CERT, the spoofed queries sent by the attacker are of the type, “ANY,” which returns all known information about a DNS zone in a single request. Because the size of the response is considerably larger than the request, the attacker is able to increase the amount of traffic directed at the victim. By leveraging a botnet to produce a large number of spoofed DNS queries, an attacker can create an immense amount of traffic with little effort. Additionally, because the responses are legitimate data coming from valid servers, it is extremely difficult to prevent these types of attacks. While the attacks are difficult to stop, network operators can apply several possible mitigation strategies.”
Two really helpful tools for verifying bind zones and configurations:
named-checkzone
named-checkconf
These tools will report errors, some warnings, or an “ok” depending on how successful you were in creating these files.