User Tools

Site Tools


linuxtips:secureremotebackup

Implementing a secure remote backup using unix tools

I wanted to store the backup of my server onto another machines filesystem.

Features

Features that I wanted the solution to provide:

  • different backup sets (to have different backups)
  • full backup
  • differential backup
  • incremental backup
  • verify
  • restore ;-)
  • fault tolerant backup (one broken bit should not make a backup useless)
  • encrypted backups
  • secure network transmission
  • bandwith limiting

Tools

All this can be done by making it the common unixway: tightening together some unixtools

Tools that I came across:

  • tob - “Tape Oriented Backup” is a simple but powerful backup script that uses afio (fault tolerant!) to do the actual backup. It is highly configurable and understands full, diff and inc backup and can verify and restore backups
  • aespipe - a small and very cool tool to encrypt a data stream using the fast and secure AES encryption algorythm
  • openssh - The secureshell client can be used to transmit data
  • cstream - A tool which can be used to limit a stream to a specified Bandwith.

Tob patch

I needed to extend tob a bit so that it supports remote backups (patch is against tob 0.23):

--- tob.bak     Tue Mar 29 19:33:37 2005
+++ tob Thu Mar 31 13:08:02 2005
@@ -191,7 +191,7 @@
<code>
        error "BACKUPDIR is deprecated: check your config file, and rename it to BACKUPDEV"
     fi

- if -d "$BACKUPDEV" ; then + if $RSH_CMD -d "$BACKUPDEV" ; then

        BACKUPDIR=$BACKUPDEV;
        BACKUPDEV="${BACKUPDIR}/${VOLUMENAME}_${DATE}_${TYPE}.gz"

@@ -466,8 +466,8 @@

 runverify ()
 {
     VOLUMENAME=$2                   # store name for usage in .rc file

- if -d "$BACKUPDIR" ; then - BACKUPDEV=`$LS ${BACKUPDIR}/${VOLUMENAME}_*full.gz` + if $RSH_CMD -d "$BACKUPDIR" ; then + BACKUPDEV=`$RSH_CMD $LS ${BACKUPDIR}/${VOLUMENAME}_*full.gz`

     fi
     message "Now starting verify program for $BACKUPDEV."
     ( cd /;

@@ -554,20 +554,32 @@

     $RM -f $TOBLISTS/$2.Full* $TOBLISTS/$2.incremental* $TOBLISTS/$2.differential.*
     gzip -c $TMPLIST > $TOBLISTS/$2.Full.gz

- if -d "$BACKUPDIR" ; then + if $RSH_CMD -d "$BACKUPDIR" ; then

        UPTO=`basename $BACKUPDEV`
        SEEN='0'

- cd $BACKUPDIR - for i in `find ${VOLUMENAME}_* -mtime +$MAXBACKUPAGE -exec echo {} \;`; do - if $i == $UPTO ; then - SEEN=1 - fi - if $SEEN == '0' ; then - message “Deleted old backup $i” - $RM -f $i - fi - done + if "$RSH_CMD" ; then + for i in `$RSH_CMD “cd $BACKUPDIR; find ${VOLUMENAME}_* -mtime +$MAXBACKUPAGE -exec echo {} \;”`; do + if $i == $UPTO ; then + SEEN=1 + fi + if $SEEN == '0' ; then + message “Deleted old backup $i” + $RSH_CMD “cd $BACKUPDIR; $RM -f $i” + fi + done + else + cd $BACKUPDIR + for i in `find ${VOLUMENAME}_* -mtime +$MAXBACKUPAGE -exec echo {} \;`; do + if $i == $UPTO ; then + SEEN=1 + fi + if $SEEN == '0' ; then + message “Deleted old backup $i” + $RM -f $i + fi + done + fi

     fi
 }

@@ -622,21 +634,34 @@

     $RM -f $TOBLISTS/$2.incremental*
     gzip -c "$TMPLIST1" > "$TOBLISTS/$2.differential.gz"

- if -d "$BACKUPDIR" ; then + if $RSH_CMD -d "$BACKUPDIR" ; then

        UPTO=`basename $BACKUPDEV`
        SEEN='0'

- cd $BACKUPDIR - $RM -f ${VOLUMENAME}_*inc* - for i in `find ${VOLUMENAME}_*diff* -mtime +$MAXBACKUPAGE -exec echo {} \;`; do - if $i == $UPTO ; then - SEEN=1 - fi - if $SEEN == '0' ; then - message “Deleting old backup $i” - $RM -f $i - fi - done + if "$RSH_CMD" ; then + $RSH_CMD “cd $BACKUPDIR; $RM -f ${VOLUMENAME}_*inc*” + for i in `$RSH_CMD “cd $BACKUPDIR; find ${VOLUMENAME}_*diff* -mtime +$MAXBACKUPAGE -exec echo {} \;”`; do + if $i == $UPTO ; then + SEEN=1 + fi + if $SEEN == '0' ; then + message “Deleting old backup $i” + $RSH_CMD “cd $BACKUPDIR; $RM -f $i” + fi + done + else + cd $BACKUPDIR + $RM -f ${VOLUMENAME}_*inc* + for i in `find ${VOLUMENAME}_*diff* -mtime +$MAXBACKUPAGE -exec echo {} \;`; do + if $i == $UPTO ; then + SEEN=1 + fi + if $SEEN == '0' ; then + message “Deleting old backup $i” + $RM -f $i + fi + done + fi

     fi
 }

@@ -681,9 +706,9 @@

 verbose ()
 {

- if -d "$BACKUPDIR" ; then + if $RSH_CMD -d "$BACKUPDIR" ; then

       message "Generating report of $BACKUPDIR."

- for i in `$LS ${BACKUPDIR}/*`; do + for i in `$RSH_CMD $LS ${BACKUPDIR}/*`; do

        BACKUPDEV=$i
        eval "$LISTCMD"
       done

@@ -707,8 +732,8 @@

     FILESPEC=$3
     message "Restoring volume $VOLUMENAME files matching $FILESPEC into $startdir."

- if -d "$BACKUPDIR" ; then - for i in `$LS ${BACKUPDIR}/${VOLUMENAME}_*gz`; do + if $RSH_CMD -d "$BACKUPDIR" ; then + for i in `$RSH_CMD $LS ${BACKUPDIR}/${VOLUMENAME}_*gz`; do

           BACKUPDEV=$i
          eval "$RESTORECMD" && message "restored data from $i"
        done

</code>

tob.rc

This options have to be changed in the tob configuration file (tob.rc)

  -  set some variables to make customising the
  -  backup commands a bit easier
THROTTLE_CMD="cstream -t 1000000 -v2"
AESPIPE_PWFILE='/etc/tob/aespipe.pwd'
AESPIPE_OPTIONS="-p3 -eAES256 -C128"

  -  RSH_CMD: if set tob will use this command
  -  to manage backup files on a remote host
  -  (see tob patch)
RSH_CMD="ssh user@backup-server.org"

  -  DELETIONSCOMMAND needs RSH_CMD, too so set it after RSH_CMD is set...
DELETIONSCOMMAND='$RSH_CMD "cat >$BACKUPDIR/${VOLUMENAME}_${DATE}_${TYPE}_deletions"'

  -  special backup commands for remote, encrypted, throttled backup 
BACKUPCMD='afio $BLOCKSIZE $BUFFERBLK $GZIPFACTOR -o - < $FILELIST \
<code>
           | $THROTTLE_CMD \
           | aespipe $AESPIPE_OPTIONS 3< $AESPIPE_PWFILE \
           | su backup -c "$RSH_CMD \"cat > $BACKUPDEV\""'

BACKUPCMDTOSTDOUT='afio $BLOCKSIZE $BUFFERBLK $GZIPFACTOR -o - < $FILELIST' LISTCMD='su backup -c “$RSH_CMD \”cat $BACKUPDEV\”” \

         | $THROTTLE_CMD \
         | aespipe -d $AESPIPE_OPTIONS 3< $AESPIPE_PWFILE \
         | afio $BLOCKSIZE $BUFFERBLK -t -'

RESTORECMD='su backup -c “$RSH_CMD \”cat $BACKUPDEV\”” \

            | $THROTTLE_CMD \
            | aespipe -d $AESPIPE_OPTIONS 3< $AESPIPE_PWFILE \
            | afio $BLOCKSIZE $BUFFERBLK $GZIPFACTOR -viny"$FILESPEC" - '

VERIFYCMD='su backup -c “$RSH_CMD \”cat $BACKUPDEV\”” \

            | $THROTTLE_CMD \
            | aespipe -d $AESPIPE_OPTIONS 3< $AESPIPE_PWFILE \
            | afio $BLOCKSIZE $BUFFERBLK $GZIPFACTOR -r -'

</code>

aespipe.pwd

Creating a secure password for aespipe:

 head -c 1024 /dev/urandom | uuencode -m - | head -n 24 | tail -n 23 > /etc/tob/aespipe.pwd
 chmod 0600 /etc/tob/aespipe.pwd

This generates a password from 1024 random bytes and writes it into the file <i>/etc/tob/aespipe.pwd</i>

mschiff 13:26, 31 Mar 2005 (CEST)

linuxtips/secureremotebackup.txt · Last modified: 2012/01/14 05:03 by mschiff