[Debian Sarge] Installing A Bind9 Master/Slave DNS System 

Version: 1.0 - aug 23, 2006


In this howto we will install 2 bind dns servers, one as the master and the other as a slave server. For security reasons we will chroot bind9 in its own jail.
Using two servers for a domain is a commonly used setup and in order to host your own domain you are required to have at least 2 domain servers. If one breaks, the other can continue to serve your domain.
Our setup will use Debian Sarge 3.1 (stable) for its base. A simple clean and up2date install will be enough since we will install the required packages with this howto.
In this howto I will use the fictional domain "linux.lan". The nameservers will use and as there ip.

Some last words before we begin: I read Joe's howto (also on this site) and some more tuts but none of them worked without some tweaks. Therefor, i made my own howto. And it SHOULD work at once :)

Installing Software

At first, you will need a clean Debian Sarge installation. Make sure its up2date!
apt-get update; apt-get upgrade
We also need some Debian building tools since we have to download source packages:
apt-get install devscripts
Next we will install the software needed for Bind. In order to use encryption for transfering the zone file between master and slave we need a more updated version of Bind9 (version >=9.3) then the one found in the Sarge repository. We will use the source from the -testing branch. So, make sure you have a line like this in your /etc/apt/sources.list:
deb-src http://---your.debian.mirror---/debian testing main contrib non-free

Bind9 from testing depends on lsb-base from testing. Lets grab it:
(Syntax explanation: the -y tells apt to say yes to all questions, build-dep installs all packages required for -testing_packageX- from the sarge repository and with -b the source gets build straight away.)

cd ~/a/dir/for/lsb-base/
apt-get -y build-dep lsb-base
apt-get source lsb-base -b
dpkg-i lsb-base*.deb

Next is Bind9:

cd ~/a/dir/for/bind9
apt-get -y build-dep bind9
apt-get source bind9 -b
dpkg -i *.deb

Now all our software is installed and ready to be configured.

Configure The Master

First we need to stop bind9:
/etc/init.d/bind9 stop
In order to chroot bind we need to set an option in /etc/default/bind9:
OPTIONS="-u bind"
OPTIONS="-u bind -t /var/lib/named"
It will now run as user 'bind' chrooted in '/var/lib/named'.
Next we edit the forwarders line in /etc/bind/named.conf.options to match the dns from our ISP:
forwarders {; };
These steps are required for the chroot jail:

mkdir -p /var/lib/named/etc
mkdir /var/lib/named/dev
mkdir -p /var/lib/named/var/cache/bind
mkdir -p /var/lib/named/var/run/bind/run
mv /etc/bind /var/lib/named/etc
ln -s /var/lib/named/etc/bind /etc/bind
mknod /var/lib/named/dev/null c 1 3
mknod /var/lib/named/dev/random c 1 8
chmod 666 /var/lib/named/dev/*
chown -R bind:bind /var/lib/named/var/*
chown -R bind:bind /var/lib/named/etc/bind

Bind now has its own dir with space for .pid files and config files. In order to keep things clear we made a symlink back to /etc/.

Now edit /etc/init.d/sysklogd to allow logging of bind activity:

SYSLOGD="-a /var/lib/named/dev/log"
The final step is to add the ip of this newly installed DNS server (the localhost) to your /etc/resolv.conf to use it:

echo "search linux.lan" > /etc/resolv.conf
echo "nameserver" >> /etc/resolv.conf

Now restart sysklogd and bind9:

/etc/init.d/sysklogd restart
/etc/init.d/bind9 start

And test !
ping www.google.com
If you get a reply, then your DNS master server is working and ready to use. We will now fill and use the linux.lan domain with our new master server.

Setting up the linux.lan domain

The master DNS server is currently just forwarding requests to the server of your ISP. So, we will now install and configure our own domain and let our new server handle all request regarding that domain.
Lets start with creating the directory where we will store the zone file. This file contains all info about the domain.
mkdir /etc/bind/zones/
Next we will create the zones file, /etc/bind/zones/master_linux.lan:
@ IN SOA ns1.linux.lan. hostmaster.linux.lan. ( 199802151 ; serial, todays date + todays serial # 8H ; refresh, seconds 2H ; retry, seconds 4W ; expire, seconds 1D ) ; minimum, seconds ; TXT "Linux.LAN, serving YOUR domain :)" NS ns1 ; Inet Address of name server NS ns2 MX 10 mail ; Primary Mail Exchanger localhost A ns1 A ns2 A www CNAME ns1
Here we have created a simple zone file with both nameservers and a www alias for ns1. Just in case we have a running apache on ns1 ;)

Now edit /etc/bind/named.conf.local and add:

zone "linux.lan" {
        type master;
        file "/etc/bind/zones/master_linux.lan";
This is it, we can now restart bind and check if it works:

/etc/init.d/bind9 restart
ping ns1.linux.lan

At this stage you should have a working and usable DNS server :)
If it says it cannot find the domain, maybe dhclient has changed your nameserver entry... So kill it.

Installing The Slave

Basically, the slave uses the same basic system as we constructed in the first part (just before we added the zone file). We will add some little changes to both master and slave to make them work together. The zones file will be transfered over the net using encryption.
Unless else stated, these commands are for the slave ONLY.

Create the zones dir:
mkdir /etc/bind/zones

For both master AND slave edit /etc/bind/named.conf.options and add:

dnssec-enable yes;

Now we need a secure key. This will generate a .private and a .key file. The 'key=' line in the .private file represents the hashkey.
dnssec-keygen -a hmac-md5 -b 128 -n host linux.lan

Add this in your /etc/bind/named.conf on master AND slave:
key "TRANSFER" {
        algorithm hmac-md5;
        secret "---HASHKEY---";

On the master we add the slave ip to /etc/bind/named.conf:
server {
        keys {

And on the slave we add the master ip to /etc/bind/named.conf:
server {
        keys {

Add to /etc/bind/named.conf.local:
zone "linux.lan" {
        type slave;
        file "/etc/bind/zones/slave_linux.lan";
        masters {; };
        allow-notify {; };
Final thing needed on BOTH hosts is to add this to /etc/bind/named.conf:
include "/etc/bind/rndc.key";

In order to have a succesfull zone transfer both systems need to have a synchronised clock, so:

apt-get -y install ntpdate

Restart bind on both machines and notice the new zone file on the slave :)
If youre wondering why _updates_ to the zonefile on your master seem to fail, check the expire etc. settings inside the zonefile.
Good luck with your new DNS master/slave configuration !
Share this page:

Suggested articles

7 Comment(s)

Add comment



I followed these instructions to set up a master-slave pair on Ubuntu 8.04. It generally worked, except that bind was not allowed to write into /etc/bind/zones. This turns out to be an apparmor issue, and the place bind is allowed to write is in /var/cache/bind. So substitute /var/cache/bind for /etc/bind/zones in the above, and it should work just fine on Hardy.

By: Gustavo Benites

Hola...estube siguiendo tu trabajo pero al llegar a la parte del dnssec-keygen el interprete se quedaba esperando... buscando en google encontre la siguiente alternativa

#> dnssec-keygen -a hmac-md5 -b 128  -n HOST master-slave.


donde master es el nombre del server master y slave el nombre del server slave y no olvidarse del punto.


Hi all,

I found out under debian 5/ubuntu 8+ u need to use command : 

 dnssec-keygen -r /dev/urandom -a hmac-md5 -b 128 -n host domain.name

 Without the -r /dev/urandom the dnssec-keygen will remain unresponsive. I found that it is waiting for input from the keyboard.

 my 0.02$



By: Anonymous

In case you're using rsyslogd, as is the case of Debian 5 systems, create a new file named /etc/rsyslog.d/bind-chroot.conf, and insert the line

AddUnixListenSocket /var/lib/named/dev/log

By: ismail

i have trouble with slave dns server. it gives like that:


ns2 named[1399]: dumping master file: /etc/bind/zones/tmp-iH5sOkwtFa: open: permission denied
ns2 named[1399]: transfer of 'yu.net/IN' from failed while receiving responses: permission denied
ns2 named[1399]: transfer of 'yu.net/IN' from Transfer completed: 0 messages, 9 records, 0 bytes, 0.001 secs (0 bytes/sec)

ns2 kernel: [ 7434.534805] type=1503 audit(1279096384.040:15):  operation="mknod" pid=1401 parent=1 profile="/usr/sbin/named" requested_mask="c::" denied_mask="c::" fsuid=102 ouid=102 name="/etc/bind/zones/tmp-iH5sOkwtFa"


forums says that: file permission is possible . but did permission 775 of the named.conf. that doesnt work.




secondly i have a question.  in rndc.key  there is a hash-key.

 key "rndc-key" {
        algorithm hmac-md5;
        secret "ZRh98eYCCLV16DX4F8WYwQ==";

i have to change this with generated linux.private key?

By: Anonymous

Hi all,

I tried your Howto with no success concerning transfert Zone between Master DNS server and Slave one, until i applied this two modifications, it'll be valuable if you can modify your Howto to take in account:

1 - Your must ensure that in the configuration file of the Master DNS include in the file /etc/bind/named.conf.options to send notification to all slaves like this:

options {
    directory "/var/cache/bind";

    also-notify { Slave IP Adress; }; // all zones Global Parameter


2 - Incorporate an example of logging facility at the end of option config file for someone who dont know howto : for example:


  channel simple_log {
    file "/var/log/named/bind.log" versions 3 size 5m;
    severity debug;
    print-time yes;
    print-severity yes;
    print-category yes;
  category default{


Thank you for all Open Source World.

PS: To spend less time to ;)

By: jamie

from the bind9 manual:

Specifies which hosts are allowed to notify this server, a slave, of zone changes in addition to the zone masters. allow-notify may also be specified in the zone statement, in which case it overrides the options allow-notify statement. It is only meaningful for a slave zone. If not specified, the default is to process notify messages only from a zone's master.

i don't think setting allow-notify with the same address of the master is necessary.