BIND can act as both your primary DNS server (the authoritative source for a zone) and a secondary DNS server (a read-only copy that synchronizes changes from the primary).

Here’s how to set up a simple primary/secondary pair for a fictional zone, example.com.

Let’s imagine our primary server has the IP 192.168.1.10 and our secondary server has the IP 192.168.1.20.

Primary Server Configuration (/etc/bind/named.conf.local on 192.168.1.10)

First, on the primary server, we define the zone and specify that it’s the master.

zone "example.com" {
    type master;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { 192.168.1.20; }; // Allow zone transfers to our secondary
};

Next, we create the zone file itself (/etc/bind/zones/db.example.com).

$TTL    604800
@       IN      SOA     ns1.example.com. admin.example.com. (
                              3         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      ns1.example.com.
@       IN      NS      ns2.example.com. // This will be our secondary
ns1     IN      A       192.168.1.10
ns2     IN      A       192.168.1.20
www     IN      A       192.168.1.100

The crucial part here is the Serial number (3 in this case). Every time you make a change to the zone file, you must increment this serial number. This is how secondary servers detect that new data is available. The allow-transfer directive is key; it explicitly permits the secondary server (192.168.1.20) to request a full copy of the zone.

After making these changes, reload BIND:

sudo systemctl reload named

Secondary Server Configuration (/etc/bind/named.conf.local on 192.168.1.20)

On the secondary server, we define the same zone but declare it as a slave. We also tell it where to get the zone data from (the primary server’s IP).

zone "example.com" {
    type slave;
    file "/var/cache/bind/db.example.com"; // Where BIND will store the zone copy
    masters { 192.168.1.10; }; // The IP of our primary server
};

The masters directive tells BIND which IP address to query for zone transfers. The file directive specifies where BIND should store the downloaded zone data. This directory (/var/cache/bind/) must be writable by the BIND user (often bind or named).

Reload BIND on the secondary:

sudo systemctl reload named

At this point, the secondary server will attempt to contact the primary server, request the example.com zone, and store a local copy in /var/cache/bind/db.example.com.

Verification

On the secondary server, you can check the BIND logs for messages indicating a successful zone transfer. You can also use dig to query both servers:

On the primary (192.168.1.10):

dig @192.168.1.10 www.example.com A

On the secondary (192.168.1.20):

dig @192.168.1.20 www.example.com A

Both should return the same IP address for www.example.com (192.168.1.100).

Making Changes

To add a new record (e.g., a mail server mail.example.com pointing to 192.168.1.50):

  1. On the primary server (192.168.1.10):

    • Edit /etc/bind/zones/db.example.com.
    • Increment the serial number to 4.
    • Add the new record: mail IN A 192.168.1.50.
    • Reload BIND: sudo systemctl reload named.
  2. On the secondary server (192.168.1.20):

    • BIND will automatically detect the serial number change (via checking with the master at the refresh interval defined in the SOA record, or via NOTIFY if configured).
    • It will then initiate a zone transfer and update its local copy.
    • You can force a check by using rndc retransfer example.com on the secondary.

The most surprising true thing about BIND’s zone transfers is that the Refresh timer in the SOA record is the maximum time the secondary will wait before checking for updates, but the primary server can (and usually does) proactively notify secondaries of changes using the DNS NOTIFY mechanism, making updates nearly instantaneous if both servers are properly configured to support it.

The next concept you’ll likely explore is DNSSEC for securing your DNS records.

Want structured learning?

Take the full Bind course →