a while back i mentioned that i had modded some existing backup scripts to make
one that supports encryption of dumps using gpg. i would appreciate any
suggestions on how to make the script better and hope that others find it to be
useful. i'm using it to do backups for a couple groups of machines for ~2 months
and it's been working fine.

change the variables at the top of the script to match your setup.

here it is:

#!/bin/ksh
# original scripts by Nicholas Marriott and Todd Fries
# further modifications by Jacob Yocom-Piatt

#   NOTES
#
# - this script is for making incremental backups of host machines on
#   a network to a single backup host; this script runs on the backup
#   host
#
# - put this script in /etc and add a line calling the script
#   to /etc/daily.local like so:
#   ./backup.ksh host1.example.com host2.example.com ...
#
# - encryption of dumps via gnupg is optional
#
# - uses gzip compression to keep processor load low on the backup
#   host; replace with other compression algos if you like
#
# - works fine for a SOHO setup and may not scale well for large numbers of
#   hosts, YMMV
#
# - known to work for backing up both openbsd and netbsd hosts; untested
#   for other *nix OSes, but will likely work
#
# - change the variables to suit your particular setup and make sure to
#   READ THE SCRIPT

# email for backup admin's gpg key; use empty string for no encryption
ADMIN='[EMAIL PROTECTED]'

# home directory for gpg keyring; needed since /var/log is assumed
HOMEDIR='/root/.gnupg'

# path to backup destination on backup server
ROOT=/home/dump

# user for making dumps on remote hosts; this user should be a member of group
# operator
OP_USER=backup

# percentage full for ROOT that elicits a warning
WARN_PERC=95

# directories and mountpoints that you want to dump by default;
# add additional non-standard mountpoints to dump to the file
# 'list' in the backup directory for a given host
SOURCES='/ /var /usr /home'

# dump sequence. FULL is 0, RESET is 1, and PATTERN is followed between RESETs
FULL=20
RESET=10

# modified Tower of Hanoi algorithm
set -A PATTERN 3 2 5 4 7 6 9 8 9 9

# hostname
HN=$(hostname)
THISHOST=${hn%%.*}

# get the previous day
if [ -f $ROOT/day ]; then
    DAY=$(< $ROOT/day)
else
    DAY=0
fi

if [ $(($DAY % $FULL)) -eq 0 ]; then
    LEVEL=0
    DAY=0
elif [ $(($DAY % $RESET)) -eq 0 ]; then
    LEVEL=1
else
    LEVEL=${PATTERN[$(((DAY % $RESET) - 1))]}
fi

# check free space
USED=`df $ROOT|awk '/^\// { print substr($5, 0, length($5) - 1) }'`
if [ $USED -gt $WARN_PERC ]; then
    echo "-------------------------------------------------------------------"
    echo "LOW ON AVAILABLE DISK SPACE"
    echo "-------------------------------------------------------------------"
    df -h $ROOT
    exit
fi

echo "Starting $0.."

# calls dossh and accepts piped commands
dormt() {
        dossh -2 -c blowfish-cbc,aes256-ctr,aes256-cbc $1 sh | gzip -d
        return $?
}

# executes ssh plus options passed by dormt
dossh() {
        err=255
        while [ $err -ne 0 ]
                do
                #echo ssh "$@" > /dev/tty
                ssh "$@"
                err=$?
        done
        return $err
}

[ "$1" ] || {
        echo "No host specified on cmdline, please specify at least one"
        exit 1
}

# loop through hosts listed as arguments to script
while [ "$1" ]
do
        HOST="$1"

        # if we can't reach it, dont try and print notification
        if ! ping -c 3 $HOST > /dev/null 2>&1 ; then
                if ! ping6 -c 3 $HOST; then
                        print "cannot reach $HOST, giving up"
                        shift
                        continue
                fi
        fi

        shift

        # create the list of filesystems to dump if it doesn't exist
        [ -f $ROOT/$HOST/list ] || {
                mkdir -p $ROOT/$HOST

                # default FSes to backup in SOURCES, put each FS on a line
                echo $SOURCES | awk '{
                        i=1
                        while ( $i != "") {
                                print $(i++)
                        }
                 }' > $ROOT/$HOST/list
        }

        # read lines from list and perform dumps
        while read line
        do
                FN=${HOST}$(echo $line | sed 's/\//_/g')-${LEVEL}.dmp.gz
                echo $FN

                case $HOST in
                $THISHOST)
                        dump -${LEVEL}au -f - $line
                        ret=$?
                ;;
                *)
                        echo "/sbin/dump -${LEVEL}au -f - $line|gzip -1"|dormt
[EMAIL PROTECTED]
                        ret=$?
                ;;
                esac | gzip -9 > $ROOT/$HOST/.$FN
                echo return is: $ret
                mv $ROOT/$HOST/.$FN $ROOT/$HOST/$FN

                # encrypt each dump and remove the original
                if [ -n "$ADMIN" ]; then
                        echo "encrypting $FN"
                        if [ -f $ROOT/$HOST/$FN.gpg ]; then
                                rm -P $ROOT/$HOST/$FN.gpg
                        fi
                        gpg --homedir $HOMEDIR -e -r $ADMIN $ROOT/$HOST/$FN
                        rm -P $ROOT/$HOST/$FN
                        echo "output to $FN.gpg"
                fi
        done < $ROOT/$HOST/list 2>&1 | tee -a $ROOT/$HOST.log
done

# update day
DAY=$(($DAY + 1))
echo $DAY >$ROOT/day

Reply via email to