Sunday, August 1, 2010

Automated Slave DNS Howto

Based on my earlier blog, concept of creation of a full automated DNS for add and removal of slave domain zone and config by itself. Not require any 3rd party program. Here is a simple howto. I use this with Windows + Linux multiple masters and a Debian Linux as good-slave-dns. Which require zero maintenance from today! :-)

  1. Prepare your slave named.conf, add the following config to logging {};
    channel goodslave_log{
    file "/var/log/goodslave.log";
    severity info;
    print-severity yes;
    print-time yes;
    print-category yes;
    };
    category notify{
    goodslave_log;
    };

  2. Create "/var/log/goodslave.log" and make sure named can read/write to it
  3. Create your slave config path, for example /etc/bind/slave on Debian; /var/named/chroot/etc/slave for RedHat bind-chroot. All slave config file will be stored here.
  4. Create an empty file called slaves.conf in your named configuration home. Debian: /etc/bind/slaves.conf and RedHat: /var/named/chroot/etc/slaves.conf
  5. Modify your named.conf and include the slaves.conf to it.
    include "/etc/bind/slaves.conf";
  6. Copy the script at end of this blog, modify your master DNS, admin email and PATH parameter
  7. Remove one of your slave zone config from named.conf. For example "example.org"
  8. Reload slave DNS with "rndc reload" and restart master DNS for "example.org"
  9. Check your "/var/log/goodslave.log" have an entry like this
    notify: notice: client slave-dns-IP: received notify for zone 'example.org': not authoritative
  10. Now run the script. If everything is fine, it will create/modify two files and reload the rndc
    First file is slave/example.org.conf, just like your previous slave config
    Second file is slaves.conf with content of "include "/etc/bind/slave/example.org.conf;"
  11. Time remove all manually added zone configrations and add the script to crontab.
  12. To test removal, add some domain on master, get it synchronized, then remove it from master. Same zone will be moved to folder deleted in your named conf folder after N days.
Now your have plenty time to do something else! I may implement this at work with 300+ domains. Think how much time you can save with it. :-)

## Copy & paste script ##

#!/bin/bash

# define allowed master(s), use space between master(s)
# example masters at 1.1.1.1 and 2.2.2.2
MASTERS="1.1.1.1 2.2.2.2"

# define other stuffs
ADMINMAIL="root"
CONFPATH="/etc/bind"
ZONEPATH="/var/cache/bind"
LOGFILE="/var/log/goodslave.log"
EXPIREDAYS=5

# script starts here

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# check the goodslave.log for "not authoritative"
grep "not authoritative$" $LOGFILE | awk -F"for zone" '{print $2}' | sort | uniq | while read LINE
do
# if find any, check if can axfr from any master

DOMAIN=$(echo $LINE | sed -e "s/'//g" -e 's/: not authoritative//' )

# check if already added
DOMAINCONF=$CONFPATH/slave/$DOMAIN.conf
DELETEDDOMAIN=$CONFPATH/deteled/$DOMAIN.conf
if [ ! -f "$DOMAINCONF" ]; then
if [ -f "$DELETEDDOMAIN" ] ; then
#already removed
ADD="1"
else

for MASTERDNS in $MASTERS
do
OUTPUT=$(dig axfr $DOMAIN @$MASTERDNS |grep "^;; XFR size:")
if [ -n "$OUTPUT" ] ; then
# create config to $CONFPATH/slave
CONF="zone \"$DOMAIN\" { type slave; masters { $MASTERDNS; }; file \"$DOMAIN\"; allow-notify { $MASTERDNS; }; };"
echo $CONF > $CONFPATH/slave/$DOMAIN.conf

# create new slaves.conf
ls -1 $CONFPATH/slave/*.conf | awk '{print "include \"" $1 "\";" }' > $CONFPATH/slaves.conf.new
mv $CONFPATH/slaves.conf $CONFPATH/slaves.conf.old
cp $CONFPATH/slaves.conf.new $CONFPATH/slaves.conf

# reload named
echo "adding $DOMAIN with master at $MASTERDNS" | mail $ADMINMAIL -s "good-dns-slave: new domain added"
rndc reload
ADD="1"
fi
done
fi
if [ -z "$ADD" ] ; then
# this part should fix to better on
# echo "unable to add $DOMAIN" | mail $ADMINMAIL -s "good-dns-slave: unable to add domain"
echo "unable to add $DOMAIN"
fi
fi
done


# check all slave zone and do dig soa against master

mkdir -p $CONFPATH/deleted
for FILE in $CONFPATH/slave/*.conf
do
DIGCMD=$(cat $FILE | awk '{print $2" "$8}' | sed -e 's/"//g' -e 's/;//' | awk '{print "dig soa " $1 " @" $2 " +short +nocomments"}')
RUNDIGCMD=$($DIGCMD | wc -l)

MISSINGMASTER="$FILE.missingmaster"
if [ ! $RUNDIGCMD -eq 1 ] ; then
# check if counter is bigger than N day if bigger than remove and restart
if [ -f $MISSINGMASTER ] ; then
EPOCH=$(cat $MISSINGMASTER)
TODAY=$(date "+%s")
let "TIMEDIFF = $TODAY - $EPOCH"
# if timediff > $days then move zone file and config away
let "LIMIT = $EXPIREDAYS * 86400"
if [ $TIMEDIFF -lt $LIMIT ] ; then
mv $FILE $CONFPATH/deleted
ZONEFILE=$(echo $FILE | awk -F'/' '{print "'"$ZONEPATH"'/"$NF}' | sed 's/.conf//')
mv $ZONEFILE $CONFPATH/deleted
mv $MISSINGMASTER $CONFPATH/deleted
echo "removing zone $FILE" | mail $ADMINMAIL -s "good-dns-slave: remove domain"
rndc reload
fi
else
# create counter of date(now)
date "+%s" > $MISSINGMASTER
fi

else
# remove missingfile if exisit
if [ -f $MISSINGMASTER ] ; then
rm -f $MISSINGMASTER
fi
fi



done

No comments: