Wednesday, July 13, 2011

Ignore at your own peril

On Monday, I lost my home directory on my primary development machine.  I'd had this machine for a couple of years but it was still beefy enough to be an excellent development box.  I've upgraded it several times with each new Ubuntu release, and it was running Natty.  I had decent sbuild and pbuilder environments, and a bunch of virtual machines for many different flavors of OS.

I'd also encrypted my home directory when I did the initial install.  Under Ubuntu, this creates an ecryptfs and does some mount magic after you successfully log in.  It's as close to FileVault as you can get on Ubuntu, and I think it does a pretty good job without incurring much noticeable overhead.  Plus, with today's Ubuntu desktop installers, enabling an encrypted home directory is just a trivial checkbox away.

To protect your home directory, ecryptfs creates a random hex passphrase that is used to decrypt the contents of your home directory.  To protect this passphrase, it encrypts it with your login password.  ecryptfs stores this "wrapped" passphrase on disk in the ~/.ecryptfs/wrapped-passphrase file.

When you log in, ecryptfs uses your login password to decrypt wrapped-passphrase, and then uses the crazy long hex number inside it to decrypt your real home directory.  Usually, this works seamlessly and you never really see the guts of what's going on.  The problem of course is that if you ever lose your wrapped-passphrase file, you're screwed because without that long hex number, your home directory cannot be decrypted.  Yay for security, boo for robustness!

When you do your initial installation and choose to encrypt your home directory, you will be prompted to write down the long hex number, i.e. your unwrapped passphrase.  Here's the moral of the story.  1) You should do this; 2) You should remember where you put that magic piece of paper!

I did #1 but failed to do #2.

I'm not exactly sure how my ~/.ecryptfs directory got corrupted, but somehow the wrapped-passphrase file got deleted.  I'm fairly certain that I didn't do it accidentally, but you never know.  I suspect that there was some bad interaction with sbuild because the only thing I'd done right before the corruption, was to update my sbuild environment, and build a package in it.  Note that if you follow the Ubuntu Security Team's instructions for setting up your sbuild (which I highly recommend), your unencrypted home directory will be exposed to sbuild's chroots.  This is very convenient for normal work-a-day package building.  However, it's possible that some bug in sbuild caused my ~/.ecryptfs directory to get corrupted.  That's only a wild guess though; I'm now rebuilding my dev box on a fresh 1.5T drive starting with Oneiric alpha 2, so we'll see if this bug bites me again.

This time, I'm prepared.  I stumbled upon a clever and secure way to never lose that piece of paper again.  This technique should also allow you to store and share other securely encrypted data across any of your Ubuntu machines.

The first step is to set up Ubuntu One.  You get 2GB of data free, so why not use it!?  I have U1 set up on all my Ubuntu desktops, and it's a great place to stash things you might need everywhere.  I've been considering storing things like my Firefox, Chromium, and Claws-Mail configs in U1 because I always want to keep them in sync.  I already store my Timelog Tracker data there, so I can enter my time and accomplishments from any desktop.

(I generally do not keep most of my configuration files in U1 since I keep them under Bazaar.)

Now, it would be a very simple matter of just creating a subdirectory under ~/Ubuntu One for each machine that has an encrypted home directory, and then just copy the contents of ~/.ecyptfs to that.  You need a separate subdirectory per machine because even if your login password is the same everywhere, that random hex number will be different.

You can do this today, but it may not be secure as you'd like, since the hex number that unlocks your encrypted home directory is "only" protected by your login password.  Crack the password, and if there's ever a security hole in U1 (or some other legal or illegal machinations) that manages to expose your wrapped-passphrase file, then your entire home directory is vulnerable.  For a little extra security, we can use encfs and fuse to create an unencrypted front-end to an encrypted directory inside U1.  You would then copy your ~/.ecryptfs files to the unencrypted mount, and it would get stored with an additional level of encryption (and obfuscation) to U1.  Now someone would have to crack two passphrases to get to your home directory.

The instructions on how to do this couldn't be simpler, and are outlined in this wiki article, and this one.  For the lazy (like myself), here are the steps:

$ sudo apt-get install encfs fuse-utils
$ sudo modprobe fuse
$ sudo adduser <your-login> fuse
$ sudo sh -c "echo fuse >> /etc/modules"
$ mkdir ~/safe  # or whatever, contents are plaintext
$ mkdir "~/Ubuntu One/safe" # or whatever, contents are encrypted
$ encfs "~/Ubuntu One/safe" ~/safe
# You will be prompted for a new encfs passphrase, this is your extra security
$ mkdir ~/safe/<your-machine>
$ cp -a ~/.ecryptfs/* ~/safe/<your-machine>

And now just let U1 do its synchronization magic.


  1. Great article Barry.

    This steps is broken as sudo in not active at the time the append happens:

    sudo echo "fuse" >> /etc/modules

  2. Thanks Brad; I fixed the text with the correct command.

  3. Barry, did you miss some quote marks around "Ubuntu One" in the shell commands at the end?

  4. Hi Barry, is the ~/UbuntuOne/safe thing working fine for you? I ask because a bit more than a year ago I tried syncing my ~/.Private (also ecryptfs) using U1 and it caused conflicts every time I created a new file there. The U1 team told me "cryptfs does some weird funky syscalls/fcntls on the files that we don't support, and that confuse the heck out of us", but maybe it's been fixed since then?

  5. echo fuse | sudo tee /etc/modules

  6. Hi Salgado. Note that I'm not syncing all of .Private, but just the metadata in ~/.ecryptfs, which I don't think actually changes at all.

  7. Why not just gpg --encrypt your wrapped-passphrase ?

  8. Right, but I thought you could have problems because your ~/UbuntuOne/safe would be the same as the old ~/.Private. That is, an encrypted dir which is mounted unencrypted somewhere else.

  9. @Jam: nothin' stoppin ya. :) I just thought it would be fun to have an encrypted U1 directory where I could drop random stuff, and this was the impetus for setting that up.

    @Salgado: I've only tested it in a limited way, but it does seem to work. YMMV ;)

  10. The other solution is to have backups :-) If you did you could just restore your home directory. Backups also protect you from failure of the drive (somewhat likely) and loss of the machine.

    On my laptop I deliberately do neither #1 or #2 since between IMAP email, remote repositories, cloud storage and backups I can always get anything back.

  11. Thanks Anonymous. Yes, I highly recommend doing backups too. I should mention that I actually lost very little because since it's a dev machine I had almost nothing on it that wasn't in a version control system somewhere (either locally or in public locations). I had one minor script that I've lost but think I can recreate. One problem here is that unless you've done full backups you might not thing to backup /home/.ecryptfs//.ecryptfs, which is where your wrapped-passphrase actually lives (i.e. ~/.ecryptfs symlinks to that).

  12. Just an update now that Ubuntu One has been discontinued. You can of course use any other file syncing technology like Dropbox or SpiderOak. I'm currently investigating the latter, based on its Zero Knowledge guarantees. If those are to be believed, then maybe you don't need all the extra machinery to encfs contents into the shared folder. OTOH, if you're particularly paranoid, then the extra encryption can't hurt. Just change the names of the folders and you should be good to go.