Here’s how we do DNS master slave auto replication… or better… slave —> master pull replication
Overview
On master DNS server we need to generate Bind slave zone file for rsync to fetch it from slave DNS server.
Than we need to set passwordless authentication between slave and master server. To do that we need to create and exchange private SSH keys (slave —> master).
Third part is rsyncing zone file(s) via secure socket from master to slave. After that we only need to reload bind service and we are done.
Step by step guide…
Master DNS server
Create folder for executable script
Create sh file, copy paste the content and set the “x” bit
Code:
vi /root/bin/generate_slave_zones.sh
Copy/Paste/change IP/save the following (Change the MASTER-SERVER-IP!!!)
Code:
#!/bin/sh
#
# Print out all domains listed in Sentora named.conf.
for domain in `/bin/grep ^zone /etc/sentora/configs/bind/etc/named.conf | grep -v '"."' | grep -vi in-addr | /bin/awk '{print $2}'| /bin/awk -F\" '{print $2}'`
# Print out all domains listed in zPanel named.conf.
# for domain in `/bin/grep ^zone /etc/zpanel/configs/bind/etc/named.conf | grep -v '"."' | grep -vi in-addr | /bin/awk '{print $2}'| /bin/awk -F\" '{print $2}'`
do
# Generate Bind slave zone file with correct master DNS IP.
/usr/bin/printf "zone \"${domain}\" {\n\ttype slave;\n\tfile \"slaves/${domain}.zone\";\n\tmasters { MASTER-SERVER-IP; };\n};\n"
# Write the file in exchange foder
done > /root/named_slave_zones_transfer/named.conf.slave.zones
Set the eXecute bit
Code:
chmod a+x /root/bin/generate_slave_zones.sh
Create zone exchange folder
Code:
mkdir /root/named_slave_zones_transfer
Run the script and check generated file contents
Code:
/root/bin/generate_slave_zones.sh
cat /root/named_slave_zones_transfer/named.conf.slave.zones
You should see something like this…
Code:
zone “domain.com” {
type slave;
file "slaves/domain.com.zone";
masters { MASTER-SERVER-IP; };
};
Add script to crontab…
Copy/paste/save the following. Script will be executed every 5 minutes. Change this according to your needs
Code:
# Named slave zone generator
*/5 * * * * /root/bin/generate_slave_zones.sh
Add Slave DNS server to acl trusted-servers pool in named.conf
Modify the following … (add the SLAVE-SERVER-IP). Without this line Bind zone transfer from Slave DNS server will fail!!!
Code:
acl trusted-servers {
MASTER-SERVER-IP; // ns1
SLAVE-SERVER-IP; // ns2
};
Install rsync
Slave DNS server
Create public and private keys using ssh-keygen on slave server
Confirm default file name to save the key and leave empty passphrase.
This will generate the following files
Code:
ll /root/.ssh/id*
-rw------- 1 root root 1.7K Feb 6 00:33 /root/.ssh/id_rsa
-rw-r--r-- 1 root root 403 Feb 6 00:33 /root/.ssh/id_rsa.pub
Tighten up file permissions
Code:
chmod 700 /root/.ssh
chmod 600 /root/.ssh/*
ls -ld /root/.ssh & ls -l /root/.ssh
Now copy the public key to the master server and fix permissions (you will be prompted for the root password)
Code:
ssh root@MASTER-SERVER-IP 'mkdir -p /root/.ssh'
scp /root/.ssh/id_rsa.pub root@MASTER-SERVER-IP:/root/.ssh/authorized_keys
ssh root@MASTER-SERVER-IP 'chmod 700 /root/.ssh'
ssh root@MASTER-SERVER-IP 'chmod 600 /root/.ssh/*'
You should now be able to ssh from slave to master server without providing a password
Code:
ssh root@MASTER-SERVER-IP
On Slave DNS server install rsync package
create folder for executable script
Create sh file, copy paste the content and set the “x” bit
Code:
vi /root/bin/named-fetch-slave-zones.sh
Copy/Paste/change IP/save the following (Change the MASTER-SERVER-IP and MASTER-HOSTNAME!!!)
Code:
#!/bin/bash
# tmp direcotry
DIRECTORY=/root/named-slave-fetch
# Create dir if not exists
if [ ! -d "$DIRECTORY" ]; then
mkdir $DIRECTORY
fi
cd $DIRECTORY
# Rsync via ssh from master to slave
/usr/bin/rsync -e ssh root@MASTER-SERVER-IP:/root/named_slave_zones_transfer/named.conf.slave.zones .
if [ $? -eq 0 ]
then
# Copy zone file to bind zone slave folder and rename it
/bin/cp -u named.conf.slave.zones /var/named/slaves/slave-zones-MASTER-HOSTNAME.conf
# Change ownership permissions
/bin/chown root.named /var/named/slaves/slave-zones-MASTER-HOSTNAME.conf
# Change file permissions
/bin/chmod 644 /var/named/slaves/slave-zones-MASTER-HOSTNAME.conf
# Reload Bind (named) - CENTOS 6
/sbin/service named reload
# Reload Bind (named) - CENTOS 7
# /usr/sbin/service named reload
else
echo "Slave zone file download failed."
fi
Set the eXecute bit
Code:
chmod a+x /root/bin/named-fetch-slave-zones.sh
Include the slave zone file in named.conf
On the end of the file add the following line (change the hostname)
Code:
include "/var/named/slaves/slave-zones-MASTER-HOSTNAME.conf";
Run the sh script
Code:
/root/bin/named-fetch-slave-zones.sh
Check the messages log file. You should see something like
Code:
zone domain.com/IN: Transfer started.
transfer of ‘domain.com/IN' from MASTER-SERVER-IPCool site...: connected using SLAVE-SERVER-IP#49764
zone domain.com/IN: transferred serial 000000000
transfer of ‘domain.com/IN' from MASTER-SERVER-IPCool site...: Transfer completed:
Last step… edit the crontab
and add
Code:
# Named - Fetch slave zones from master
*/5 * * * * /root/bin/named-fetch-slave-zones.sh
This was tested in Centos 6/7 environment, but with minor changes it should also work on Ubuntu.
Thats it. Hope it helps.