Navigation: home » linux » dnsreplicate

Secure djbdns zonefile replication

For many, djbdns provides a better solution for nameservers than BIND. However, if you have a group of servers all with data files that need to be shared between them, some custom scripting is needed. The author of djbdns suggests using rsync over SSH on this page, here we use SSH and public/private keys to automate replication zonefiles and updating of remote hosts.

Concepts

There are currently four scripts used to carry out this task, as well as a configuration file. It is assumed that a new user will be created on each of the machines who want to share their DNS data files, doing otherwise is a possible security risk.

There are two sets of hosts used, partners and trusted. A partner is a host that we will send our data file to, a trusted host is one who we will accept a data file from. This means we can send our zonefile to ns1.example.net, but we don’t necessarily want to host theirs. More information on configuring this is available below.

The scripts handle the task of accepting a new data file from a remote host and catenating all the information together to make a single, monolithic data file. The scripts also handle sending our data.host file to remote hosts that accept it.

Setting it up

Configuring the scripts to work is very easy, the instructions below should be all that is needed. If you have any questions, please feel free to contact me. All users should at least complete 1 and 2, most will also need to complete 3 and/or 4.

1. Installing the scripts

To install the scripts and make use of them on your DNS system, the steps below should be followed for each host that will be sharing or accepting data.

  1. Make a new user, in this example dnsreplicate, with a valid shell, preferably bash1).
  2. Make the user a home directory, for example /var/tinydns/dns or /home/dnsreplicate.
  3. Copy the scripts and sample dnsreplicate.cfg to the above directory.
  4. Create an SSH key for the user with no passphrase 2) and place it in ~/.ssh/id_dsa.
    # ssh-keygen -b 1024 -f /tmp/id_dsa -t dsa -C "DNS replication key for example.net"

  5. Edit dnsreplicate.cfg, following the instructions. Make sure you set local and that the same value appears in trusted!
  6. Move your local data file to ~dnsreplicate/zones/data.host, where host is the name in local.

2. The tinydns Makefile

By default, tinydns comes with a very simple Makefile to compile data.cdb. If you want the scripts to automatically make your data file from the collection of data.host files, the Makefile should be edited to look something like below:

update:
        /path/to/MakeData.sh
        make data.cdb

data.cdb: data
        /usr/bin/tinydns-data

Now, when make is run, the data files will be collated automatically and compiled to the tinydns format data.cdb.

3. Accepting data from others

For each host that will send us data, the following must be done:

  1. Create an entry in ~/.ssh/authorized_keys2 similar to the following:
    # Wibble key
    command="~/Accept.sh wibble",from="wibble.example.net",no-port-forwarding,no-pty ssh-dss AAAA...== DNS Replication Key - Wibble

    When a machine connects and offers the key above, data that is sent will be saved to data.wibble. Note that three security options are given, from=, no-port-forwarding and no-pty (see man 8 sshd). It is highly recommended these are used. If your key gets stolen, this will make it useless except from one host 3).

  2. Add the entry wibble to trusted in dnsreplicate.cfg, if this host’s file is to be considered when building our data for tinydns.

The remote host can now “push” data to our server over SSH. When their data is successfully received, the local tinydns file data.cdb will automatically be rebuilt.

4. Sending data to others

To send data to others, the requirements are:

  • A full SSH address (username@host) must appear in partners in dnsreplicate.cfg.
  • A key in ~/.ssh/id_dsa that the remote host will accept (as above).
  • A local data file, in zones/data.XXX, where XXX is whatever local is set to in dnsreplicate.cfg.

A local administrator can now run su - dnsreplicate -c ./Replicate.sh to send data to all the partners.

The scripts

A short explanation of each script is given below. The first two are not designed to be run from the command-line, the second two may be.

Accept.sh

This script should be run by SSH when a user logs in with a key. Data from a remote host is read in from stdin and compared to the provided MD5 sum, if it matches then the data is saved and the local DNS data file is rebuilt. This script is not designed to be run from the command-line.

MakeData.sh

This script handles building many data.host files into one single data file. It uses the list of trusted hosts to decide which are built into the local data file.

Rebuild.sh

This script is designed to be run by the user, or automatically by Accept.sh, and simply runs make in the tinydns root directory. It also keeps a simple logfile of the time at which the data file was rebuilt.

Replicate.sh

This script is designed to be run by the user. It sends the local data.host file to all of the hosts in our partners list, using SSH.

Todo

Eventually, all of the scripts will have very strict error checking and messages. At present, there may be a few files that are assumed to exist before they are read/written, this is not ideal.

1) This is necessary, as the scripts must be run upon remote login.
2) SSH command-triggering will be used to ensure security.
3) Note that it would be fairly useless anyway, as Accept.sh is run upon login and does very strict checking.