Contact our honeypot department if you are desperate to get blacklisted.

Tuesday, April 14, 2015

collect server config files via rsync and commit them to a CVS with svn

I really like what RANCID does for routers and switches and wanted the same thing for my mail server configs. Here's what I put together with some help from the folks at freenode's #bash IRC channel. I hope someone else can find it a useful starting point. If you have any suggestions on how to improve it, I'd be grateful.
#!/bin/bash
#
# TODO:
#       *)make removing the working directories optional?
#

servers=("server-01" "server-02" "server-03" "server-04")
working_dir=/var/rancid/svn-temp/
rm -fr $working_dir/servers-cvs.mail
rm -fr $working_dir/servers-cvs2.mail

for i in "${servers[@]}"
 do
  echo '#########################################################' >>  $working_dir/servers-cvs.mail
  echo "$i: clearing working directories." >>  $working_dir/servers-cvs.mail
#  rm -rf $working_dir$i/\.*
#  rm -rf $working_dir$i/*
  cd /var/rancid/svn-servers/$i/
  echo "$i: checking out files from the repo." >>  $working_dir/servers-cvs.mail
  svn  checkout file:///var/rancid/svn-servers/$i $working_dir$i/
  echo "$i: copying files from $i into working directory." >>  $working_dir/servers-cvs.mail
  rsync  -q --no-motd --checksum -rptgoDLK --compress --recursive --delete  --relative --cvs-exclude  --exclude '/var/log/*'  root@$i:/etc/postfix :/etc/dovecot :/etc/mail :/var/www/html :/etc/snmp :/etc/mail :/etc/policyd :/etc/policyd-weight.conf  :/etc/fail2ban :/etc/amavisd.conf :/etc/clamd.conf :/mnt/lustre $working_dir$i/
  echo "$i: svn status:" >>  $working_dir/servers-cvs.mail
  svn status $working_dir$i   >>  $working_dir/servers-cvs.mail
  echo "$i: svn diff:"  >>  $working_dir/servers-cvs.mail
  svn diff $working_dir$i   >>  $working_dir/servers-cvs.mail
  echo "$i: committing changes to svn repo, if any."  >>  $working_dir/servers-cvs.mail
  IFS=$'\n'
  for new_line in $(svn status $working_dir$i); do
    file_svn_status=$(echo $new_line | cut -c1)         #get svn status of the file
    new_file=$(echo $new_line | cut -c2-)       #get the name of the file
    new_file="${new_file#"${new_file%%[![:space:]]*}"}" 
    echo '----------------------------------------------------------'
        case $file_svn_status in
        D)
                echo "this appears to be a DELETED file:$new_file.  Removing file from repo SVN" >>  $working_dir/servers-cvs2.mail
                svn remove /$new_file
                ;;
        M)
                echo "this appears to be a MODIFIED file:$new_file.  Committing changes to SVN" >>  $working_dir/servers-cvs2.mail
                ;;
        !)
                echo "this appears to have been removed from the working copy: $new_file .  Removing from repo SVN"  >>  $working_dir/servers-cvs2.mail
                svn remove /$new_file
                ;;
        ?)
                echo "this appears to be a new file: $new_file.  Committing new file to SVN"  >>  $working_dir/servers-cvs2.mail
                svn add /$new_file     
                ;;
        *)
                echo "Unknown fruit - sure it isn't toxic?"  >>  $working_dir/servers-cvs2.mail
        esac

  done  # done with 'for new_line  in $(svn status $working_dir$i)' loop
  svn commit $working_dir$i  -m 'auto-commit'
done     # done with 'for i in "${servers[@]}"' loop

#mail logic repurposed from RANCID
MAILHEADERS=""
    if [ -s $working_dir/servers-cvs2.mail ]  ; then
         echo "Today's date is $(date)" >> $working_dir/servers-cvs.mail
         echo "Today's date is $(date)" >> $working_dir/servers-cvs2.mail
        (
          echo "To: me@example.com"
          echo "Subject: changes in servers"
          echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}'
          echo ""
          cat $working_dir/servers-cvs.mail
          cat $working_dir/servers-cvs2.mail
        ) | /usr/sbin/sendmail -t
    fi