Simple RSYNC/SSH/ZFS Backup

Hi there,

It has been a while, busy building clouds and stuff. In the Christmas spirit of sharing, today I wanted to share this bash script for ZFS backups, it will basically snapshot the ZFS share, RSYNC new files over and the delete the old ZFS snaps.

Simple, yes, but somehow a wheel that keeps being reinvented over and over again, so here’s my version of it. Hope it helps someone save some time.

For this script, the backup server is one of our own TerraNas servers (basically, Ubuntu 14 with Native ZFS and NFS/4) the client is a Ubuntu14 LTS server, the SSH keys have been imported to the client so we can SSH across without passwords and such.

On the ZFS/NFS server side, we disable ID mapping to have usernames cross the wire instead of ID’s

echo N > /sys/module/nfs/parameters/nfs4_disable_idmapping

share the ZFS drive with:

zfs set sharenfs=rw=@,insecure,no_root_squash pool1/backup

Where is your subnet or host of course.

Then we share it our with zfs share -a and service nfs-kernel-server restart.

We do have one export to the localhost in the /etc/exports file, because NFS will complain if this file is empty, but the rest of the exports come from ZFS

On the client we have this little script:

Make note of the additions of MOUNT and UMOUNT to the sudoers file, to enable a user to mount NFS shares.
# User home ZFS Backup Script 2.0
# Needs SSH token access to ZFS Server and NFS Mount Points
# ZFS/NFS exports on ZFS server under zfs/backup/*
# add Cmnd_Alias MOUNT=/bin/mount,/bin/umount to the ALIAS section in /etc/sudoers using visudo
# add ALL ALL=NOPASSWD: MOUNT to the END of the /etc/sudoers using visudo

# Vars
NOW=$(date +"%m-%d-%Y")

# Create or mount the ZFS folder
echo ZFS Backup from $BACKUPSOURCE to $BACKUPDEST started..
if ! [ -d $BACKUPSOURCE/zfs ]; then mkdir $BACKUPSOURCE/zfs; fi
if ! mountpoint -q $BACKUPSOURCE/zfs; then if ! (sudo mount $ZFSSERVER:$ZFSMOUNT $BACKUPSOURCE/zfs); then echo "Mount of $BACKUPSOURCE/ZFS failed"; exit 1; fi;fi

# Add attempt to backup list and syslog
echo $NOW,$HOME/zfs/$HOSTNAME-$USER-$NOW.log >> $HOME/zfs/backup-$HOSTNAME-$USER-dates.lst

# Create ZFS folder or snapshot
if [ -d $BACKUPDEST ]; then
ssh root@$ZFSSERVER 'zfs snapshot '$ZFSPOOL'/'$HOSTNAME'@'$USER-$NOW
ssh root@$ZFSSERVER 'zfs create '$ZFSPOOL'/'$HOSTNAME

# Remove the older snaps (see RETENTION varaible)
ssh root@$ZFSSERVER 'zfs list -rt snap -H -S creation -o name |grep '$USER' |tail -n '$RETENTION' |xargs -n 1 zfs destroy -r'
# Do the Magic
rsync -av -P $BACKUPSOURCE $BACKUPDEST --stats --human-readable --delete-before --log-file=$HOME/zfs/$HOSTNAME-$USER-$NOW.log --exclude-from=$BACKUPSOURCE/exclude.lst

# Clean it up
sudo umount $BACKUPSOURCE/zfs

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s