In this tutorial, we’ll walk you through the process of configuring high availability DNS servers for your Control Web Panel (CWP) using two bash scripts. This setup ensures redundancy and reliability for your DNS infrastructure, improving overall system availability.
Environment Details
Before we begin, let’s review the environment details:
- CWP Server: Rocky Linux 8 (Hostname:
cwpserver01.domain.local
) - DNS Cluster Servers: Rocky Linux 9 (Hostnames:
dns01.domain.local
anddns02.domain.local
)
Step 1: Generating SSH Keys and Copying to DNS Servers
First, we need to generate SSH keys on the CWP server and copy them to the DNS cluster servers. This will facilitate secure communication between the servers.
# Generate SSH keys on CWP server
ssh-keygen -t rsa
# Copy SSH keys to Rocky Linux 9 BIND servers
ssh-copy-id -i /root/.ssh/id_rsa.pub root@dns01.domain.local
ssh-copy-id -i /root/.ssh/id_rsa.pub root@dns02.domain.local
Replace dns01.domain.local
and dns02.domain.local
with the actual hostnames or IP addresses of your Rocky Linux 9 BIND servers.
Step 2: Configuring High Availability DNS Servers
Next, we’ll configure high availability for your DNS servers using two bash scripts. Let’s delve into the details of each script and its functionality.
Script 1: Synchronizing DNS Records and Reloading BIND
Save the following script as /opt/dns/dns-sync.sh
on your CWP server and make it executable with .
chmod +x /opt/dns/dns-sync.sh
First Script:
#!/bin/bash
# Define the remote paths for DNS zones on Rocky Linux servers
REMOTE_USER1="root" # Replace with your Rocky Linux SSH username for dns01
REMOTE_USER2="root" # Replace with your Rocky Linux SSH username for dns02
REMOTE_SERVER1="dns01.domain.local"
REMOTE_SERVER2="dns02.domain.local"
REMOTE_PATH="/var/named/" # Remote path for named
REMOTE_SCRIPT="/opt/dns/generate_named_conf_reload.sh" # Remote script path
echo "Starting the script to sync zone files to remote servers..."
# Sync zone files to the first Rocky Linux server
echo "Syncing zone files to ${REMOTE_SERVER1}..."
if timeout 5s sudo rsync -avz --delete /var/named/ ${REMOTE_USER1}@${REMOTE_SERVER1}:${REMOTE_PATH}/; then
echo "Sync to ${REMOTE_SERVER1} completed successfully."
else
echo "Sync to ${REMOTE_SERVER1} failed. Moving on to the next server."
fi
# Sync zone files to the second Rocky Linux server
echo "Syncing zone files to ${REMOTE_SERVER2}..."
if timeout 5s sudo rsync -avz --delete /var/named/ ${REMOTE_USER2}@${REMOTE_SERVER2}:${REMOTE_PATH}/; then
echo "Sync to ${REMOTE_SERVER2} completed successfully."
else
echo "Sync to ${REMOTE_SERVER2} failed. Moving on to the next server."
fi
# Determine if the current minute is odd or even
current_minute=$(date +%M)
if ((current_minute % 2 != 0)); then
# Odd minute - execute script on dns01 and reload BIND
echo "Executing script and reloading BIND on ${REMOTE_SERVER1}..."
if timeout 5s ssh ${REMOTE_USER1}@${REMOTE_SERVER1} "${REMOTE_SCRIPT}"; then
echo "Script execution on ${REMOTE_SERVER1} completed successfully."
else
echo "Script execution on ${REMOTE_SERVER1} failed."
fi
else
# Even minute - execute script on dns02 and reload BIND
echo "Executing script and reloading BIND on ${REMOTE_SERVER2}..."
if timeout 5s ssh ${REMOTE_USER2}@${REMOTE_SERVER2} "${REMOTE_SCRIPT}"; then
echo "Script execution on ${REMOTE_SERVER2} completed successfully."
else
echo "Script execution on ${REMOTE_SERVER2} failed."
fi
fi
echo "Sync completed successfully."
Explanation of Script 1 Logic
- Synchronization: The script synchronizes DNS zone files from the CWP server to the remote BIND servers (
dns01
anddns02
) usingrsync
. It ensures that any changes made on the CWP server are replicated on the DNS servers. - Odd-Even Logic: The script utilizes the parity of the current minute to determine which DNS server should execute the remote script (
REMOTE_SCRIPT
) to reload the BIND service. This alternates between the primary (dns01
) and secondary (dns02
) servers, distributing the workload evenly.
Using Odd-Even Logic for BIND Service Reload
In the provided script (dns-sync.sh
), there’s a section that determines whether the current minute is odd or even using the date +%M
command. This logic serves a crucial purpose in ensuring seamless and uninterrupted service during DNS zone file synchronization.
Purpose of Odd-Even Logic
- Load Distribution: By alternating the execution of the remote script (
REMOTE_SCRIPT
) between the primary and secondary DNS servers based on the parity of the current minute, the script distributes the workload evenly across both servers. This prevents a single server from bearing the burden of frequent BIND service reloads, which could potentially impact performance. - High Availability: In a high availability setup, it’s essential to ensure that critical services like BIND are always available. By reloading the BIND service alternately between the primary and secondary servers, the script minimizes the risk of downtime during updates or synchronization activities. If one server is undergoing maintenance or experiencing issues, the other server can continue to serve DNS requests without interruption.
Example Scenario
- Odd Minute: When the current minute is odd, the script executes the remote script (
REMOTE_SCRIPT
) on the primary DNS server (REMOTE_SERVER1
) to reload the BIND service. This ensures that any changes or updates to the DNS zone files take effect on the primary server, and DNS resolution remains uninterrupted for clients querying this server. - Even Minute: Conversely, when the current minute is even, the script executes the remote script on the secondary DNS server (
REMOTE_SERVER2
). This ensures that the secondary server stays synchronized with the primary server and is ready to take over DNS resolution if needed, providing redundancy and fault tolerance.
Conclusion
In summary, the odd-even logic employed in the script helps maintain a balanced workload distribution and ensures high availability of the DNS service across multiple servers in a cluster. By carefully orchestrating the execution of the BIND service reloads, the script optimizes performance and resilience in the DNS infrastructure.
Script 2: Generating named.conf
and Reloading BIND
Save the following script as /opt/dns/generate_named_conf_reload.sh
on both DNS servers (Rocky Linux 9) and make it executable with following command:
chmod +x /opt/dns/generate_named_conf_reload.sh
Second Script:
#!/bin/bash
# Directory containing .db files
DB_DIR="/var/named"
# Location of named.conf
NAMED_CONF="/etc/named.conf"
# Temp file to store existing zones
TMP_FILE="/tmp/existing_zones.txt"
echo "Starting the script to generate named.conf and reload BIND..."
# Generate list of existing zones in named.conf
echo "Generating a list of existing zones in named.conf..."
grep "zone " "$NAMED_CONF" | awk -F\" '{print $2}' > "$TMP_FILE"
echo "Existing zones list generated."
# Check if any new .db files are present
echo "Checking for new .db files in $DB_DIR..."
NEW_ZONES=$(find "$DB_DIR" -name "*.db" -type f)
for file in $NEW_ZONES; do
zone=$(basename "$file" .db)
# Check if the zone is already included in named.conf
if ! grep -q "$zone" "$TMP_FILE"; then
# Add zone to named.conf
echo "Adding zone $zone from $file to named.conf..."
echo "zone \"$zone\" {
type master;
file \"$file\";
};" >> "$NAMED_CONF"
echo "Zone $zone added to named.conf."
fi
done
# Check if any .db files have been removed
echo "Checking for removed .db files..."
while IFS= read -r existing_zone; do
db_file="$DB_DIR/$existing_zone.db"
if [ ! -f "$db_file" ]; then
# Remove zone from named.conf
echo "Removing zone $existing_zone from named.conf..."
sed -i "/zone \"$existing_zone\" {/,/};/d" "$NAMED_CONF"
echo "Zone $existing_zone removed from named.conf."
fi
done < "$TMP_FILE"
# Remove temporary file
echo "Cleaning up temporary files..."
rm -f "$TMP_FILE"
echo "Temporary files cleaned up."
# Check BIND configuration
echo "Checking BIND configuration..."
if named-checkconf "$NAMED_CONF"; then
# Reload BIND
echo "Reloading BIND..."
if systemctl reload named; then
echo "BIND reloaded successfully."
else
echo "Error: Failed to reload BIND."
exit 1
fi
else
echo "Error: BIND configuration check failed."
exit 1
fi
echo "Script execution completed."
Explanation of Script 2 Logic
- Named.conf Generation: The script generates the
named.conf
file by dynamically adding or removing zone configurations based on the presence of.db
files in the specified directory ($DB_DIR
). This ensures that the BIND service is aware of all DNS zones and their configurations. - Configuration Check and Reload: After updating the
named.conf
file, the script checks the BIND configuration for errors usingnamed-checkconf
. If the configuration is valid, it reloads the BIND service usingsystemctl reload named
, ensuring that changes to DNS configurations take effect immediately.
Purpose of Script 2 Tasks
- Generating named.conf: The script first generates a list of existing zones in
named.conf
. It then checks for new.db
files and adds any new zones tonamed.conf
. Similarly, it checks for removed.db
files and removes corresponding zones fromnamed.conf
, ensuring that the configuration stays up to date. - Checking BIND Configuration and Reloading: After updating
named.conf
, the script checks the BIND configuration for errors usingnamed-checkconf
. If the configuration is valid, it reloads the BIND service to apply the changes. This ensures that the DNS service remains consistent and operational.
Additional Instructions
Line Ending Correction
When copying and pasting the scripts from Windows to Linux environments, they may have incorrect line endings, which can cause errors when executing the scripts. To ensure proper functionality, follow these steps:
- On CWP Server (Rocky Linux 8):
- Run the following command to correct the line endings for the synchronization script:
dos2unix /opt/dns/dns-sync.sh
- Run the following command to correct the line endings for the synchronization script:
- On DNS Servers (Rocky Linux 9):
- Run the following command on each DNS server to correct the line endings for the generation and reload script:
dos2unix /opt/dns/generate_named_conf_reload.sh
- Run the following command on each DNS server to correct the line endings for the generation and reload script:
This will ensure that both scripts are formatted correctly for execution on their respective servers.
Final Steps
- On CWP Server (Rocky Linux 8):
- Add the
dns-sync.sh
script to the root user’s crontab to ensure it runs periodically and keeps your DNS servers synchronized and updated.sudo crontab -e
Then add the following line at the end of the file
This will run the synchronization script (dns-sync.sh
) every 5 minutes. Logs will be saved in/var/log/
for monitoring and troubleshooting. - Add the
- On DNS Servers (Rocky Linux 9):
- Run the
generate_named_conf_reload.sh
script to generatenamed.conf
and reload BIND as needed. This script should already be set up to run as part of the synchronization process initiated bydns-sync.sh
.
- Run the