Skip to content

Backup to an encrypted sparsebundle over AFP

François edited this page Mar 7, 2016 · 2 revisions

Also known as mimicking Apple's Time Machine© !

Overview

The goal is to backup some data on a remote encrypted sparsebundle, shared through AFP.

The server designates the host (can be a NAS, a MacMini or whatever you want, as long as it supports sparsebundle files and the AFP protocol) that holds the destination sparsebundle file.

The client designates the host from which we want to backup data.

The process is done in 5 steps :

  1. The client connects to the server and mounts the AFP share that contains the destination sparsebundle file.
  2. The client mounts the sparsebundle file.
  3. The client creates a new backup.
  4. The client unmounts the sparsebundle.
  5. The client disconnects from the server.

There are several advantages to use such a process :

  • Your backups are stored remotely ;
  • Your backups are encrypted ;
  • Since the destination is mounted locally, you can delete expired backups.

Prerequisites

Create the destination sparsebundle

On the client, as root, create an encrypted sparsebundle. You can use the Disk Utility app that comes with OSX, or you can use the WABAC Tools and call the osx_create_sparsebundle function. It will create the destination sparsebundle for you.

#!/bin/bash

source "./WABACMachine-tools.sh"

size="1000g"                # Change this to whatever you want/need. Here, 1000g = 1000GB = 1TB
encryption="AES-256"        # AES-256 or AES-128
volume_name="backup"
sparsebundle="/Volumes/afp_share/WABACMachineBackup.sparsebundle"
pass="my_Sup3r_passw0rDz!"

osx_create_sparsebundle "${size}" "${encryption}" "${volume_name}" "${sparsebundle}" "${pass}"

Place this sparsebundle file on a mounted AFP share (in the previous example, you would make sure that /Volumes/afp_share is a mounted AFP share).

Store passwords

On the client, you will need to store the password needed to connect to the AFP share and the password needed to decrypt the sparsebundle file. In this guide, I chose to store them in the System.keychain keychain. This is easy to achieve, thanks to the security command line tool.

To add an entry for the AFP share, run, as root:

security add-internet-password -a "username" -D "AFP Share Password" -s "server.local" -p "afp_share" -r "afp " -l "Description" -w "t0p5ecret+" /Library/Keychains/System.keychain

Of course, you have to replace username, server.local, share and t0p5ecret+ with your values.

To add an entry for the sparsebundle file, run, as root:

security add-generic-password -a "root" -D "Image Disk Password" -s "whatever.sparsebundle" -w "TopS3cret!" /Library/Keychains/System.keychain

Here again, replace whatever.sparsebundle and TopS3cret! with your values.

Create the preflight script

The preflight script will take care of the following :

  • Retrieve AFP share and sparsebundle credentials from the System keychain,
  • Mount the AFP share,
  • Mount the sparsebundle file.

Mine looks like this :

#!/bin/bash

source "./WABACMachine-tools.sh"
source "./WABACMachine-AFP-sparsebundle.conf"

preflight_run()
{
    local exit_code

    local sparsebundle_name
    local sparsebundle_pass
    local sparsebundle_mount_point

    exit_code=0

    # Mount the AFP share
    afp_user=$(osx_get_user_from_keychain_for_afp_share "${afp_host}")
    afp_pass=$(osx_get_pass_from_keychain_for_afp_share "${afp_host}")

    osx_mount_afp_share "${afp_host}" "${afp_share}" "${afp_user}" "${afp_pass}" "${afp_mount_point}"
    exit_code=$?

    if [ ${exit_code} -eq 0 ]
    then
        # Mount the sparsebundle
        sparsebundle_name=$(basename "${sparsebundle}")
        sparsebundle_pass=$(osx_get_pass_from_keychain_for_sparsebundle "${sparsebundle_name}")

        sparsebundle_mount_point=$(osx_mount_sparsebundle "${sparsebundle}" "${sparsebundle_pass}")
        exit_code=$?

        if [ ${exit_code} -eq 0 ]
        then
            # We overwrite the destination preference set in the config file :
            destination="${sparsebundle_mount_point}"
        fi
    fi

    return ${exit_code}
}

preflight_run

As you can see, I'm using the WABAC Machine Tools and another configuration file, where I store values related to this special case.

The WABACMachine-AFP-sparsebundle.conf file looks like this :

afp_host="server.local"
afp_share="backup"
afp_mount_point="/Volumes/backup"
afp_user=
afp_pass=

sparsebundle="${afp_mount_point}/backup.sparsebundle"

Feel free to adjust/modify it or to create your own, depending on your needs.

Create the postflight script

The postflight has to do the following tasks :

  • Unmount the sparsebundle file,
  • Unmount the AFP share.
#!/bin/bash

source "./WABACMachine-tools.sh"
source "./WABACMachine-AFP-sparsebundle.conf"

postflight_run()
{
    local exit_code

    exit_code=0

    # Unmount sparsebundle
    osx_unmount_sparsebundle "${destination}"

    # Unmount AFP share
    osx_unmount_afp_share "${afp_host}" "${afp_mount_point}"

    return ${exit_code}
}

postflight_run

As you can see, the WABAC Machine Tools makes it really easy to write.

Put the pieces together

Putting the pieces together is a little bit trickier, but still easy :

  1. Still on the client, mount the AFP share and the sparsebundle. The mounted point for the sparsebundle is your <destination> ;
  2. Initialize the WABACMachine : sudo WABACMachine.sh init <your_source> <destination> -c /path/to/your/config/file ;
  3. Unmount the sparsebundle, unmount the AFP share ;
  4. Edit your config file, and make sure to fill the preflight, postflight and rsync_path preferences. You'd probably need to also uncomment the rsync options that are related to HFS+ ;
  5. Run WABACMachine.sh backup -c /path/to/your/config/file, this will create your first backup ! Alternatively, you can conduct a dry-run if you are not confident ;
  6. Once everything run smoothly, automate the process.