Monday, April 21, 2014

Multiple DNS master servers

It is perfectly fine to have multiple master DNS servers as long as you keep them all in sync.  Here is an example how to make changes to DNS zones in GIT and push the changes to Bind servers.


DNS push script uses dedicated "sysadmin" account.  SSH keys have to be in place.


#!/bin/bash
# OPS branch have to be checked out to ~/git/ops/ to use this script
# I assume you have sudo privileges


usage(){
        echo -e Usage:\\n$0 datacenter
        exit 1
}

if [[ -z "$1" ]]
then
  usage
  exit 1
fi

datacenter=$1

cd ~/git/ops/config/sjc/named/var/named/data/
# Build reverse DNS zones
/usr/bin/mkrdns -root ~/git/ops/config/sjc/named/ ~/git/ops/config/sjc/named/etc/named.conf
# Checking syntax
for zone in `ls`
  do
    test=$(named-checkzone $zone $zone |grep OK)
    if [ "$test" != 'OK' ]
      then
      echo "Zone $zone syntax is wrong!"
      exit 1
    else
      echo "Syntax is fine"
    fi
done

echo "pushing to $datacenter"

# Execute remote dns change
sudo su - sysadmin -c "ssh -t -o StrictHostKeyChecking=no mgr1.$datacenter.company.com \"~/git/ops/scripts/dnspull.sh\""
echo "======================================================"
echo "mgr1.$datacenter.company.com is done"
echo "======================================================"
sudo su - sysadmin -c "ssh -t -o StrictHostKeyChecking=no mgr2.$datacenter.company.com \"~/git/ops/scripts/dnspull.sh\""
echo "======================================================"
echo "mgr2.$datacenter.company.com is done"
echo "======================================================"


DNS pull script will pull your changes from GIT, apply the changes, restart named, test if resolution is working properly (in this case "mgrclust1" server), and push the change to the next server.

#!/bin/bash
# Run it on the actual DNS (mgr1,2) server as user "sysadmin"


# I'm relying on resolv to get DC
DC=$(cat /etc/resolv.conf |grep search |awk '{print $2}' |awk -F. '{print $1}')
echo "=============================================="
echo "Pulling zones for $DC"
echo "=============================================="

# Pull from GITolite
cd ~/git/ops/
git pull origin master

# Copy zones over
rsync -av config/$DC/named/etc/ /var/named/chroot/etc/
rsync -av --delete config/$DC/named/var/named/ /var/named/chroot/var/named/

# Fix permissions
chown sysadmin:named /var/named/chroot/etc/named.conf
chown -R sysadmin:named /var/named/chroot/var/named/

# Restart named, look for OK
named_test=$(sudo /etc/init.d/named restart |grep Starting |awk '{print $4}')
echo $named_test

if [ "$named_test" != 'OK' ]
  then
    echo "Named restart failed!"
    exit 1
  else
    echo "Named restarted"
fi

# Try to resolve mgrclust1
dns_test=$(host mgrclust1 localhost |grep mgrclust1 |awk '{print $4}' |awk -F. '{print $4}')
if [ "$dns_test" != '1' ]
  then
  echo "I can't resolve mgrclust1!"
  exit 1
fi