02- DNS & Bind
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
Hostname
Start by changing the name of your host. You do this by editing the file /etc/sysconfig/network and modify the HOSTNAME line. Be sure to enter
the FQDN here; in my example, I will call the host “shades” with parent domain “cosc.tu” giving me the file:
NETWORKING=yes HOSTNAME=shades.cosc.tu
Documentation is available in usr/share/doc/initscripts-<version-number>/sysconfig.txt.
You also need to modify the entries in the file /etc/hosts; in particular you need to make sure that all of the aliases for 127.0.0.1 are appropriate. As an example, we can set that file to look like
127.0.0.1 localhost localhost.localdomain shades shades.cosc.tu ::1 localhost localhost.localdomain shades shades.cosc.tu
so that any of the four names “localhost”, “localhost.localdomain”, “shades” and “shades.cosc.tu” will refer to 127.0.0.1
At this point, you can reboot the machine. Mind you, this is not strictly necessary, as the changes can also be made live by using the hostname command. Noe that changes made that way only persist until a reboot when the configuration files are re-read. Given that we are going to do a lot of work with DNS and hostnames, it is better is you simply reboot now and verify that your changes have been made correctly.
Static networking
Because we want to use this system as our master DNS server, it is imperative that it have a static IP address.
Edit the file /etc/sysconfig/network-scripts/ifcfg-eth0 along the following lines
DEVICE="eth0" ONBOOT="yes" BOOTPROTO="none" HWADDR="00:0C:29:C2:89:83" NETMASK="255.255.255.0" IPADDR="192.168.1.60" GATEWAY="192.168.1.1" TYPE="Ethernet" USERCTL="no" IPV6INIT="no" PEERDNS="no"
where (of course) you change the addresses to match the particulars of your network. Notice that we have decided to disable IPv6 networking for this host. Remember not to use spaces around the equal signs. Documentation for this file is available in usr/share/doc/initscripts-<version-number>/sysconfig.txt
At this point, you have a number of options. The slowest way is to simply reboot the machine. You can also run the script
[root@shades ~]# /etc/init.d/network restart
which is probably the best way to proceed.
Note also that changes can be made to the IP of a running system with the ifconfig command (See man ifconfig for details). Be sure to also change the gateway if necessary using the route command (e.g. # route add default gw 192.168.1.1); see man route.
DNS server with BIND: The basics
The first step is always to verify that BIND is installed; run
[root@shades ~]# named -v BIND 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.1
In the virtual machines provided to the class, you will find that the installed version should be a Red Had modified version of 9.7.3
Note that the BIND service is chrooted by default on some versions of CentOS (e.g. CentOS 5.5), so the directory structure in our VM and in this document might be slightly different than what you might see if you look for help online at other locations.
The Forward Zone
We will start with one top level domain- “cosc.tu”. This DNS server will respond to requests for “hostname.cosc.tu”. This zone is called a forward zone, because it maps names to addresses.
Create the zone file /var/named/db.cosc.tu, and set it up as follows:
; $TTL 3h ; cosc.tu. IN SOA shades.cosc.tu. vimes.shades.cosc.tu. ( 1 ; Serial 3h ; Refresh after 3 hours 1h ; Retry after 1 hour 1w ; Expire after 1 week 1h ) ; Negative TTL of one week ; ; Name Servers ; cosc.tu. IN NS shades.cosc.tu. ; ; Host Addresses ; localhost.cosc.tu. IN A 127.0.0.1 gw.cosc.tu. IN A 192.168.1.1 shades.cosc.tu. IN A 192.168.1.60 dimwell.cosc.tu. IN A 192.168.1.61 longwall.cosc.tu. IN A 192.168.1.62 scours.cosc.tu. IN A 192.168.1.63 hippo.cosc.tu. IN A 192.168.1.64 smallgods.cosc.tu. IN A 192.168.1.65 naphill.cosc.tu. IN A 192.168.1.66 dollysisters.cosc.tu. IN A 192.168.1.67 unrealestate.cosc.tu. IN A 192.168.1.68 dragonslanding.cosc.tu. IN A 192.168.1.69 isleofgods.cosc.tu. IN A 192.168.1.70 ; ; Aliases ; dns.cosc.tu. IN CNAME shades.cosc.tu.
We adopt the naming convention for bind configuration files in /var/named that they have the form db.namespace for forward records. This is not required however, and we could give this file any name we wish.
Reading the file, we first see that the default time to live (TTL) is set to three hours. This is the amount of time that these records could be cached. Because our is a classroom environment where we expect things to change rapidly, we choose the very small value of three hours.
Next in the file comes the SOA record. When reading the file, be sure to notice the periods after the hostnames. These are required.
The first line has the form
domain_name IN SOA dns_server_name mail_address_of_admin
where the ‘@’ in the mail address has been replaced by another ‘.’ Here IN = Internet- this is the class of data in this file, while SOA = Start of authority record. Only one SOA can be in a zone datafile. SOA means that this file is authoritative for this zone.
The file then sets up the Internet (IN) namerserver records (NS); these are all of the nameservers for this zone. More than one nameserver can be specified
Next, the file sets up the host name records, or address records (A) for each host.
Finally, the file ends with a list of aliases records (CNAME). This configuration file gives a second name (dns.cosc.tu) to the name server (shades.cosc.tu).
It should be noted that the CentOS 6.2 VM provided to the class has 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.
The Reverse Zone
Now we set up the address to name mappings, this is called a reverse zone.
Create the file /var/named/db.192.168.1 as follows
$TTL 3h ; 1.168.192.in-addr.arpa. IN SOA shades.cosc.tu. vimes.shades.cosc.tu. ( 1 ; Serial 3h ; Refresh after 3 hours 1h ; Retry after 1 hour 1w ; Expire after 1 week 1h ) ; Negative TTL of one week ; ; Name Servers ; 1.168.192.in-addr.arpa. IN NS shades.cosc.tu. ; ; Address records ; 1.1.168.192.in-addr.arpa. IN PTR gw.cosc.tu. 60.1.168.192.in-addr.arpa. IN PTR shades.cosc.tu. 61.1.168.192.in-addr.arpa. IN PTR dimwell.cosc.tu. 62.1.168.192.in-addr.arpa. IN PTR longwall.cosc.tu. 63.1.168.192.in-addr.arpa. IN PTR scours.cosc.tu. 64.1.168.192.in-addr.arpa. IN PTR hippo.cosc.tu. 65.1.168.192.in-addr.arpa. IN PTR smallgods.cosc.tu. 66.1.168.192.in-addr.arpa. IN PTR naphill.cosc.tu. 67.1.168.192.in-addr.arpa. IN PTR dollysisters.cosc.tu. 68.1.168.192.in-addr.arpa. IN PTR unrealestate.cosc.tu. 69.1.168.192.in-addr.arpa. IN PTR dragonslanding.cosc.tu. 70.1.168.192.in-addr.arpa. IN PTR isleofgods.cosc.tu.
We again use a naming convention; since this is a reverse zone, we name it db.netaddr, where netaddr is the address of the network.
Like the forward zone, we have set the time to live to three hours.
The remaining records are similar to the db.class file. Numerical addresses are in reverse order, and ended with “.in-addr.arpa.” The primary difference here is that now we use pointer (PTR) records rather than address (A) records.
Loopback
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 3h ; 0.0.127.in-addr.arpa. IN SOA shades.cosc.tu. vimes.shades.cosc.tu. ( 1 ; Serial 3h ; Refresh after 3 hours 1h ; Retry after 1 hour 1w ; Expire after 1 week 1h ) ; Negative TTL of one week ; 0.0.127.in-addr.arpa. IN NS shades.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.conf, 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 "1.168.192.in-addr.arpa" in { type master; file "db.192.168.1"; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; };
Running and Testing
To start your server, run
[root@shades etc]# /etc/init.d/named start
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.
As your first test, from the DNS server, run nslookup “hostname” for a hostname that appears in your records; you should get the correct response. Do the same for the an IP address.
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.
Clients
Now that the server is configured, we need to set our clients to use it. On a typical linux machine, add the line
nameserver 192.168.1.60
(substitute the correct address!) to the file/etc/resolv.conf. The details of the structure of /etc/resolv.conf can be found by checking man resolv.conf
The situation is slightly different however, with the network manager for CentOS 6.2. The file /etc/resolv.conf is modified based on the contents of the file /etc/sysconfig/network-scripts/ifcfg-eth0. In fact, changes made to that file are reflected in the /etc/resolv.conf almost immediately. Conversely, changes made directly to /etc/resolv.conf will be lost whenever a change is made to /etc/sysconfig/network-scripts/ifcfg-eth0. Thus, rather than change /etc/resolv.conf, the preferred approach is to modify /etc/sysconfig-network-scripts/ifcfg-eth0 to add lines for the DNS server(s) and the search domain as follows:
DEVICE="eth0" ONBOOT="yes" BOOTPROTO="none" HWADDR="00:0C:29:3C:21:1E" NETMASK="255.255.255.0" IPADDR="192.168.1.61" GATEWAY="192.168.1.1" TYPE="Ethernet" USERCTL="no" IPV6INIT="no" PEERDNS="no" DNS1="192.168.1.60" DNS2="192.168.1.61" DOMAIN="cosc.tu"
Do so, and the contents of the file /etc/resolv.conf become
# Generated by NetworkManager search cosc.tu nameserver 192.168.1.60 nameserver 192.168.1.61
The precise method to configure a Windows machine varies by the type of Windows, but in general go through control panel, to network connections, to TCP/IP and make the corresponding change in the GUI.
Setting up a slave nameserver
Why do we want to set up a second nameserver? 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 “dimwell” and the IP address 192.168.1.61. Note that this name/IP combination is already included in DNS zone data for our master nameserver.
The slave named.conf file
First we create a new named.conf file as follows:
// BIND Configuration File options { directory "/var/named/slaves"; }; zone "cosc.tu" in { type slave; file "bak.cosc.tu"; masters {192.168.1.60; }; }; zone "1.168.192.in-addr.arpa" in { type slave; file "bak.192.168.1"; masters {192.168.1.60; }; }; 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
Check that the zone files have been downloaded and now reside in the directory /var/named/slaves
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.
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@shades ~]# /etc/init.d/named status rndc: neither /etc/rndc.conf nor /etc/rndc.key was found named (pid 3439) 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@shades ~]# rndc-confgen > rndcconf
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 "C/TmciFpYhffK/Lu77gwfA=="; }; 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 "C/TmciFpYhffK/Lu77gwfA=="; # }; # # 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 contents
key "rndc-key" { algorithm hmac-md5; secret "C/TmciFpYhffK/Lu77gwfA=="; };
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@shades etc]# ls -l /etc/rndc.key -rw-r--r--. 1 root root 87 Jan 28 18:19 /etc/rndc.key
Not so secret. Still, a little change, and we should be good to go
[root@shades etc]# chmod o-r /etc/rndc.key [root@shades etc]# ls -l /etc/rndc.key -rw-r-----. 1 root root 202 Jan 28 18:15 /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@dimwell etc]# chown root:named /etc/rndc.key [root@dimwell etc]# ls -l /etc/rndc.key -rw-r-----. 1 root named 89 Jan 28 19:06 /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 "1.168.192.in-addr.arpa" in { type master; file "db.192.168.1"; }; 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 “C/TmciFpYhffK/Lu77gwfA==”. 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.
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. As an example, we could run
[root@shades ~]# rndc status version: 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.1 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
to find the current status of the server. Other commands include
- reload: Reload the configuration file or a single zone (if the zone is also specified).
- reconfig: Reload the configuration file and new zones (only)
- refresh zone:Schedules an immediate refresh for the specified zone
- stop:Stop the server, saving any pending updates
- halt:Stop the server, without saving any pending updates
Take a look at the man page for rndc. You will discover that rndc can also be used to configure remote servers by specifying the appropriate server and port. To do so however, the server must be configured to listen on more than just localhost as we have done so.
Updating the data
Suppose that the data for a zone is changed on the master. How does the slave know to update its data? The answer is through the use of the serial number. If the serial number on the master is larger than the serial number for the slave, then the slave will know that it needs to update its data from the slave. Beyond this, there is no requirement that serial numbers be e.g. consecutive.
To reload the zone data on the master, you can restart the named daemon, or simply run
[root@shades ~]# rndc reload server reload successful
The changes on the master will automatically be propgated to the slaves. This is governed by our refresh interval- which in our example files is set to 3 hours. If this is too long to wait, this can be done manually using rndc. Suppose that we have modified the zone file for cosc.tu on the master; then on the slave if we run
[root@dimwell ~]# rndc retransfer cosc.tu
the zone file will be updated accordingly. Note that the retransfer command pays no attention to the serial number- if you run a retransfer, the zone will be transferred, regardless of the serial numbers. The refresh command for rndc will also schedule an immediate transfer, but will respect the serial numbers.
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. But- 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 *.class.tu, while team 2 is using the namespace *.cosc.tu. We also suppose that the nameserver for team 2 is located at 192.168.2.24. Then in the named.conf file for team 1, we add the lines:
zone "class.tu" in { type forward; forwarders {192.168.2.80; }; };
Now when a machine that is using the team 1 DNS server is asked for an address from team 2- say mybox.tu- that request will be forwarded to the nameserver 192.168.2.24 maintained by team 2, and the nameserver for team 1 will cache the reply and send the result back to the requestor.
Exercises- Set Up
Build your own CentOS based DNS server. Include records for the server, a slave server (to be built), a windows machine, and the class gateway (10.0.x.254).
Set up a slave server. Verify that the slave server is able to perform the zone transfer to get its records.
Set up the server, the slave, and the windows machine to use your DNS server. Verify that they work. Verify that the master can be shut down and that the slave will still serve data.
Exercises- Common DNS commands
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@shades ~]# nslookup > set all
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
From within the nslookup shell, you can get information about a host by simply giving the name like the following:
[root@shades ~]# nslookup > shades Server: 192.168.1.60 Address: 192.168.1.60#53 Name: shades.cosc.tu Address: 192.168.1.60
Do so. Do the same with an IP address, e.g.
[root@shades ~]# nslookup > 192.168.1.66 Server: 192.168.1.60 Address: 192.168.1.60#53 66.1.168.192.in-addr.arpa name = naphill.cosc.tu.
Another important command to be comfortable using is dig.
$ dig “hostname.domain”
It is simplest to use when your resolv.conf uses the nameserver you want to test. Try
[root@shades ~]# dig -x 192.168.1.66 ; <> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.1 <> -x 192.168.1.66 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34150 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 ;; QUESTION SECTION: ;66.1.168.192.in-addr.arpa. IN PTR ;; ANSWER SECTION: 66.1.168.192.in-addr.arpa. 10800 IN PTR naphill.cosc.tu. ;; AUTHORITY SECTION: 1.168.192.in-addr.arpa. 10800 IN NS shades.cosc.tu. ;; ADDITIONAL SECTION: shades.cosc.tu. 10800 IN A 192.168.1.60 ;; Query time: 1 msec ;; SERVER: 192.168.1.60#53(192.168.1.60) ;; WHEN: Sun Jan 29 15:26:19 2012 ;; MSG SIZE rcvd: 109
It is possible to use dig to pull the entire zone from a host. For example, fire up a Backtrack machine; you don’t even need to set the resolver (etc/resolv.conf). Point dig at your namerserver as follows:
root@bt:~# dig @192.168.1.60 cosc.tu axfr ; <> DiG 9.7.0-P1 <> @192.168.1.60 cosc.tu axfr ; (1 server found) ;; global options: +cmd cosc.tu. 10800 IN SOA shades.cosc.tu. vimes.shades.cosc.tu. 4 10800 3600 604800 3600 cosc.tu. 10800 IN NS shades.cosc.tu. dimwell.cosc.tu. 10800 IN A 192.168.1.61 dns.cosc.tu. 10800 IN CNAME shades.cosc.tu. dollysisters.cosc.tu. 10800 IN A 192.168.1.67 dragonslanding.cosc.tu. 10800 IN A 192.168.1.69 gw.cosc.tu. 10800 IN A 192.168.1.1 hippo.cosc.tu. 10800 IN A 192.168.1.64 isleofgods.cosc.tu. 10800 IN A 192.168.1.70 localhost.cosc.tu. 10800 IN A 127.0.0.1 longwall.cosc.tu. 10800 IN A 192.168.1.62 naphill.cosc.tu. 10800 IN A 192.168.1.66 scours.cosc.tu. 10800 IN A 192.168.1.63 shades.cosc.tu. 10800 IN A 192.168.1.60 smallgods.cosc.tu. 10800 IN A 192.168.1.65 unrealestate.cosc.tu. 10800 IN A 192.168.1.68 cosc.tu. 10800 IN SOA shades.cosc.tu. vimes.shades.cosc.tu. 4 10800 3600 604800 3600 ;; Query time: 23 msec ;; SERVER: 192.168.1.60#53(192.168.1.60) ;; WHEN: Sun Jan 29 18:30:09 2012 ;; XFR size: 17 records (messages 1, bytes 463)
From this, we see that we have enumerated the entire network!
In the example above, we could try
There is some nice (old) documentation for dig at http://www.madboa.com/geek/dig/
Security
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 192.168.1.61. 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 { 192.168.1.61; }; }; zone "1.168.192.in-addr.arpa" in { type master; file "db.192.168.1"; allow-transfer { 192.168.1.61; }; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; }; zone "class.tu" in { type forward; forwarders {192.168.2.80; }; }; 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 Backtrack box will fail:
root@bt:~# dig @192.168.1.60 cosc.tu axfr ; <> DiG 9.7.0-P1 <> @192.168.1.60 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:
// BIND Configuration File options { directory "/var/named/slaves"; }; zone "cosc.tu" in { type slave; file "bak.cosc.tu"; masters {192.168.1.60; }; allow-transfer{ none; }; }; zone "1.168.192.in-addr.arpa" in { type slave; file "bak.192.168.1"; masters {192.168.1.60; }; allow-transfer{ none; }; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; }; zone "class.tu" in { type forward; forwarders {192.168.2.80; }; }; include "/etc/rndc.key"; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; };
Now this approach solves the problem of unauthorized hosts grabbing our zone files, but one problem remains- what would happen if an impostor spoofed the IP address of the master, and sent a malicious set of zone data to the slave? Then the attacker could redirect traffic that used the data provided by the slave.
To avoid this problem, we will take advantage of transaction signatures, or TSIG. We start by creating a key that we will share between the master and the slave. On the master, we run
[root@shades ~]# dnssec-keygen -a HMAC-MD5 -b 128 -n HOST shades.cosc.tu Kshades.cosc.tu.+157+04598
This generates two files in the current directory:
- Kshades.cosc.tu.+157+04598.key
- Kshades.cosc.tu.+157+04598.private
We can examine their contents:
[root@shades ~]# cat Kshades.cosc.tu.+157+04598.key shades.cosc.tu. IN KEY 512 3 157 KlK46jAKc13AhjVSttLZCA== [root@shades ~]# cat Kshades.cosc.tu.+157+04598.private Private-key-format: v1.3 Algorithm: 157 (HMAC_MD5) Key: KlK46jAKc13AhjVSttLZCA== Bits: AAA= Created: 20120130003230 Publish: 20120130003230 Activate: 20120130003230
With this data in hand, we start by creating a file, which we will call /etc/named.keys.conf with contents:
key tsig.shades.cosc.tu { algorithm hmac-md5; secret "KlK46jAKc13AhjVSttLZCA=="; };
Note that the secret here is just the secret that we created with the dnssec-keygen command above.
Like other secrets, we do not want this to be world readable; so we make the necessary changes:
[root@shades etc]# ls -l /etc/named.keys.conf -rw-r--r--. 1 root root 95 Jan 29 16:45 /etc/named.keys.conf [root@shades etc]# chmod o-r /etc/named.keys.conf [root@shades etc]# chown root:named /etc/named.keys.conf [root@shades etc]# ls -l /etc/named.keys.conf -rw-r-----. 1 root named 95 Jan 29 16:45 /etc/named.keys.conf
We then add another include line to /etc/named.conf
include "/etc/named.keys.conf";
Now we modify the allow-transfer directive so that now it calls for the key we just defined; the result is the following named.conf on the master:
// BIND Configuration File options { directory "/var/named"; }; zone "cosc.tu" in { type master; file "db.cosc.tu"; allow-transfer { key tsig.shades.cosc.tu; }; }; zone "1.168.192.in-addr.arpa" in { type master; file "db.192.168.1"; allow-transfer { key tsig.shades.cosc.tu; }; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; }; zone "class.tu" in { type forward; forwarders {192.168.1.80; }; }; include "/etc/rndc.key"; include "/etc/named.keys.conf"; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; };
Now we head over to the slave. We again create the file /etc/named.keys.conf with the identical contents, change its permissions, and include in /etc/named.conf. Then we adjust the masters directive to require the signature; this yields the following /etc/named.conf for the slave:
// BIND Configuration File options { directory "/var/named/slaves"; }; zone "cosc.tu" in { type slave; file "bak.cosc.tu"; masters {192.168.1.60 key tsig.shades.cosc.tu; }; allow-transfer{ none; }; }; zone "1.168.192.in-addr.arpa" in { type slave; file "bak.192.168.1"; masters {192.168.1.60 key tsig.shades.cosc.tu; }; allow-transfer{ none; }; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; }; zone "class.tu" in { type forward; forwarders {192.168.1.80; }; }; include "/etc/rndc.key"; include "/etc/named.keys.conf"; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; };
Be sure to test your results!
Errors will not, in general be thrown by the scripts or tools like rndc; you will need to look at the logs (/var/log/messages). Don’t forget to reload your configuration file or restart named if you make changes.
Exercise
Set up a functioning DNS environment. It should
- Have a master
- Have a slave
- Correctly forward queries aimed at the domain of one of your teammates
- Not allow arbitrary zone transfers
- Use TSIG to ensure security of zone transfers from the master to the slave
another great reference that has an entire book, setup as a website. It covers concepts and terminology indepth and at a high level, all while staying organized and easy to understand
http://www.zytrax.com/books/dns/