Back up FileVault directories to a Linux server

Jun 02, '08 07:30:00AM

Contributed by: mikebremford

This is a fairly specific hint, but it might help someone trying to achieve the same thing. The goal: To back up a FileVault-protected home directory to a UNIX server, keeping the backup encrypted, and without logging off. Time Machine isn't an option, as it doesn't play well with Filevault. A previous hint I submitted does half the job, but the backups are stored unencrypted, so anyone with access to the server can read them.

The solution is to use EncFS on the server. This ensures files are stored encrypted (the password is stored in a file on the client, safely inside the FileVault protected home directory). Only SSH access to the server is required, no special encrypted volume is used (so the encrypted backup can easily be backed up itself), and root access is only required to install EncFS and add the user to the correct group. Here's what you need to do:

  1. Set up a user account on the server, and ensure you can log in from the client with SSH using a public key with no password.
  2. On the server, install EncFS. You will need at least version 1.4.
  3. On the server, ensure each user that will be backing up is a member of the "fuse" group, eg. usermod -a -G fuse mike
  4. If you want to back up files with resource forks or extended attributes, make sure the client and server are both running rsync version 3.0 (version 2.6.3 is included in 10.5). This compiles easily for OS X -- just download, ./configure and make, then put the rsync binary somewhere in your path. Do the same on the server.
Once that's done, you need to prepare the server. The setup I've chosen is a folder, /mnt/backup, which will contain all the backups for each user. Each user will have a folder in there called .user@hostname (note the dot), which contains the encrypted backup. As with FileVault, the decrypted version of this can then be mounted at user@hostname.

So, for example, to back up a user called "mike" on the host "macbook", do:

bash$ encfs /mnt/backup/.mike@macbook /mnt/backup/mike@macbook.local
The directory "/mnt/backup/.mike@macbook" does not exist. Should it be created? (y,n) y
The directory "/mnt/backup/mike@macbook" does not exist. Should it be created? (y,n) y
Creating new encrypted volume.
Please choose from one of the following options:
 enter "x" for expert configuration mode,
 enter "p" for pre-configured paranoia mode,
 anything else, or an empty line will select standard mode.
?> 

Standard configuration selected.

Configuration finished.  The filesystem to be created has
the following properties:
Filesystem cipher: "ssl/aes", version 2:1:1
Filename encoding: "nameio/block", version 3:0:1
Key Size: 192 bits
Block Size: 1024 bytes
Each file contains 8 byte header with unique IV data.
Filenames encoded using IV chaining mode.

Now you will need to enter a password for your filesystem.
You will need to remember this password, as there is absolutely
no recovery mechanism.  However, the password can be changed
later using encfsctl.

New Encfs Password: *****
Verify Encfs Password: *****
Now on the client, create a folder (we use $HOME/bin/backup), cd into it, and run the following command: echo secret > password; chmod 600 password, where secret is the password you used on the server. Then save the following file as backup, and chmod 755 backup (remember to change the host and path):
#!/bin/sh -x

REMOTEHOST=debian.local          # Host to back up to
REMOTEPATH=/mnt/backup           # Folder for all backups
REMOTEFOLDER=$USER@`hostname -s` # Subfolder in REMOTEPATH for this user on this machine
RSYNC=`which rsync`              # If you compiled rsync 3.x, set the path to it here.
RSYNCOPTS=-X                     # If you're not using rsync 3.x, comment out this line

BASEDIR=`dirname $0`
cd $BASEDIR
LOGDIR=$BASEDIR/logs
SERVICE=backup
/sbin/ping -t2 -m4 -q $REMOTEHOST >& /dev/null
if [ $? -eq 0 ] ; then
    AVG=`ssh $REMOTEHOST uptime | grep 'average: [1-9]'` &test -d $LOGDIR || mkdir $LOGDIR
    test -f EXCLUDES || cat  EXCLUDES
- /.fseventsd/
- .Trashes/
- .Trash/
- .TemporaryItems/
- .Spotlight-V100/
- /Library/*/Firefox/**/Cache/
- /Library/Caches/
EOF
    rm -f $LOGDIR/$SERVICE.3
    test -f $LOGDIR/$SERVICE.2 && mv $LOGDIR/$SERVICE.2 $LOGDIR/$SERVICE.3
    test -f $LOGDIR/$SERVICE.1 && mv $LOGDIR/$SERVICE.1 $LOGDIR/$SERVICE.2
    test -f $LOGDIR/$SERVICE   && mv $LOGDIR/$SERVICE   $LOGDIR/$SERVICE.1
    logger -i -p daemon.notice -t $SERVICE "Starting to '$REMOTEHOST'"
    test -r password && ERR=`ssh $REMOTEHOST encfs -S -i 1 $REMOTEPATH/.${REMOTEFOLDER} $REMOTEPATH/$REMOTEFOLDER &1` || {
        logger -i -p daemon.notice -t $SERVICE "Unable to mount $REMOTEPATH/$REMOTEFOLDER on $REMOTEHOST: $ERR"
        exit
    }
    $RSYNC -avx $RSYNCOPTS --exclude-from EXCLUDES --delete --delete-excluded --stats $HOME/ $REMOTEHOST:$REMOTEPATH/$REMOTEFOLDER > $LOGDIR/$SERVICE 2>&1
    tail -2 $LOGDIR/$SERVICE | logger -i -p daemon.info -t $SERVICE
else
    logger -i -p daemon.notice -t $SERVICE "Aborting - $REMOTEHOST not on local network"
fi
What this script does is: You can then run the script manually, or (better), set up a cron job to run this script whenever you want -- eg run crontab -e and add the following line
0 13 * * 1-5 $HOME/bin/backup/backup
To access the backed-up files on the server, simply log on and run encfs /mnt/backup/.user@hostname /mnt/backup/user@hostname. Enter your password and the files can be recovered.

[robg adds: I haven't tested this one...]

Comments (5)


Mac OS X Hints
http://hints.macworld.com/article.php?story=2008052909003014