This is an old revision of the document!
Full system rsync
This script will perform a full system backup with rsync, leaving out /dev and /tmp and what not.
There are several configuration parameters:
target
: system to back up, must be set to output ofuname -n
. Used as a sanity check.source_dir
: source directory. Set to/
for full system backup.target_dir
: target directory. Set to a remote directory accessible via rsync over ssh in the form user@host:path.exclude_dir
: excluded directories. Set these to temporary directories and other things you don't want backed up.include_dir
: included directories. Subfolders of excluded directories to include.enc_mount_dir
: where to mount encrypted version ofsource_dir
. Recommended to do this in/tmp
somewhere.
This script also requires the encfs password GPG encrypted and stored as $target-encfs-password.gpg
. Also, the reverse encfs mount point must be configured before running the script for the first time. To do this, run ENCFS6_CONFIG=“/.encfs6.xml” sudo -E encfs –reverse “source-directory” “temporary-mount-point”
and setting up the encryption as desired. When that's done, unmount and run the backup script.
If you want to use ths script for a local hard drive, change flags to
flags="-avP --delete"
and set target_dir
to the mountpoint of an external hard drive. Note: make sure that target_dir
or a parent is included in exclude_dir
otherwise rsync will recurse and your hard drive will get filled up completely.
backup-system
#!/bin/bash set -f hostname=$(uname -n) target="my-hostname" source_dir="/" target_dir="user@server:backup/$target/" exclude_dir="*/.gvfs /media /run/media /sys /dev /proc /mnt /tmp pagefile.sys hiberfil.sys /home/*/.cache .mozilla/firefox/*/Cache .Trash-1000 /var/cache" include_dir="/mnt/linux-data/opt /mnt/data" flags="-avPse ssh --delete --rsync-path=\"rsync --fake-super\"" enc_mount_dir="/tmp/encrypted-root-mount/" if [ "0$skip_key" -ne 1 ] ; then export key=$(gpg --decrypt "$(pwd)/$target-encfs-password.gpg") export skip_key=1 fi # Require root if [ "$(/usr/bin/id -u)" != "0" ]; then sudo -E $0 exit fi if [ -n "$target" ] ; then if [ "$hostname" != "$target" ] ; then echo Error: must be run on $target exit 1 fi fi include="" # process include directories for d in $include_dir do found=0 dir="" exc_dir="" shortest_parent="" # Need to deal with rsync idiosyncracies # by including excluded directories # but not their contents # Removes matches to the include directory # and finds the shortest parent path for d2 in $exclude_dir do if [[ $d = $d2* ]]; then found=1 if [[ -z "$shortest_parent" ]]; then shortest_parent=$d2 else if [ ${#shortest_parent} -gt ${#d2} ]; then shortest_parent=$d2 fi fi else exc_dir="$exc_dir $d2" fi done if [[ $found ]]; then exclude_dir=$exc_dir path=`dirname "$d"` while [[ "$path" != "/" ]]; do exclude_dir="$exclude_dir $path/*" #include_dir="$include_dir $path" include="$include --include $path" path=`dirname "$path"` done fi include="$include --include $d" done exclude="" for d in $exclude_dir do exclude="$exclude --exclude $d" done die () { echo >&2 "$@" exit 1 } echo "Mounting..." mkdir -p "$enc_mount_dir" config_file="/.encfs6.xml" export ENCFS6_CONFIG="$config_file" echo $key | sudo -E encfs --reverse --stdinpass "$source_dir" "$enc_mount_dir" if [ "$?" -ne 0 ] ; then echo "Mount error!" else echo "Backing up..." dest=`echo "$target_dir" | sed -e 's,\(.\)/$,\1,'` dest=${dest}.encfs6.xml eval rsync $flags "$config_file" "$dest" eval rsync $flags $include $exclude "$enc_mount_dir" "$target_dir" echo "Unmounting..." fusermount -u "$enc_mount_dir" fi rmdir "$enc_mount_dir" echo "Done"