Private Backups with Duplicity

Overview

Backups are a must for everyone who stores data electronically. In fact, with the lowering cost of disk storage and fantastic instruction sets like this one. There is little to no excuse not to perform regular backups. However there is an issue which may arise in your backup solution, what if you don't trust the system administrator of your backup server.

A system administrator has complete access to all your files (at least the plaintext ones) regardless of the permissions (ACLs) you place. This is a great boon to you, the user, when you break something and need the sysadmin to repair it. However, it is a tremendous pain when you wish to keep something from the prying eyes of the sysadmin. As much as I would like to believe admins respect their users' privacy, I know better. I personally have witnessed admins reading personal files and emails. Needless to say, I no longer associate with those admins. So when backing up your data to a remote system you need two elements to protect your data's privacy. The first element is a means to encrypt the communications between your machine and the backup server. The second is a means to encrypt the data residing on the backup machine, never having the data exist on the backup machine in plaintext. Fortunately, such a solution exists in duplicity.

Duplicity is a backup utility which supports incremental encrypted network backups and GnuPG. Duplicty offers numerous methods to transfer files to the backup server. The ones which interest us for this discussion are ssh/scp and rsync. This can cover the encrypted transfer portion of our requirements. Duplicity covers the second portion through the use of gpg. Duplicity both encrypts and signs the tar archives containing our data. The encryption prevents the admin from reading our data and by signing the files, duplicity makes us aware of any tampering with the archive.


Source Machine Configuration

Installing Duplicity

The duplicity developers provided source tarball, i386 RPM and source RPM for installation. Also, Fedora, Debian and Ubuntu make duplicity part of their packages. The below instructions show how to install duplicity on Fedora using the yum utlity.

% sudo yum install duplicity

GPG Keys

We will use two gpg keys for the encryption of the backup files. The first key is the "encryption key" This key will protect the confidentiality of the backup data. The second key is the "signature key". This key will protect the integrity of the backup data. Duplicity will require the passphrase of the "signature key" be entered manually or stored in an environmental variable. Although duplicity will allow you to use one key as both the "encryption" and "signature" key, this model is not advisable. If an intruder roots your machine, the passphrase to unencrypt your backups will be in plain view.

The final security measure to protect the confidentiality of your backups is to ensure you keep the "encryption key's" private key somewhere safe and secure. My recommendation is to keep the private key on a USB thumb drive which you only connect to a networked machine if and when you need to decrypt your backups.

The example below shows how to create your duplicity encryption key. It is highly recommended you create this key on a machine not attached to the network or on one in which you are sure of its security. After creating the key pair, you may transfer the public key to the server by whatever means you prefer. I highly recommend scp. Once transferred to your server, you can import the public key as appropriate. Note the data below is merely an example, you need to configure the key to match your specific criteria.

% gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
(1) DSA and Elgamal (default)
(2) DSA (sign only)
(5) RSA (sign only)
Your selection? 1
DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)Press Enter
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sat 06 Jun 2009 07:02:34 PM CDT
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Patrick McDonald's Duplicity Encryption Key
Email address: marlowe@antagonism.org
Comment: Patrick McDonald's Duplicity Encryption Key
You selected this USER-ID:
"Patrick McDonald's Duplicity Encryption Key (Patrick McDonald's Duplicity Encryption Key) <marlowe@antagonism.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.
Enter your passphrase here
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++.++++++++++++++++++++++++++++++++++++++++++++++++++>+++++....+++++.........+++++ gpg: key B856BCB6 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2009-06-07
pub 1024D/B856BCB6 2008-06-07 [expires: 2009-06-07]
Key fingerprint = 0190 01E8 FF6D 2738 2348 5B56 2902 4E8B B856 BCB6
uid Patrick McDonald's Duplicity Encryption Key (Patrick McDonald's Duplicity Encryption Key) <marlowe@antagonism.org>
sub 2048g/D1E6FFDD 2008-06-07 [expires: 2009-06-07]

The next key you need to create is the "signing key". The same instructions as the "encryption key" apply. However in this case, you will need to transfer both the public and private key of the key pair to your server and import them as appropriate. The below example demonstrates the creation of the "signing key". As before, change the key's configuration to match your criteria not the example.

% gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
(1) DSA and Elgamal (default)
(2) DSA (sign only)
(5) RSA (sign only)
Your selection? 1
DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)Press Enter
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sat 06 Jun 2009 07:20:51 PM CDT
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Patrick McDonald's Duplicity Signing Key
Email address: marlowe@antagonism.org
Comment: Patrick McDonald's Duplicity Signing Key
You selected this USER-ID:
"Patrick McDonald's Duplicity Signing Key (Patrick McDonald's Duplicity Signing Key) <marlowe@antagonism.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.
Enter passphase here
We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. .+++++++++++++++++++++++++++++++++++++++++++++.++++++++++++++++++++.++++++++++.++++++++++++++++++++..+++++++++++++++++++++++++++++++++++>+++++.+++++>...+++++..........<+++++.....+++++
gpg: key F8EEFD30 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2009-06-07
pub 1024D/F8EEFD30 2008-06-07 [expires: 2009-06-07]
Key fingerprint = 1F55 40FF E627 D6A8 EC86 CCDD 9FCB 0B36 F8EE FD30
uid Patrick McDonald's Duplicity Signing Key (Patrick McDonald's Duplicity Signing Key) <marlowe@antagonism.org>
sub 2048g/D8A95430 2008-06-07 [expires: 2009-06-07]

You will need to remember the key IDs for your "encryption" and "signing" keys. You will need them when you configure duplicity-backup. In the above examples, the signing key's ID is F8EEFD30 and the encryption key's ID is B856BCB6.

Generating SSH Key

We will need to generate an SSH key to allow automated login to the backup server. We give the key an empty passphrase. The below example demonstrates creating the SSH key. Once we generate the key, you need to transfer the public key to the backup machine. You can use whatever means you prefer, once again scp is highly recommended.

% cd ~/.ssh
% ssh-keygen -t dsa -b 1024 -f id_dsa_duplicity_backup -C 'Duplicity Backup Key'
Generating public/private dsa key pair.
Enter passphrase (empty for no passphrase): Just hit ENTER
Enter same passphrase again: Just hit ENTER again
Your identification has been saved in id_dsa_duplicity_backup.
Your public key has been saved in id_dsa_duplicity_backup.pub.
The key fingerprint is:
8c:04:2c:f4:a4:c4:8d:6f:eb:aa:f4:f9:76:13:1a:f0 Duplicity Backup Key
Note: your key fingerprint will almost certainly be different from the example shown here.
% chmod 600 id_dsa_duplicity_backup


Backup Machine Configuration

Installing the Source Machine's SSH Public Key

In order for this solution to work, the system administrator needs to have configured SSH to allow for public key authentication. Once you confirm public key authentication is enabled, you need to configure the system to accept your private key. The below example assumes your public key is located in your home directory. Make sure to change the commands accordingly.

% cat id_dsa_duplicity_backup.pub >> .ssh/authorized_keys
% chown marlowe.marlowe .ssh/authorized_keys
% chmod 600 .ssh/authorized_keys
% rm -rf id_dsa_duplicity_backup.pub

Installing Duplicity-Backup

Next we need to install the backup script, duplicity-backup. I finally recommend you install this in your personal bin directory. The instructions below show how I installed duplicity-backup on my system. Make sure to change the commands as appropriate.

% cd ~/bin
% wget -c -O duplicity-backup http://www.antagonism.org/scripts/duplicity-backup.pl
% chmod 700 duplicity-backup
% chown marlowe.marlowe duplicity-backup

Configure Duplicity-Backup

Duplicity-backup requires the following variables to be configured:

Once these variables are set, all that remains to run the script. The below example demonstrates how to run the script. Note, the example assumes duplicity-backup is the user's $PATH.

% duplicity-backup
--------------[ Backup Statistics ]--------------
StartTime 1212857821.12 (Sat Jun 7 11:57:01 2008)
EndTime 1212857821.28 (Sat Jun 7 11:57:01 2008)
ElapsedTime 0.15 (0.15 seconds)
SourceFiles 2
SourceFileSize 6536 (6.38 KB)
NewFiles 2
NewFileSize 4096 (4.00 KB)
DeletedFiles 0
ChangedFiles 0
ChangedFileSize 0 (0 bytes)
ChangedDeltaSize 0 (0 bytes)
DeltaEntries 2
RawDeltaSize 1428 (1.39 KB)
TotalDestinationSizeChange 2230 (2.18 KB)
Errors 0
-------------------------------------------------

Run the first time, duplicity-backup will create a full backup. Each time after, it will create an incremental backup. Once you confirmed, duplicity-backup operates as expected, you can setup a cron job to run your backups as often as you like.


Other information

Duplicity allows you to verify the integrity of the files backed through duplicity as well restoring from the backups. These options and more are covered in the duplicity man page. The construction of scripts to automate this process is an exercise left to the reader.


Downloads

File: duplicity-backup.pl
Size: 3,220 bytes
Date: 2008-06-07 11:06:36 -0700
MD5: e9d118e15e97f0fe15f8fa04e6325200
SHA-1: 954d410ce0f5967b2dbb69bea7f307c725841d81
RIPEMD-160: 8974bc57f22f98db2428054de4edee6e5248b0ea
PGP Signature: duplicity-backup.pl.asc