The problem and solution
I want to automatically distribute my DNS to two locations on a DirectAdmin server that only has one IP address. The issue is that DirectAdmin only syncs DNS records with DirectAdmin servers, so it will cost more to buy the cheapest DirectAdmin license, which costs at least $5, and a minimum of 4GB VPS, which raises the price. Therefore, I decided to write a script that can accomplish this on a cheap 1GB VPS from Netcup. In this thorough tutorial, we’ll go over how to fix any discrepancies between local and remote nameservers and synchronize DNS zones between DirectAdmin (ns1) and BIND (ns2) servers.
in my case ns1 directadmin nameserver is located in the USA, and ns2 server is located in Germany.
Table of Contents
- Introduction
- Setting Up SSH Key Authentication
- Creating the DNS Sync Script
- Configuring BIND on ns2
- Troubleshooting Common Issues
- Conclusion
1. Introduction
DNS synchronization ensures that changes made in one DNS server are automatically reflected in another. This is particularly important when managing domains across multiple servers. In this scenario, we have a DirectAdmin server (ns1) and a BIND-only server (ns2). Our goal is to sync DNS records from ns1 to ns2, ensuring both servers are always up-to-date.
2. Setting Up SSH Key Authentication
To securely transfer DNS zone files between servers, we need to set up SSH key authentication. This eliminates the need for password prompts during automated tasks.
Step 1: Generate an SSH Key on ns1
ssh-keygen -t ed25519 -N "" -f ~/.ssh/ns2-sync
Step 2: Copy the Public Key to ns2
ssh-copy-id -i ~/.ssh/ns2-sync.pub root@2.2.2.2
in above mentioned command 2.2.2.2 is the ip of your ns2 or secondary dns server
Step 3: Test Password-less Login
ssh -i /root/.ssh/ns2-sync root@ns2 "echo 'SSH works!'"
3. Creating the DNS Sync Script
We’ll create a script (dns-sync.sh
) that automates the synchronization process.
Step 1: Create the Script File
nano /usr/local/bin/dns-sync.sh
Step 2: Add the Following Content
#!/bin/bash
# Configuration
REMOTE_USER="root"
# this is the remote server ip or secondary server ip
REMOTE_HOST="2.2.2.2"
LOCAL_ZONE_DIR="/var/named"
REMOTE_ZONE_DIR="/var/lib/bind/domains"
REMOTE_CONF_DIR="/etc/bind/zones"
SSH_CMD="ssh -i /root/.ssh/ns2-sync ${REMOTE_USER}@${REMOTE_HOST}"
RSYNC_OPTS=(-avz --delete -e "ssh -i /root/.ssh/ns2-sync")
# Create temporary directory for config generation
TMP_DIR=$(mktemp -d)
trap 'rm -rf $TMP_DIR' EXIT
# Generate BIND zone configurations
for zone_file in ${LOCAL_ZONE_DIR}/*.db; do
domain=$(basename "${zone_file%.db}")
cat <<EOF > "${TMP_DIR}/${domain}.conf"
zone "${domain}" {
type master;
file "${REMOTE_ZONE_DIR}/${domain}.db";
};
EOF
done
# Sync zone files and configurations
rsync "${RSYNC_OPTS[@]}" ${LOCAL_ZONE_DIR}/*.db ${REMOTE_HOST}:${REMOTE_ZONE_DIR}/
rsync "${RSYNC_OPTS[@]}" ${TMP_DIR}/*.conf ${REMOTE_HOST}:${REMOTE_CONF_DIR}/
# Fix permissions and reload BIND
${SSH_CMD} -T << 'EOF' # Added -T flag
chown -R bind:bind /var/lib/bind/domains
chmod 644 /var/lib/bind/domains/*.db
systemctl reload bind9
EOF
Step 3: Make the Script Executable
chmod +x /usr/local/bin/dns-sync.sh
4. Configuring BIND on ns2
Step 1: Create Required Directories
mkdir -p /var/lib/bind/domains
mkdir -p /etc/bind/zones
chown -R bind:bind /var/lib/bind/domains
chmod 755 /var/lib/bind/domains
chmod 755 /etc/bind/zones
Step 2: Update BIND Configuration
Add the following line to /etc/bind/named.conf.local
:
include "/etc/bind/zones/*.conf";
5. Troubleshooting Common Issues
Issue: Local NS List Does Not Match Parent NS List
Ensure the NS
records in your DNS zone file match those registered with your domain registrar.
6. Conclusion
By following this guide, you’ve successfully synchronized DNS zones between DirectAdmin and BIND, ensuring seamless domain management. Regularly syncing DNS records helps maintain website availability and email functionality. If you encounter any issues, refer to the troubleshooting section for assistance.
Happy DNS managing! 🚀
If you do not have bind installed on NS2 server then Installing BIND on ns2 here is the instructions
Installing BIND on ns2
Below are the detailed steps to install BIND on your ns2 server, along with the necessary commands. This will ensure that your ns2 server is properly set up to handle DNS requests and synchronize with your DirectAdmin server (ns1).
Step 1: Update Your System
Before installing any new software, it’s a good practice to update your system packages.
sudo apt update && sudo apt upgrade -y
Step 2: Install BIND9
BIND9 is the most widely used DNS server software. You can install it using the following command:
sudo apt install bind9 -y
Step 3: Verify Installation
After installation, check if BIND is running correctly:
systemctl status bind9
You should see an output indicating that bind9
is active and running.
Step 4: Configure BIND
BIND uses configuration files located in /etc/bind/
. The main configuration file is named.conf
, which includes other configuration files like named.conf.options
, named.conf.local
, etc.
Edit named.conf.options
This file contains global options for BIND. You might want to adjust some settings based on your needs. For basic setup, you can leave it as default.
sudo nano /etc/bind/named.conf.options
Edit named.conf.local
This file is where you define your DNS zones. Add the following line to include zone configurations from the zones
directory:
include "/etc/bind/zones/*.conf";
sudo nano /etc/bind/named.conf.local
Add the line mentioned above and save the file.
Step 5: Create Zone Directories
Create directories for storing zone files and configurations.
sudo mkdir -p /var/lib/bind/domains
sudo mkdir -p /etc/bind/zones
sudo chown -R bind:bind /var/lib/bind/domains
sudo chmod 755 /var/lib/bind/domains
sudo chmod 755 /etc/bind/zones
Step 6: Test Configuration
Before restarting BIND, it’s a good idea to test the configuration for syntax errors.
named-checkconf
If there are no errors, proceed to restart BIND.
Step 7: Restart BIND
Restart the BIND service to apply the changes.
sudo systemctl restart bind9
Step 8: Enable BIND to Start on Boot
Ensure BIND starts automatically when the server boots.
sudo systemctl enable bind9
Step 9: Firewall Configuration
Make sure your firewall allows DNS traffic (port 53). If you’re using ufw
, you can allow DNS traffic with the following command:
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
sudo ufw reload
Summary of Commands
Here’s a summary of the commands you need to run to install and configure BIND on your ns2 server:
# Update system
sudo apt update && sudo apt upgrade -y
# Install BIND9
sudo apt install bind9 -y
# Check BIND status
systemctl status bind9
# Edit named.conf.options (optional)
sudo nano /etc/bind/named.conf.options
# Edit named.conf.local
sudo nano /etc/bind/named.conf.local
# Add: include "/etc/bind/zones/*.conf";
# Create zone directories
sudo mkdir -p /var/lib/bind/domains
sudo mkdir -p /etc/bind/zones
sudo chown -R bind:bind /var/lib/bind/domains
sudo chmod 755 /var/lib/bind/domains
sudo chmod 755 /etc/bind/zones
# Test configuration
named-checkconf
# Restart BIND
sudo systemctl restart bind9
# Enable BIND on boot
sudo systemctl enable bind9
# Allow DNS traffic through firewall
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
sudo ufw reload
By following these steps, you’ll have BIND installed and configured on your ns2 server, ready to synchronize DNS records with your DirectAdmin server (ns1).
Setup Cron on a directadmin server to sync dns records
Scheduling DNS Sync Script with Cron
To ensure your DNS records are automatically synchronized between DirectAdmin (ns1) and BIND (ns2), you can schedule the `dns-sync.sh` script to run at regular intervals using a cron job. Follow these steps to set up the cron job:
Step 1: Open Crontab for Editing
You can edit the crontab file using the following command:
crontab -e
This will open the crontab file in your default text editor (usually `nano` or `vi`).
Step 2: Add Cron Job Entry
Add a new line to the crontab file to specify when the script should run. The format of a cron job entry is as follows:
* * * * * command_to_be_executed
- - - - -
| | | | |
| | | | +-- Year (range: 1900-3000)
| | | +---- Month (range: 1-12)
| | +------ Day of the Month (range: 1-31)
| +-------- Hour (range: 0-23)
+---------- Minute (range: 0-59)
For example, if you want to run the `dns-sync.sh` script every hour, you would add the following line:
0 * * * * /usr/local/bin/dns-sync.sh >> /var/log/dns-sync.log 2>&1
This cron job will execute the `dns-sync.sh` script at the beginning of every hour and log the output to `/var/log/dns-sync.log`.
Step 3: Save and Exit
After adding the cron job entry, save the file and exit the editor. In `nano`, you can do this by pressing `CTRL+X`, then `Y` to confirm, and `Enter` to save.
Example: Running the Script Every 15 Minutes
If you want to run the script every 15 minutes, you would use the following cron job entry:
*/15 * * * * /usr/local/bin/dns-sync.sh >> /var/log/dns-sync.log 2>&1
Example: Running the Script Daily at Midnight
If you want to run the script daily at midnight, you would use the following cron job entry:
0 0 * * * /usr/local/bin/dns-sync.sh >> /var/log/dns-sync.log 2>&1
Verifying the Cron Job
To verify that the cron job has been added correctly, you can list all cron jobs with the following command:
crontab -l
This will display the contents of your crontab file, allowing you to confirm that the new entry has been added.
Checking the Log File
The log file (`/var/log/dns-sync.log`) will contain the output of each execution of the `dns-sync.sh` script. You can check this file to ensure that the script is running as expected and to troubleshoot any issues that may arise.
tail -f /var/log/dns-sync.log
Summary
By following these steps, you can easily schedule the `dns-sync.sh` script to run automatically at the desired interval using a cron job. This ensures that your DNS records are always up-to-date and synchronized between your DirectAdmin server (ns1) and BIND server (ns2).