#!/bin/bash -e # Set "V" to "true" for verbose output. V=false # Set the following three variables to the username, hostname and # directory in which you want to store the remote backup. If you are # running the script automatically, e.g., in a cron job or in # /etc/cron.daily, then you need to make sure that ssh has the ability # to log in as this user on this host without a password, e.g., by # creating an SSH key with no passphrase whose public key is in the # .ssh/authorized_keys file for the user and whose private key is # listed in root's .ssh/config on your VPS. # # For additional security you may wish the remote user to run inside a # chroot environment, but setting that up is complicated and beyond # the scope of this posting. REMOTE_USER=[remote-username] REMOTE_HOST=[remote-hostname] REMOTE_DIR=[remote-backup-directory] # Search for "CONFIG:" below to find additional configuration you may # wish to change. D=/tmp/backup.$$ mkdir $D # Find paths in all RPMs. The find the ones that have changed. Then # find the ones that have *not* changed by removing the ones that have # changed from the complete list. Finally, remove directories from # the list of unchanged paths, to arrive at a list of files and # devices which are identical to what's in their RPMs. These are the # paths that are excluded from the backup. $V && echo "Finding paths in all RPMs" rpm -qla | fgrep -v '(contains no files)' | sort > $D/all-rpm-paths $V && echo "Finding changed RPM paths" rpm --verify --nomd5 -a | grep '^[\.S]' | grep -v '^missing' | awk '{print $NF}' | sort >| $D/changed-rpm-paths # Need to do this because some config files are explicitly not # verified by rpm. $V && echo "Finding changed config files" rpm -q --dump -a | perl -ne 'split; next if (! $_[7]); print;' | while read path size mtime md5sum mode owner group rest; do if [ -d $path ]; then : elif [ ! -e $path ]; then : elif [ "$(stat -c "%s %Y %U %G" $path)" != "$size $mtime $owner $group" ]; then echo $path elif [ 0$((echo 'obase=8; ibase=16;'; stat -c %f $path | tr a-z A-Z) | bc) != $mode ]; then echo $path elif [ $(md5sum $path | awk '{print $1}') != $md5sum ]; then echo $path fi done | sort -u -o $D/changed-rpm-paths $D/changed-rpm-paths - $V && echo "Finding unchanged RPM paths" comm -23 $D/all-rpm-paths $D/changed-rpm-paths > $D/unchanged-rpm-paths $V && echo "Extracting non-directories from exclude path list" while read file; do test -L "$file" -o \! -d "$file" && echo "$file" done < $D/unchanged-rpm-paths > $D/excludes $V && echo "Adding extra excludes" # CONFIG: Add paths you don't wish to back up to this list. These can # be files or directories (in which case the entire contents of the # directory are excluded). NOTE: Do *not* use globbing patterns here. # They won't work, because the command below uses --include-filelist # and --exclude-filelist instead of --include-globbing-filelist and # --exclude-globbing-filelist. Globbing patterns slow down # rdiff-backup *tremendously*. See below for how to do globbing if # you need to. cat >> $D/excludes <> $D/excludes ls /home/jik/Mail/notspam* >> $D/excludes ls /home/*/.bogofilter/wordlist.db >> $D/excludes ls /home/*/.bogofilter/wordlist.db.autobak.gz >> $D/excludes ls /var/lib/news/history.* >> $D/excludes find / -xdev -name '.#*' -print >> $D/excludes $V && echo "Creating includes" # CONFIG: You may wish to have some exceptions to the directories # excluded above. Edit the following as needed. You can also use the # globbing technique shown above for the includes file, if you need # to. cat >> $D/includes <