Problem: you have a shared remote backup space and you want to backup sensitive data from your servers

There is a plenty of options out there, in my situation I have a Linux server with shell access where to take files and a shell account on BSD with 75GB of space where to put these files. I need to keep a daily copy of everything for a week. After some thinking and experimenting here is what I’ve got with “standard” tools available on the source host:

openssl, SSH, tar+bz2

first, I am going to use openssl smime encryption, so your milage may vary with different versions, my version is

$ openssl version
OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008

so first thing to do is to create self-signed certificate to use smime encryption, I’ve used SSH rsa key just to have less files to keep, but you can generate a separate one

openssl req -new -key .ssh/id_rsa -out .ssh/id_rsa.csr
openssl x509 -req -days 365 -in .ssh/id_rsa.csr  -signkey .ssh/id_rsa -out .ssh/id_rsa.crt

and your important files now are .ssh/id_rsa and .ssh/id_rsa.crt
now, for every day I will create a compressed tar archive with the name that includes weekday, like backup-Fri.tar.bz2 and will encrypt/transfer it like this:

cat backup-Fri.tar.bz2 | openssl  smime -encrypt -des3 -binary  ~/.ssh/id_rsa.crt | bzip2 | ssh remoteuse[email protected] "cat > backup-Fri.tar.bz2.enc.bz2"

needless to say you have to add .ssh/id_rsa.pub to the remoteuser’s authorized_kyes
and here comes the trade-off, after some ( not very scientific) experiments the best file size I’ve got is from this pipe:

 tar | bzip | enc | bzip

which gives me this unencrypted/encrypted files sizes ratio:

66M    bckAll-Fri.tar.bz2
67M    bckAll-Fri.tar.bz2.enc.bz2

YMMV here, it depends on your file content and so on. Besides it consumes CPU. So you can play around with the sequence.
To conclude, here is the script I launch every night:

#!/bin/bash
PATH=$PATH:/usr/bin:/usr/sbin
bpath=/srv/backup
day="`date +%a`"
dbpass=pass
bckdirs="/etc /srv/www/site1 /srv/www/site2"
mkdir $bpath/bckAll-$day
for d in $bckdirs; do
        cd $d/..
        tar cpf $bpath/bckAll-$day/`basename $d`.tar --exclude="logs" $d
        cd - >/dev/null
done
cd $bpath
mysqldump -u root -p$dbpass --all-databases > bckAll-$day/all-databases.sql
tar cjpf bckAll-$day.tar.bz2 bckAll-$day
rm -fr bckAll-$day
cat bckAll-$day.tar.bz2 | openssl  smime -encrypt -des3 -binary  /home/user/.ssh/id_rsa.crt | bzip2 | 
        ssh -i /home/user/.ssh/id_rsa  [email protected] "cat > bckAll-$day.tar.bz2.enc.bz2"

this one is not error proof so up to you to add try/catch wrappers

hope it is useful 🙂

Post Navigation