views:

92

answers:

2

I created a bash script to transfer my zones between my primary and secondary DNS server. It downloads my zone list from the primary and checks for any new zones and then downloads and inserts those zone files into the zone directory and into the .local file for bind.

The problem I have is that if the zone file does not exist, the script will enter the details into the .local regardless of if this config already exists or not.

Can someone help me out to distinguish between zones that already exist and simply download the zone file. I have pasted my script below and if anyone has any queries on how it works, please feel free to ask. (can someone wrap the code please, it never works properly for me in any browser I try!)

#!/bin/sh
NAMED="/etc/bind/named.conf.local"
TMPNAMED="/tmp/zns-441245.temp"
TMPZONEFILE="/tmp/zones.txt"
TMP="/tmp/zns-732.temp"
ZONELOCATION="/var/cache/bind"
IGNORE=`cat ignore.txt`

logger DNS Update script running...
echo -n "Checking for new named.conf... "
wget -q http://91.121.75.205:10801/named/named.conf -O $TMPNAMED
if [ -e $TMPNAMED ]
then
        echo "done."
else
        echo "no new data!"
        exit
fi
echo -n "Generating zone names... "

grep "^zone" $TMPNAMED | cut -d " " -f "2" | cut -d "\"" -f 2 > $TMPZONEFILE
sed '1,5d' $TMPZONEFILE > $TMP
mv $TMP $TMPZONEFILE

echo "done. ("$TMPZONEFILE")"

echo "Generating zone info... "

grep -vf ignore.txt $TMPZONEFILE | while read ZONE; do

echo -n "Checking for $ZONELOCATION/$ZONE.db "

 if [ -e $ZONELOCATION/$ZONE.db ]
 then
  echo "[ exists ]"
 else
  export updates="yes"
  echo "[ doesn't exist ]"
  echo "New zone available ($ZONE)... "
  echo "zone \"$ZONE\" {
  type slave;
  file \"$ZONELOCATION/$ZONE.db\";
  masters { 91.121.75.205; };
  allow-notify { 91.121.75.205; };
  };" >> $NAMED
 fi

 done

 echo "Updating Bind configuration... "
 /etc/init.d/bind9 restart

rm $TMPZONEFILE
rm $TMPNAMED
A: 

One problem may be that your wget creates a file regardless of whether there's a source file so checking for existence will always be true.

if [ -s $TMPNAMED ]
then
    echo "done."    # file exists AND has data
else
    echo "no new data!" 
    exit
fi

will test to see if it's empty or non-existent and exit if so. This may be an issue with your if [ -e $ZONELOCATION/$ZONE.db ] as well.

sed or awk could do all of this in one line:

grep "^zone" $TMPNAMED | cut -d " " -f "2" | cut -d "\"" -f 2 > $TMPZONEFILE
sed '1,5d' $TMPZONEFILE > $TMP

but I would need to see some sample data to offer a solution.

Simplified quoting:

echo "done. ($TMPZONEFILE)"

You're not using the IGNORE variable or the updates variable. I don't see any reason to export it. Also, if you are relying on it elsewhere, its value won't survive once the while loop exits since piping something (grep in this case) into while sets up a subshell. It may be better to do one of these:

Bash:

while ...
do
    ...
done <(grep -vf ignore.txt $TMPZONEFILE)

sh:

grep -vf ignore.txt $TMPZONEFILE > tmp.out
while ...
do
    ...
done < tmp.out

I recommend using mktemp or tempfile to create temporary files, by the way.

This might be more readable and allows you to include quotes without having to escape them:

cat << EOF >> "$NAMED"
zone "$ZONE" {
  type slave;
  file "$ZONELOCATION/$ZONE.db";
  masters { 91.121.75.205; };
  allow-notify { 91.121.75.205; };
  };
EOF

It's always a good habit to quote variables that contain filenames.

Dennis Williamson
This is very explanitory, I'm going to have to work through it and tes the methods you've outlined and see how it goes. I am very new to scripting in linux and have never really learned anything more than what I had to do and that worked.
kaotix
A: 

If you're going to all of that trouble to synchronise named.conf you might just as well rsync the whole config including the zone files, and not bother using zone transfers between primary and secondary.

It's by no means mandatory to use AXFR to slave servers. If you've got administrative control over all of the servers for a zone it's quite acceptable to treat them all as masters.

Alnitak
This is a very good idea, one which I had not even considered. I'm going to look into getting this method setup. My only difference would be that the location of bind's zone files is not the same on both servers so I would need to change this using some form of script?
kaotix
you could just put in a symlink to make the (missing) directory from your main master's named.conf point to the real directory.
Alnitak