LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Blogs > rouvas
User Name
Password

Notices


Rate this Entry

Securely backup your $HOME to a remote machine

Posted 10-29-2011 at 07:19 PM by rouvas

SYNOPSIS

A simple and effective script to perform a secure backup of your home directory to a remote machine, with the help of sshfs and rsync. With trivial modifications it can be used to backup any directory.


FOR THE IMPATIENT

Drop this script into your path:

Code:
#!/bin/bash

#
# Specify the name of the user on the remote machine, defaults to the current user
#
REMOTE_USER=${REMOTE_USER:=$USER}

#
# Specify the remote host, either as an IP or a FQDN.
# If you are using the same remote host, provide it as a default to skip
# specifying it every time
#
REMOTE_HOST=${REMOTE_HOST:=remote.host.example.com}

#
# Specify what to mount from the remote host. Defaults to the remote $HOME
#
REMOTE_MOUNT=${REMOTE_MOUNT:=/home/$USER}

#
# Specify the local directory where the REMOTE_MOUNT will be mounted, i.e. locally visible.
# If the directory does not exists, it will be created.
# You must have appropriate rights to create this directory
# It makes sense to provide a default value that resembles the REMOTE_HOST
#
LOCAL_MOUNT=${LOCAL_MOUNT:=$HOME/$REMOTE_HOST}

#
# Specify where on the REMOTE_MOUNT will the backup be created.
# If the directory does not exist, it will be created.
# You must have appropriate rights to create this directory
#
BACKUP_DESTINATION=${BACKUP_DESTINATION:=${LOCAL_MOUNT}/backup}

#
# --- NO NEED TO MODIFY BEYOND THIS POINT ---
#
# rouvas [at] di.uoa.gr, 30 OCT 2011
#

exitVal=0;

function banner() {
  echo ":::"
  echo ":::" $@
  echo ":::"
}

function mount_remote() {
  local eVal=0
  sshfs -C -o reconnect,workaround=rename ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_MOUNT} ${LOCAL_MOUNT}
  if [ $? -eq 0 ]; then
    banner "$SHORT_LOCAL_MOUNT mounted"
    eVal=0
  else
    eVal=1
  fi
  return $eVal;
}

ego=$(basename $0)
banner $ego

SHORT_LOCAL_MOUNT=$(basename $LOCAL_MOUNT)

mkdir -p $LOCAL_MOUNT

pushd $HOME &> /dev/null

  goon=yes
  if [ $(mount | grep `basename ${LOCAL_MOUNT}` | wc -l) -ne 1 ]; then
    mount_remote
    if [ $? -ne 0 ]; then
      banner "${LOCAL_MOUNT} cannot be mounted, exiting"
      goon=no
      exitVal=2
    fi
  fi
  if [ x$goon = xyes ]; then
    mkdir -p $BACKUP_DESTINATION
    rsync -av --stats --delete                \
          --exclude $USER/$SHORT_LOCAL_MOUNT  \
          --exclude $USER/.mozilla            \
          --exclude $USER/.gconf*             \
          --exclude $USER/.cache              \
          --exclude $USER/.local              \
          --exclude $USER/.netbeans*          \
          --exclude $USER/.thumbnails         \
          --delete-excluded $HOME $BACKUP_DESTINATION
    exitVal=$?
  fi

popd &> /dev/null

exit $exitVal
name it something like "backup_home" and make it executable. To invoke it, you can either modify the parameters REMOTE_USER, REMOTE_HOST, REMOTE_MOUNT, LOCAL_MOUNT and BACKUP_DESTINATION at the start of the script or set them directly as environment variables and invoke the script. For example, assuming that the user name of both your local host and the remote host are the same you can invoke the script specifying only the REMOTE_HOST as in :

Code:
REMOTE_HOST=backup.machine.com ./backup_home

WHAT DOES IT DO
The script will try to connect to the REMOTE_HOST as the user provided in the REMOTE_USER variable. It will mount the REMOTE_MOUNT in the LOCAL_MOUNT and backup $HOME to the BACKUP_DESTINATION, creating the necessary directories along the way.

For the special case that both the local user and the remote user are the same, then a lot less variable have to be configured. Furthermore, if you accept the predefined defaults (i.e. backup to the directory "backup" on the remote machine), only the REMOTE_HOST must be provided.

Two directories will be created. On the local side, the $HOME/$REMOTE_HOST directory will be created and the remote host's side the directory "backup" (that is accepting the script's defaults). For example, it the remote host is "backup.machine.com", then the directory $HOME/backup.machine.com on the local host will be created.

The REMOTE_MOUNT directory will be mounted under the LOCAL_MOUNT using sshfs. Thus a secure connection between local host and the remote host will have been established and we can proceed with the actual backup using rsync. The operation can be stopped at any time and can be resumed at will. rsync will make sure that everything will be backed-up as it should.

By default, all of $HOME will be backed-up (to the REMOTE_HOST's directory backup) excluding the following directories:
  • SHORT_LOCAL_MOUNT, i.e. the remote host's name, thus avoiding an recursively backing up both the local and remote machine ad nauseam.
  • .mozilla, there really is little point in backing up the ever changing caches of Firefox
  • The directories .gconf, .local, .cache, .thumbnails that contain information valuable only to the local machine. There is no point in backing up the thumbnails of the most recently browsed photos, for example.
  • .netbeans*, as an example of specifying a wildcard in the directory exclusion, but quite useful as well. Under the .netbeans moniker, the NetBeans IDE stores a lot of information that is only relevant to the locally installed copy.
Of course you are free to modify the script to add or remove directories as needed.

The directories created during script's execution (i.e. LOCAL_MOUNT and BACKUP_DESTINATION) will NOT be deleted upon exit. Backing-up is a repetitive operations and most probably you're going to need these in the future. Also, the remote host is not unmounted. This will allow you to browse the remote host and validate the whole operation.

Should you wish to unmount the remote host, make sure that no process is using LOCAL_MOUNT, cd to a different directory than LOCAL_MOUNT and execute the following command.

Code:
fusermount -u LOCAL_MOUNT
In the above command you will actually have to specify the name of the LOCAL_MOUNT.


REQUIREMENTS
This script relies upon sshfs, rsync and fuse. Except from sshfs, rsync and fuse are almost certainly already installed in all but the tiniest Linux distributions. This script has been tested on Slackware and LinuxMint.10, but there is no reason why it shouldn't work on other distributions as well.
Posted in Uncategorized
Views 1789 Comments 0
« Prev     Main     Next »
Total Comments 0

Comments

 

  



All times are GMT -5. The time now is 04:08 AM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration