Howto configure encrypted home directories under Linux

To get an encrypted home directory under Debian Linux, only a few steps are necessary. The performance hit for the encryption is, at least for current processors and normal (i.e. slow compared to all other PC components) harddisks, negligible. This howto describes the necessary configuration options for automatically mounting the encrypted volume at login and unmounting it again afterwards. First of all, you need the following packages to be installed on your Debian system (or on other distributions, but I don’t know the package names for them):

  • libpam-mount (>= 0.9.25-3): This PAM module takes care of mounting and unmounting. The version really must by at least 0.9.25-3, because that version introduced the LUKS support.
  • cryptsetup (>= 1.0): For configuring encrypted mounts using the dm-crypt device mapper target of newer kernels.
  • A kernel version >= 2.6.10 is recommended for best support.

You then need the following configuration options:

  • In /etc/security/pam_mount.conf add a line: “volume * crypt - /home/.&.img /home/& loop - -”. This line allows every user who has a corresponding crypted container /home/….img to automatically use an encrypted home. For newer versions of pam_mount that use an XML config file format, the line should read “<volume options=“loop,noatime” user=”*" mountpoint="/home/%(USER)" path="/home/.%(USER).img" fstype=“crypt” />"
  • In /etc/login.def: “CLOSE_SESSIONS yes”
  • In /etc/pam.d/login: add a line “@include common-pammount” directly after the line “@include common-session”. Do the same for all other login methods you use, e.g. kdm, gdm or ssh.
  • In /etc/modules: Add the two modules “dm-crypt” and “aes” as new lines.

And then initialize the crypted container for each user with (this example assumes a user name “rene”, adapt to the user you want to use):

  • dd if=/dev/urandom of=/home/.rene.img bs=1024 count=20000000
  • losetup /dev/loop0 /home/.rene.img
  • cryptsetup -c aes-cbc-essiv:sha256 -s 256 –verify-passphrase luksFormat /dev/loop0
  • cryptsetup luksOpen /dev/loop0 cryptedhome
  • mkfs.xfs /dev/mapper/cryptedhome
  • cryptsetup luksClose cryptedhome

You will probably want to adjust the size of the encrypted home directory container too (I set it to ca. 20GB in this example).

One of the major advantages of using LUKS instead of plain loopback encryption (that is, besides being more secure), is that the password can be changed easily without re-encrypting the whole volume. You just need to execute:

  • cryptsetup luksAddKey –verify-passphrase /dev/loop0
    This asks for the previous password and then (twice) for the new one.
  • cryptsetup luksDelKey /dev/loop0 0

It should be noted that the device must already exist (it’s completely ok to have the volume mounted while doing that, because the loopback device will have been created by mounting the encryption volume then). For deleting the key slot, it depends on how often the password has been changed. When executing the first command (the luksAddKey), it will tell which key slot has been used to unlock the master key. In the second line, this number should be used to delete the original key.

Attention: It is recommended to double-check while typing the new password. After removing the previous key, there will be no way of opening the volume if there has been a typo. I usually add a second key just for testing by executing luksAddKey again, this time using the new password, before deleting the previous key (and then of course delete the second, temporary key as well). You could also try to log off and log in again with the new key before removing the previous one.

More information can be found at the LUKS homepage at http://luks.endorphin.org/dm-crypt.

Update: ecryptfs

Since quite some time already, there is a new option for filesystem encryption: ecryptfs, integrated with the upstream Linux kernel since 2.6.19. In contrast to the LUKS option described above, ecryptfs works on the filesystem instead of on the block level, acting as a stacking filesystem. This has the following advantages:

  • Dynamic size of the encrypted tree: The size of the encrypted part does not need to be fixed in advance but files are transparently written to the underlying filesystem.
  • Files can be encrypted with multiple keys so that multiple different users can have access to encrypted (but shared) files.
  • It is possible to access the “lower” encrypted files and copy these anywhere (e.g. on a USB stick or send via email). On the target system, they can be decrypted if the ecryptfs key is known.

In comparison to block-level encryption, it has the following disadvantages:

  • Filename encryption is only available on newer kernels and with newer ecrypts user-space tools. This should not be a problem with distributions having released in 2010 or later, but it is something to take care of.
  • Even with filename encryption, certain patterns (such as a typical distribution of file size in a directory) will always give a clear hint of what is being stored, even if it is encrypted. ecryptfs is therefore not a good idea if you want to hide the fact that something is stored.

There are of course similarities between the LUKS and ecryptfs approaches, e.g. that both use the in-kernel crypto implementations and therefore strong cryptography. If you loose your key (or password for the key) with either of them, you’re screwed. Furthermore, both get mounted at some directory for transparent access by all applications, and both can be integrated with PAM for re-using the login password to mount the encrypted tree. LUKS integration with PAM (via pam-mount) currently allows to transparently mount the whole user directory so that all user files will be transparently encrypted (as described above), while the ecryptfs PAM module does not support this easily (it depends on configuration files in ~/.ecryptfs, so mounting over ~ is tricky).

Update: I am now using ecryptfs to encrypt the home directory on both my laptop (Lenovo Thinkpad X201s) and work desktop (a generic Dell something machine). The most recent Debian/Ubuntu package ecryptfs-utils now includes support to easily encrypt the whole user directoy with Ubuntu being a step farther than Debian and already supporting this with an option to the adduser utility. To set up a user account for full-home encryption, simply use:

  • ecryptfs-setup-private -u <your user name> -b

as root to call the “bootstrap” mode for setting up another user’s home directory. On first login of this user, their login password is wrapped and stored in .ecryptfs. Although opton “-a” should also accomplish this, I was not successful calling this as the logged-in user (chicken-and-egg problem, I guess).

René Mayrhofer
René Mayrhofer
Professor of Networks and Security & Director of Engineering at Android Platform Security; pacifist, privacy fan, recovering hypocrite; generally here to question and learn