Advertisment

Sunday, 30 March 2014

Update Zone Files

Update Zone Files

Now that we have the zone files entered into the slave DNS server successfully, the zone files need to be populated with current information from the master DNS server. There are a number of ways to do that; AXFR (or IXFR), rsync, scp, etc. Setting up any of those methods is an involved process, and they all work (some better than others), but I’ve found rsync to be the most satisfactory solution for updating zone files.

Before starting, confirm that both the master DNS server and the slave DNS server machines have the latest rsync installed.

# yum install rsync

On the master DNS server machine, create a user that has a password and login access. Using webmin you can click the System icon at the top and then click the Users and Groups icon. Click the “Create a new user” link. Fill it out like this.

Also, farther down the page next to “Primary group” select “Existing group” and enter named, like this.

Click the Create button at the bottom.

Determine where your zone files are located in your master DNS server. Those are usually in one of these two locations.

/var/named/
/var/named/chroot/var/named/

If you are in the correct directory you will see individual files for each zone you maintain. The file naming convention is simply the domain name that the zone services.

On the slave DNS server machine, test rsync by logging into SHH as root and issuing the following command. This step is more than just a test, since you must login to rsync manually at least once to add your remote server to the “allow” list before a non-human login is allowed.

# rsync -avz -e ssh dnsdenver@example.com:/var/named /var/named/slaves/

Where “dnsdenver” is the user you created in the master DNS machine and example.com is the domain name (or IP address) of your master DNS server. The first /var/named entry is the location in your master DNS server where the zone files are located, and /var/named/slaves/ is the location in the slave DNS server where you want the zone files to be replicated.

Note that if you are using a non-standard SSH port (555 in this example) that you will need to enter the command like this:

# rsync -avz -e "shh -p 555" dnsdenver@entomy.com:/var/named/ /var/named/slaves/dallas/

The test run will still ask for the password of the user, which you will need to provide, but we’ll take care of automating the process later. Right now you just want to get your source and target directories doing exactly what you want them to do. That is, to make sure that rsync is finding the zone files in the master DNS server machine, and then updating the zone files in the slave DNS server machine where you want them to go. Test run rsync as many times as you need to in order to get it working right.

Note that rsync might be moving some sub directories to the slave DNS server machine that you don’t need. Don’t worry about that now, we’ll exclude those later.
Once you are satisfied that rsync is doing exactly what you want it to do, we’ll move-on make rsync run without user interaction by installing a key. On the slave DNS server machine, login to SSH as root and issue the following commands.

IMPORTANT: Don’t enter your password when prompted. If you enter your password rsync will still require user interaction. Just press Enter when prompted for a password.

# mkdir /root/rsync # ssh-keygen -t dsa -b 1024 -f /root/rsync/mirror-rsync-key
Now copy the key you just created to the master DNS server machine.
# scp /root/rsync/mirror-rsync-key.pub dnsdenver@example.com:/home/dnsdenver/

If you are using an alternate ssh port, such as 522 suggested earlier in this paper, then you would need to enter that command this way:

# scp –P 522 /root/rsync/mirror-rsync-key.pub dnsdenver@example.com:/home/dnsdenver/
If you have difficulty with the above command for some reason (perhaps a firewall issue from a non-standard SSH port) don’t fret over it too much. Use whatever method you wish to transfer the file, just make sure that it’s in the home directory for the user you created in the master DNS server machine.

On the master DNS server machine, login to SSH as the user you created (dnsdenver in my example) but NOT AS ROOT. You MUST login as the user you created. Enter the following commands.

# mkdir ~/.ssh # chmod 700 ~/.ssh # mv ~/mirror-rsync-key.pub ~/.ssh/ # cd ~/.ssh # touch authorized_keys # chmod 600 authorized_keys # cat mirror-rsync-key.pub >> authorized_keys
Your key should be installed in the master DNS machine and is now ready for testing.
On the slave DNS server machine, login to SSH as root and issue this more detailed rsync command (it is all one command, but wrapping to a new line).

rsync -avz --delete --exclude=**/data --exclude=**/slaves -e "ssh -p 555 -i /root/rsync/mirror-rsync-key" dnsupdate@entomy.com:/var/named /var/named/slaves/dallas

Note that we’ve added a few things since we tested rsync earlier. The “--delete” entry tells rsync to remove any files that it finds on the slave DNS server that are no longer on the master DNS server. The “--exclude=” entries tell rsync to ignore the /data and /slaves directories, so they won’t be transferred any longer. The “ssh” commands between the double-quotes tells SSH to use the non-standard SSH port 555, and to authenticate using the specified key. If you are using the standard SSH port of 22 then you can enter the “ssh” entry like this.

"ssh -i /root/mirror-rsync-key"

The rest of the entries should be entered exactly as what worked well for you during the testing phase. If the command does what you want it to do, and runs without asking for a password, then you are ready to automate the process. To do that you will run the rsync to update zone file contents each time the zone file list is updated. We can do that by entering the final rsync command in the script that we wrote for the slave DNS server. In the example we called it getdallas and placed it in the following directory.

/var/named/chroot/var/named/slaves/

Edit the script with a text editor, adding the rsync command on a new line before the named restart command, so it looks like this.

Test run the script using SSH as root on the slave DNS machine, just to be sure everything works as it should. You don’t need to do anything else, since the cron job for that script was created in a previous step. You can run the scripts in the two machines as often as you wish, but bear in mind that the DNS server in the slave machine will be unavailable for the time it takes to restart named. Running it once or twice per hour should be more than adequate.

These steps are done in the Slave DNS server

These steps are done in the Slave DNS server

The objective of this section is to configure the slave DNS server to fetch a zone information file from the master DNS server, place the file in a location that is accessible to BIND, and then apply those zones to BIND by restarting the application. To do that you need to create a script.
Create a text file and paste the following code into it:

#!/bin/sh

wget http://entomy.com/dns/updatedenver.txt -O /var/named/chroot/var/named/slaves/dallas.conf
/etc/init.d/named restart

The wget statement fetches the file from the master DNS server, and then saves it as a file called dallas.conf in the specified location. You will need to edit the URL of the text file location to the actual web accessible location you put it in on the master DNS server. Likewise, edit the name and location of the .conf file to your liking. When done, save the file. I called the file getdallas, since my master DNS server is in Dallas, and saved it in the var/named/chroot/var/named/slaves/ directory, the same location as I put the .conf file.

Now open your named.conf file (normally found in /etc) and place this statement at the end of the file.

include "/var/named/chroot/var/named/slaves/dallas.conf";

You will need to edit the path and file name to match the location of the .conf file you specified in the script. Save the file. Also not that if BIND is running “chrooted” (as it is under Kloxo) that the path will be shortened to make the command look like this.

include "/var/named/slaves/dallas.conf";

Now login to SSH as root and create the .conf file so it can be written to by your script, editing for the proper path and file name, of course.

# touch /var/named/chroot/var/named/slaves/dallas.conf

Create the directory for the zone files to be created in, make the directory writable, and then restart BIND.

# mkdir /var/named/chroot/var/named/slaves/dallas/
# mkdir /var/named/chroot/var/named/slaves/dallas/named/
# chmod 777 /var/named/chroot/var/named/slaves/dallas/
# chown named:named /var/named/chroot/var/named/slaves/dallas/
# chmod 777 /var/named/chroot/var/named/slaves/dallas/named/
# chown named:named /var/named/chroot/var/named/slaves/dallas/named/ # /etc/rc.d/init.d/named restart
Of course, all of the above can be done a lot quicker & easier using the webmin file manager, but it works fine from the command prompt.
With those tasks done, test run the script from the command prompt.
/var/named/chroot/var/named/slaves/getdallas
With any luck, your output will look like this.
You can see from the output that the file was fetched, saved in the proper location, then named was restarted successfully.

Once you have the script running the way you want it to, create a cron job to run the script soon after the script on the master DNS server runs. Scheduling the scripts to run once or twice an hour is normally sufficient for redundant DNS.

Note that the zone files that were created from these scripts will be empty files. These scripts are only intended to make the slave DNS server aware of changes in the master DNS server zone listing. You will need to configure another solution to fetch the zone file contents, such as AXFR, rsync, or scp. However, it’s important to note that any zone files that existed in the slave DNS server before the script was run that already contained zone details will not be overwritten.

Secondary DNS

Secondary DNS

The previous tutorial described a DNS server on the same machine as the web server using a single IP address. That works just fine if all you are doing is hosting simple websites. In that case, a good argument can be made that if the web server goes down for some reason (along with the DNS server, most likely), that a secondary DNS server can’t help visitors get to your website because the web server is down anyway. And all of that is true.

Where it makes a difference is when you have clients who are counting on email that is handled by your server. So if you have a business that is hosting its email with you and your only DNS server is down, mail will be immediately returned to senders as a bad email domain. Obviously having email returned to customers would not be good for business. But if you had a secondary DNS server running someplace the sender’s email server will hold the email message until your email server comes back up, then try sending again.

So if your business reaches a point where you believe that a secondary DNS server is necessary, you need to consider a solution. If you only have a limited number of domains then you might consider a free service to host your secondary DNS. You might consider BuddyNS.com for that. It’s very good service, and you can host an unlimited number of DNS zones (domains) with them, but you will have to enter new domains manually.

If you are going to be running a hosting business where a lot of domains are likely to be created or deleted, particularly if you are going to have resellers who will be creating domains that you aren’t even aware of, then you need to find a more automated solution. To that end, I am going to provide an automated method of making the slave DNS server aware of new or deleted domains.

It’s important to understand that while BIND comes with the capability to automatically update zones, it does not have the capability to know when new zones are added in the master DNS server. The first part of this tutorial will be to take care of that by transferring a zone list to the slave server.