Skip to content

Configure BIND Slave DNS Server

In a DNS setup, having a slave server ensures redundancy, load balancing, and high availability. This guide will walk you through setting up a slave DNS server and syncing DNS zones from the master server.

Prerequisites

  • A master DNS server running on CentOS Stream 9 with the configured named service.
  • A slave DNS server running on CentOS Stream 9 or Debian with the bind9 service.
  • Root access to both servers.
  • SSH connection between the master and slave servers (non-default port in use for added security).

Step 1: Prepare Your Environment

  1. Ensure DNS services (named or bind9) are installed on both servers:
# CentOS
sudo dnf install bind bind-utils

# Debian
sudo apt-get install bind9 bind9utils

Ensure Rsync service installed on both servers:

# CentOS
sudo dnf install rsync

# Debian
sudo apt-get install rsync

Update the /etc/bind/named.conf.options file on the slave DNS server, follow these steps:

  • Open the configuration file for editing:
sudo nano /etc/bind/named.conf.options
  • Replace or add the following configuration under the options block:
   options {
       forwarders {
           8.8.8.8;
           8.8.4.4;
       };

       dnssec-validation auto;
       masterfile-format text;
       allow-query     { any; };
       allow-notify    { <slave-ip-address>; <master-ip-address>; };
       allow-query-cache { any; };
       recursion no;
       listen-on port 53 { any; };
   };
  • Save and close the file
  • Restart the BIND service to apply the changes:
sudo systemctl restart bind9
  • Verify the configuration to ensure there are no syntax errors:
sudo named-checkconf
  1. Configure your firewall to allow SSH and DNS traffic:
# Example for SSH and DNS
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=dns
sudo firewall-cmd --reload
  1. Set up SSH keys for passwordless login between the servers:
    run this from master server
ssh-keygen
ssh-copy-id -p 2222 root@<slave-ip-address>

Step 2: Create and Sync Zone Files

Here’s the full script code for setting up and syncing a DNS slave server:

#!/bin/bash

# Define variables
MASTER_DIR="/var/named"
SLAVE_DIR="/var/cache/bind"
SLAVE_IP="<slave-ip-address>"
MASTER_IP="<master-ip-address>"
SSH_PORT="2222"
SSH_USER="root"
ZONE_FILES="*.db"
BIND_CONFIG="/etc/bind/named.conf.local"
BIND_SERVICE="bind9"

# Sync zone files to the slave server
echo "Transferring zone files from $MASTER_DIR to $SLAVE_IP:$SLAVE_DIR..."
rsync -avz -e "ssh -p $SSH_PORT" $MASTER_DIR/$ZONE_FILES $SSH_USER@$SLAVE_IP:$SLAVE_DIR/

if [ $? -ne 0 ]; then
    echo "Error: Failed to transfer zone files to the slave server."
    exit 1
fi

# Set correct ownership for zone files
echo "Setting ownership of zone files to bind:bind..."
ssh -p $SSH_PORT $SSH_USER@$SLAVE_IP "chown bind:bind $SLAVE_DIR/*.db"

if [ $? -ne 0 ]; then
    echo "Error: Failed to set ownership for zone files."
    exit 1
fi

# Configure zones in named.conf.local on the slave server
echo "Configuring zones in $BIND_CONFIG on the slave server..."
ssh -p $SSH_PORT $SSH_USER@$SLAVE_IP bash <<EOF
ZONE_DIR="$SLAVE_DIR"
CONFIG_FILE="$BIND_CONFIG"

# Loop through each zone file in the zone directory
for ZONE_FILE in \$(ls \$ZONE_DIR/*.db 2>/dev/null); do
    ZONE_NAME=\$(basename \$ZONE_FILE .db)
    ZONE_CONFIG="zone \"\$ZONE_NAME\" IN {
    type slave;
    file \"\$ZONE_DIR/\$ZONE_NAME.db\";
    masters { $MASTER_IP; };
};"

    # Check if the zone is already configured
    if grep -q "zone \"\$ZONE_NAME\" IN" \$CONFIG_FILE; then
        echo "Zone \$ZONE_NAME already exists. Skipping..."
    else
        # Append the new zone configuration
        echo "\$ZONE_CONFIG" >> \$CONFIG_FILE
        echo "Added zone \$ZONE_NAME."
    fi
done
EOF

if [ $? -ne 0 ]; then
    echo "Error: Failed to configure zones on the slave server."
    exit 1
fi

# Restart BIND service on the slave server
echo "Restarting BIND service on the slave server..."
ssh -p $SSH_PORT $SSH_USER@$SLAVE_IP "systemctl restart $BIND_SERVICE"

if [ $? -ne 0 ]; then
    echo "Error: Failed to restart the BIND service on the slave server."
    exit 1
fi

echo "DNS zones successfully transferred, configured, and BIND service restarted on the slave server."

This script handles the entire process: transferring zone files, setting permissions, configuring zones in named.conf.local, and restarting the bind9 service on the slave server.

  1. Save the script provided earlier as sync_dns_slave.sh on the master server.
  2. Update the variables to match your environment:
MASTER_DIR="/var/named"
SLAVE_DIR="/var/cache/bind"
SLAVE_IP="<slave-ip-address>"
MASTER_IP="<master-ip-address>"
SSH_PORT="2222"
SSH_USER="root"
  1. Make the script executable:
chmod +x sync_dns_slave.sh
  1. Execute the script to sync zone files and configure the slave server:
./sync_dns_slave.sh

Step 3: Verify the Configuration

  1. Ensure zone files are present on the slave server:
ls /var/cache/bind/*.db
  1. Check the named.conf.local on the slave server for added zones:
cat /etc/bind/named.conf.local
  1. Test DNS functionality:
dig @<slave-ip-address> <zone-name>

Step 4: Automate Zone Syncing

To keep the slave server updated, set up a cron job on the master server:

crontab -e

Add the following line:

0 * * * * /path/to/sync_dns_slave.sh >> /var/log/sync_dns_slave.log 2>&1

Conclusion

By following these steps, you’ve set up a resilient DNS architecture with a master-slave configuration. The provided script ensures seamless synchronization, reducing manual intervention and minimizing downtime.

Published inBatchLinuxScriptSecurityShell