Table of Contents

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:

Tools

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

Tools that I came across:

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)