If you’ve recently read my guide on running BIND, pihole and DoH in particular the section about BIND you may have noticed we are running on a non-standard port. The setup is surprisingly easy 😊

A follow up question that was asked is how this works when running separate BIND servers (like I do) in a master/slave configuration. Most users of BIND are probably running a Master/Slave deployment. In large internet-facing environments there may be many slave servers that external users query, with a master hidden and secured in a separate network. If you’re unsure how zone transfers/updates are made in a Master/Slave configuration, here is the quick summary:

  • A user modifies the zone on the master server (adding a new record, updating a record etc)
  • They also increment the serial (we will get to that) on the master server
  • They perform a reload / refresh of the zone configuration on the master server
  • The master server “notifies” (push) all of its slaves that an update is available
  • The slave servers read the serial record from the master to see if there is in fact an update
  • If there is an update, the slaves perform a zone transfer from the master to themselves (pull)
  • The slaves servers load the new/updated records

There are a few different things that happen in the background, but that is the very basic working of how zone transfers operate in a simple master/slave configuration. There are other configurations like multi master, but we won’t get into that now.

Coming back to the original question of how to configure BIND on a non-standard port, let’s make a few assumptions. My setup is as follows:

  • Two servers running Ubuntu 16.04 with BIND installed
  • The master server is running on 192.168.211.11
  • The slave server is running on 10.152.0.3

The Master server

In my setup, I have the master running on the IP 192.168.211.11 so be sure to substitute my IP with whatever your one will be. As per one of my previous articles on Setting up BIND we configured it to respond on port 5354. We are going to roll with that since we are half way there. The other options you need to configure relate to notify and transfer.

You will need to include the following lines in /etc/bind/named.conf.options:

also-notify 
allow-transfer

This is how the last few lines of my named.conf.options look:

        listen-on port 5354 { 192.168.211.11; };
        listen-on-v6 { none; };
        also-notify { 10.152.0.3 port 5354;};
        allow-transfer { 10.152.0.3; };

So what we are doing here is telling BIND that it should notify our slave server (10.152.0.3) on port 5354 whenever there are updates. We are also telling BIND that we should allow zone transfers to the server 10.152.0.3. Make sure you include this last part otherwise the slave won’t be authorised to transfer zones!

The Slave Server

On the slave server, make sure you have BIND listening on port 5354 (as per the above, that’s the “listen-on-port” section. My setup has a few other bits I wont include here like internal routing interfaces, but to summarise my named.conf.options on the slave server looks like this:

        listen-on port 5354 { 10.152.0.3; };
        listen-on-v6 { none; };
        transfer-source 10.152.0.3;
        use-alt-transfer-source yes;

Then you need to configure your slave zones. Your slave server will only pick up DNS zones from the master after they have been configured on the slave. This means you need to tell BIND that it should host the relevant zone files. There is a new feature in BIND called Catalog zones which makes this process easier in large deployments, but I haven’t had time to test it out so I wont get into that just yet. So on your slave server, you need to adjust /etc/bind/named.conf.local so that it looks like this:

//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "mycoolzone" {
        type slave;
        masters { 192.168.211.11 port 5354; };
        masterfile-format text;
        file "mycoolzone.db";
};

Simple, isn’t it? Here you are telling BIND that the zone is a slave, that its master is 192.168.211.11 running on port 5354. The “masterfile-format text” is a personal preference. This tells bind to store the files in a text format (that can easily be read) instead of binary. While this slightly hinders performance, in most environments its probably worth doing if you want to compare zone files on master/slaves.

So with the above two changes made to the master/slave, you just need to give bind a reload;

systemctl reload bind9

Do that on the slave first, then the master. If you monitor /var/log/syslog by using the command

tail -f /var/log/syslog

on the slave, you should also see something like this show up:

Dec 18 00:10:47 dns2 named[17106]: client 192.168.211.11#47194: received notify for zone 'mycoolzone'
Dec 18 00:10:47 dns2 named[17106]: zone mycoolzone/IN: notify from 192.168.211.11#47194: serial 2018121803
Dec 18 00:10:47 dns2 named[17106]: zone mycoolzone/IN: Transfer started.
Dec 18 00:10:47 dns2 named[17106]: transfer of 'mycoolzone/IN' from 192.168.211.11#5353: connected using 10.152.0.3#52097
Dec 18 00:10:47 dns2 named[17106]: zone mycoolzone/IN: transferred serial 2018121803
Dec 18 00:10:47 dns2 named[17106]: transfer of 'mycoolzone/IN' from 192.168.211.11#5353: Transfer status: success
Dec 18 00:10:47 dns2 named[17106]: transfer of 'mycoolzone/IN' from 192.168.211.11#5353: Transfer completed: 1 messages, 27 records, 684 bytes, 0.019 secs (36000 bytes/sec)
Dec 18 00:10:47 dns2 named[17106]: zone mycoolzone/IN: sending notifies (serial 2018121803)

Keeping tail running, modify the contents of your zone file on the master server, add a new record or maybe change one of the records to a different IP.

Make sure you also increase the serial! At present the serial for my zone is 2018121803. While it isn’t required, a good way to keep track of changes in zone files is to date them. 2018121803 represents:
Year: 2018
Month: 12 (December)
Day: 18th
Increment: 03

So if I am making a change to the zone on the same day, i simply increase the increment by 1. This means the serial would become 2018121804 If i am making a change to the zone in a few days’ time, it would become something like 2018122101.

As long as the serial is higher than the previous value, it will be pushed out to slaves. Once you have made the change to your zone, you can simply type the following on your master server

rndc reload

This will load the zone configuration into bind, sending any updates out to slaves. Again, if you’ve got tail running on your slave, you should see the new updates replicating correctly:

Dec 18 00:20:01 dns2 named[17106]: client 192.168.211.11#46856: received notify for zone 'mycoolzone'
Dec 18 00:20:01 dns2 named[17106]: zone mycoolzone/IN: notify from 192.168.211.11#46856: serial 2018121804
Dec 18 00:20:01 dns2 named[17106]: zone mycoolzone/IN: Transfer started.
Dec 18 00:20:01 dns2 named[17106]: transfer of 'mycoolzone/IN' from 192.168.211.11#5353: connected using 10.152.0.3#53809
Dec 18 00:20:01 dns2 named[17106]: zone mycoolzone/IN: transferred serial 2018121804
Dec 18 00:20:01 dns2 named[17106]: transfer of 'mycoolzone/IN' from 192.168.211.11#5353: Transfer status: success
Dec 18 00:20:01 dns2 named[17106]: transfer of 'mycoolzone/IN' from 192.168.211.11#5353: Transfer completed: 1 messages, 27 records, 684 bytes, 0.025 secs (27360 bytes/sec)
Dec 18 00:20:01 dns2 named[17106]: zone mycoolzone/IN: sending notifies (serial 2018121804)

And there you have it. If you have any issues getting this setup, feel free to hit me up. While I do read my emails I tend to be a bit more responsive on Twitter these days. Enjoy.