Linux:dm=crypt Encrypted Home Directories

There are three primary methods for encrypting one’s home directory seamlessly in Linux: dm-crypt, eCryptFS, and EncFS. All differences aside, this post will cover dm-crypt (as indicated by the title of course). A few things to note before going forwards though. First, this method is by no means the standard. I’m not even sure if there is a standard way to do this. This is just the way I’ve done it and it has worked out swimingly thus far on more than one computer. Secondly, my method detailed here will use something called LUKS. I highly recommend this, if not just for convenience. While it does have its pitfalls, they shouldn’t be too bad if you keep a backup of your data. Really though, when encrypting, you should always keep more than one copy of your data in case something goes awry.

Before proceeding, here is a list of what this will give you once completed, so you can decide if this is what you want before reading this monolithic post .

  1. Users will each have their own encrypted home directory.

    • Each home directory will be unlocked using the user’s own password.

    • Users have complete storage anonimity. Even root can’t tell how many files they are storing, filenames, or even how much data they have unless the user is logged in at the time of inspection.

  2. User’s home directories will be seamlessly decrypted and mounted at login.

  3. Users will have their own virtual device, so they will have a storage "quota". To expand it, the virtual device needs to be extended on its own (some might consider this cumbersome).

Setup

This should be relatively simple. Install a package likely called cryptsetup (most of the mainstream distros should have it). This is the utility we will be using to manage dm-crypt volumes. Note also that cryptsetup can be used for managing more than just dm-crypt and luks. It also works with Truecrypt (much to my excitement a few months ago when I needed to extract some data from a Truecrypt volume, but didn’t want to install it becuase of all the suspicion surrounding it lately).

Modifying PAM

/etc/pam.d/system-auth

This piece assumes your distribution puts this file here and that it is named this. Unfortuantely, I can’t really write this part to be distribution-agnostic as most of them do this differently to an extent. The contents of the file will likely look similar, despite its name. For anyone wondering though, this section is written from an Arch Linux instance.

Open /etc/pam.d/system-auth in your favorite editor. Be sure to do this either with sudo or as root or you won’t be able to save your changes.

Here we need to put in calls to a module called pam_mount.so so it will be called at the right time to pass the user’s password to the mount command, allowing for seamless encrypted home directory mounting. Pay attention to where the calls to pam_mount.so are. Order is very important in this file.

Note
Many distributions use eCryptFS as their default encryption for home directories. They do it this way as well, but using pam_ecryptfs.so instead of pam_mount.so.
/etc/pam.d/system-auth
#%PAM-1.0

auth      required  pam_unix.so     try_first_pass nullok
auth      optional  pam_mount.so
auth      optional  pam_permit.so
auth      required  pam_env.so

account   required  pam_unix.so
account   optional  pam_permit.so
account   required  pam_time.so

password  optional  pam_mount.so
password  required  pam_unix.so     try_first_pass nullok sha512 shadow
password  optional  pam_permit.so

session   optional  pam_mount.so
session   required  pam_limits.so
session   required  pam_unix.so

session   optional  pam_permit.so

/etc/security/pam_mount.conf.xml

This is the configuration file used by pam_mount when the user logs in. Depending on your distribution, it may or may not already be set up the way we need for this.

Just before the </pam_mount> at the end of the xml file, insert the following lines.

/etc/security/pam_mount.conf.xml
...

<volume fstype="crypt" path="/home/.%(USER)" mountpoint="/home/%(USER)" options="space_cache,autodefrag,compress=lzo" />
<mkmountpoint enable="1" remove="true" />

</pam_mount>

Before proceeding, there are a couple of assumptions that I need to mention about the way I do this here.

  1. My home directories are all formatted with btrfs. If you’re not using that, then remove the autodefrag,compress=lzo piece in the options section.

  2. The encrypted block device files are located at /home/.USERNAME (note the dot).

Creating an Encrypted Home Per User

The creations of each user’s home directory has a few fairly simple steps [if you’ve been using linux command line for a bit]. For the sake of more succinct directions, here we will assume a username of kevin.

  1. Allocate user’s encrypted home space (assuming 15 gigs)

    • dd if=/dev/zero of=/home/.kevin bs=1G count=15

    • This command writes 15 gigabytes of zeros to one file, /home/.kevin

  2. Encrypt the user’s home device

    • cryptsetup luksFormat /home/.kevin

    • This command will require the user to enter their password when prompted after running the command, as that will be what is passed to the file container on login.

  3. Open the user’s new home device (you’ll need the user to enter their password again)

    • cryptsetup luksOpen /home/.kevin kevin

    • This will only be needed the first time around. Kevin can’t use this yet becasue it doesn’t have a filesystem and it can’t be mounted for the same eason.

  4. Format the opened dm-crypt device

    • mkfs.btrfs /dev/mapper/kevin

    • This is assuming you want to use btrfs. Otherwise you’d use mkfs.ext4 or some other filesystem of choice.

  5. Cleanup

    • cryptsetup luksClose kevin

    • In this case, kevin can be the alias given to the opened device on luksOpen. You can also provide its path at /dev/mapper/kevin.

How it Works

When a user logs in, they type their username and password. Those are passed to pam, which verifies the user’s identity using the pam_unix.so module. If the credentials provided by the user are correct, the next step is to pass that username and password to the pam_mount.so module. This module runs the commands dictated in the pam_mount.conf.xml. The commands pam mount runs (as per our earlier configuration) are effectively

cryptsetup luksOpen /home/.$\{username} _home__$\{username} mount /dev/mapper/_home__$\{username} /home/%\{username}

Those commands open the dot file (/home/.username) for the given user with the recently provided password. It then mounts that user’s decrypted dot file at the user’s home directory (/home/username).

Backups

This kind of encryption makes backups a bit difficult to pull off as the administrator. Because you don’t have each user’s password, you can’t back up their data. This leaves you with one option - back up the encrypted block devices themselves. Depending on how much space each user is given, this can take a long time (though rsync helps significantly with that) and a lot of space. This is the downside to block device encryption. Stacked encryption though, while rumored to be less secure for various reasons, allows administrators access to encrypted verions of each user’s data. With stacked encryption, each individual file’s contents are encrypted, but the user’s filenames, paths, and file sizes are still accessible to the administrator(s) (hence the rumored security flaw).

As a user though (if you’re using this on your laptop for instance), backups are simple because the data itself is available to you (you have the password after all). This however assumes you have user rights on a remote server to rsync your data to. Even if the remote server has the same dm-crypt setup, rsync still sends your credentials, so your data can go from an encrypted laptop/desktop to an encrypted server.

Category:Storage Category:Security Category:Linux