Faulbaer's Schlafmulde :: english :: hacking :: djbdns + svn + cron = dns replication
2010.08.23, 08:16

djbdns + svn + cron = dns replication

I'm sure this has been done before - probably even pretty often - but since I couldn't find anything on how to make it work properly without spending too much time on it, I decided to write up what I did there.

I wanted to replicate my dns-database between several djbdns installations on different operating systems. When I first set this up, I went for ssh without password. there were some minor issues with that:

- no passphrase (must be something spiritual but I don't like that)
- without rsync involved: one-way only (as in master->slave, slave...)
- with rsync involved still not optimal to keep env, root etc. apart
- no versioning, no roll-back, no safety

on the plus side it's been super-easy to set it up, though.

since I recently bought into a new server plan and just a month before found and old wrap-pc that had been configured as openbsd-dns-server years ago, that was still working, I decided to put some more brain into the matter. these were the results I was looking for:

- it shouldn't matter where to change configuration
- shouldn't be needed to log into the dns server ever again
- versioning/backup/roll-back should be an option
- only parts of the directory should be replicated/distributed
- take into consideration that not every server is the same
- server should pull the updates
- encrypted communication
- authentication required for at least writing

the main trigger was going to be cron like before but I had to find something for allmy other needs. subversion was the solution.

I finally went for a subversion repository with different env-directories for each server as there are IP-address as well as the path to the root-directory configured and those can differ from server to server.

the svn is behind an apache2 just because it's already been there and I couldn't be bothered to make svnserver fly with ssl and authentication. apache works just fine. so we have svn behind apache/ssl and that part took my rusty brain two attempts and maybe an hour to get it working properly. I'm getting too old for this stuff.

the configuration of the servers didn't take much longer and finally writing a script for cron with all the necessary environment variables took another two hours. I bet every half-way routined administrator finishes this in less than an hour.

now let's talk source (and yes, I'm perfectly aware of there being room for improvement - so just let me know if you find something, will you?)

since djbdns/tinydns has become part of the even debian lenny distribution I think you will find the basic setup instructions for your favorite flavor of linux/unit real quick on any major search-engine. so let's dive into the specifics of my setup, will we?

first of all I'm kind of a control-freak when it comes to my servers. I didn't really like to have all domains on one data-file and decided to add a directory for configurations I'd later just "cat > data". also I prepared some files I was going to work with later.

cd /service/tinydns/root/
mkdir data.d
touch tosses.info.data
touch lsrv.net.data
touch make.sh
touch svnup.sh

I went on configuring my .data files like I'd do it for a regular tinydns data file. to assemble the data file into the root directory, I just hacked a little make.sh script like this:

vim make.sh

echo # This file will be generated by $DATAD/make.sh > $ROOT/data
cat $DATAD/*.data >> $ROOT/data
chmod +x make.sh
svn add make.sh
svn ci -m "build your data from data.d with make.sh"

my dnsservers were half-way done. next up had to be the subversion configuration at the svn-server as well as at the dns-servers.

at the subversion server I made a repository just for the dns servers. into that repository I made some directories and finally I added some basic auth ssl configuration to the apache setup:

mkdir -p /var/svn/repositories
chown www:www /var/svn/repositories
su www -
svn create /var/svn/repositories/dns
svn mkdir --parents /var/svn/repositories/dns/tinydns/root/data.d
svn mkdir --parents /var/svn/repositories/dns/tinydns/ns1/env
svn mkdir --parents /var/svn/repositories/dns/tinydns/ns2/env
svn mkdir --parents /var/svn/repositories/dns/tinydns/ns3/env

now I had the directories for data, data.cdb and the .data files as well as env directories for each of my dns servers.

the apache2 configuration was pretty simple as well. after enabling ssl and configuring the ports as well as the virtual hosts, I added the site configurations for my dns repository as follows as root:

vim /etc/apache2/sites_available/svn.tosses.info

  ServerName svn.tosses.info
  ServerAdmin svn@tosses.info
  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl.crt
  SSLCertificateKeyFile /etc/apache2/ssl.key
  Alias /svn/ /var/svn/repositories/
  <Location /svn>
    DAV svn
    SVNParentPath /var/svn/repositories
  <Directory /var/svn/repositories/dns>
    AuthType Basic
    AuthName DNS
    AuthUserFile /etc/apache2/htpasswd.svn
    require valid-user
    order deny,allow
    deny from all
    satisfy any
  ErrorLog /var/log/svn.tosses.info-error.log
  CustomLog /var/log/svn.tosses.info-access.log common
htpasswd -c /etc/apache2/htpasswd.svn dns

after a graceful restart I could access the repository and see the directories I had made before. my work on the svn-server was done.

back on the (till then) main dns server I checked out the empty directories and started adding files to the svn:

cd /service/tinydns/env
svn co https://svn.tosses.info:443/svn/dns/ns1/env .
svn add IP ROOT
svn ci -m "IP and ROOT configuration for ns1 added"
cd /service/tinydns/root
svn co https://svn.tosses.info:443/svn/dns/root .
svn add data.d data.cdb
svn ci -m "general data.d directory and data.cdb database for all dns"

so far so good. for cron I still needed an svn update script including the necessary variables. those scripts needed to be executable and I had to add svnup.sh to the crontab:

cd /service/tinydns/root/data.d
vim svnup.sh

cd /service/tinydns/root
svn update
chmod +x svnup.sh
svn add svnup.sh
svn ci -m "now svnup.sh will update the svn"

crontab -e

* * * * * /service/tinydns/data.d/svnup.sh > /dev/null

for the other two servers all I had to do was to repeat the checkout of their own env directories and in the root directory I needed to remove data, data.d and data.cdb before a checkput could be successful. but those had to go anyway:

on ns2

cd /service/tinydns/env
svn co https://svn.tosses.info:443/svn/dns/ns2/env .
svn add IP ROOT
svn ci -m "IP and ROOT configuration for ns2 added"
cd /service/tinydns/root
rm -Rf data.d data data.cdb
svn co https://svn.tosses.info:443/svn/dns/root .

crontab -e

* * * * * /service/tinydns/data.d/svnup.sh > /dev/null

on ns3

cd /service/tinydns/env
svn co https://svn.tosses.info:443/svn/dns/ns3/env .
svn add IP ROOT
svn ci -m "IP and ROOT configuration for ns3 added"
cd /service/tinydns/root
rm -Rf data.d data data.cdb
svn co https://svn.tosses.info:443/svn/dns/root .

crontab -e

* * * * * /service/tinydns/data.d/svnup.sh > /dev/null

now every minute every server tries to update from the repository. sure, that's a lot and maybe I even go back to five minutes as checking interval.

the only thing that might become an issue is if I change files in data.d on several servers without immediate check-in. but there are enough ways to fix this in svn.

Faulbaer (I hope I haven't forgotten anything)tt

add a comment