pam_mount + EncFS

Index

Update: (2007-02-09) I noticed my files were being created with root ownership (ooops!) I've amended the script to correct this. I also inadvertly broke some of the internal links in this page :/

Introduction

Quick and dirty hack alert: The stuff here is a quick and dirty solution for a problem I faced. Since it has the potential of destroying important data don't trust this too much. And don't assume it's a good solution to the problem either.

As usual I'm rather verbose in the intro explaining what's everything and adding quite a bit of unneeded information, so you can skip to the next section safely 🙂

I recently wiped my laptop's disk and started from scratch. I did it because Windows would refuse to even try to load and I was in the mood of testing some more (possibly) laptop-friendly Linux distros such as Ubuntu or SUSE. Turns out my good old Debian, if a bit less flashy, is a lot more friendly to my laptop.

Anyway, I took the chance to switch to EncFS instead of dm-crypt (or rather on top, but the explanation of this would be lengthy :P). I wanted a fully encrypted home, mounted on login, just as I had before with dm-crypt + pam_mount. I figured pam_mount could be somehow made to use encfs. It proved rather tricker (and hackier) than what I expected so I'm posting here my experience and solution. Googling around didn't gave me any better solution (except maybe pam-encfs) so feel free to share your knowledge of better ways :).

EncFS

EncFS is an encrypted filesystem. Kind of. It sits on top of your filesystem and stores every file in a separate directory in encrypted form. When not mounted the separate folder contains gibberish-like files with gibberishy names. It uses fuse, so no tinkering with the kernel nor superuser privileges are needed to mount/umount/create it.

The main reason I switched to it, though, is flexibility. I can't know beforehand how many space my encrypted files will need but when using more traditional approaches (cryptoloop, dm-crypt, LUKS…) I'd need to allocate a certain, fixed, amount of disk to be encrypted. With this approach your encrypted stash will simply grow/shrink as needed.

It's apparently reliable and the performance hit is not something I've noticed (not yet at least).

pam_mount

pam_mount mounts one or more volume on login, and umounts them on logout. It's used often to mount encrypted and networked home directories; and it makes very easy using such kind of homes.

pam_mount vs EncFS

While pam_mount supports mounting fuse volumes, mounting encfs is a bit trickier: it will reject the typical format for mount options ('-o option[,option]') and won't pass them along to fuse unless flagged with a double dash ('-- -o option[,option]'), which can't be accomplished easily with pam_mount (as far as I can tell) and it must take the password from stdin (option -S).

Additionally there's a change of some boilerplate files present in the home directory before mounting so the nonempty option is almost required to be on the safe side.

I tried getting around these limitations to no avail (playing around the options' syntax, clumsily trying to provide an encfsmount command in pam_mount's configuration, etc.) and finally decided to provide a wrapper for the mount operation.

It has a good deal of caveats but it works (for me).

mount.whatever

In case you didn't know, mount, when asked to mount an unsupported filesystem (with the mount -t fstype syntax) will try to find a mount.fstype executable, and if present use it to mount the filesystem. In my tests it only looks in /sbin, though.

Ummounting probably works like this too (judging by the umount.* files in my /sbin) but it rarely works on my pam_mount's (it, wrongly, insists I have one more open session) so I can't say for sure.

So in pam_mount we can define an entry with filesystem encfs and provide /sbin/mount.encfs to handle it.

Symlinking it to the encfs executable is no solution, though, as the options would remain inappropriate. A wrapper is needed.

mount.encfs

Here's the wrapper (name it mount.encfs, place it in /sbin and make it executable):

#!/bin/sh

# Changelog:
#  2008-02-09: Changed "-o allow_other" to "--public" to correct file permissions
#  2008-02-07: Pusblishment
# Caveats:
#  * possible auto-ummount workaround: timeout umount (encfs feature)
#  * mounts with allow_other. This script is run as root and can't
#    su safely as that might imply loading pam_mount again (nothing
#    explodes, no infinite loop or anything, simply won't work)

# Lame debugging
# exec >/dev/shm/stdout 2>/dev/shm/stderr

# USER=`echo $@ | grep -o user=[a-z0-9]*`
# USER=`echo "$USER" | sed 's/^user=//g'`
# echo "I should be '$USER'"

ARGS=`echo "$@" | sed 's/-o/-- -o/'`
# Password passing failed on my first tests without
# re-passing it
read PW
echo $PW | exec encfs --public -S $ARGS

Things to note:

  • As commented in the script, it runs as root and there's no safe way, that I know of, to run su safely, so it must use the allow_other option from fuse (which allows other users to view the mounted filesystem). Note the correct permissions are retained.
  • As explained auto umount on logout doesn't work for me, but might do for you…

umount.encfs

As I've said before can't be sure if this thing works, but I guess it should be something like:

#!/bin/sh
fusermount -u $@

Name it umount.encfs, place it in /sbin and make it executable.

pam_mount configuration

Here a sample mount description, on login user john will have his encrypted home,
placed in /home/.john-encrypted, mounted in his home directory (~):


<volume user="john" fstype="encfs" path="/home/.john-encrypted"
        mountpoint="~" options="nonempty,user=john">

Good luck!
version 1.0 published Feb 7th 2008
update 1 published Feb 9th 2008

pam_mount + EncFS

  • cjk says:

    The correct way to use encfs — like any other fuse-based fs — is, in your case,:

    (try to read an unmodified pam_mount.conf.xml which contains tons of examples)

  • cjk says:

    …noting that the option passing issue has been resolved recently, too so that fstype="fuse" works reliably.

  • Toni says:

    Thank you!
    Is your first message missing something inbetween the two lines? (wordpress' admin section shows extra padding).

    I had read pam_mount's configuration and tried adapting the fuse examples but they failed to work, can't remember for sure why (I guess the option passing issue you mention was the problem).

    Indeed after an upgrade it appears to work although options doesn't seem to be received by fuse (at least it doesn't see the "nonempty"). Might be my version is not in sync with upstream, will have to take a deeper look ASAP.

  • cjk says:

    Yeah wordpress stripped the unaccepted tag. Be sure to check back with the mailing list, which is the authoritative place for rants and Q&A.

  • Toni says:

    I'll check ASAP.

  • cjk says:

    We are also aware of encfs 1.3 not accepting the standard mount syntax (this has been fixed in 1.4), which is why pam_mount >= 0.47 carries a special mount helper to workaround this; use fstype="encfs13" path="/dir" (instead of fstype="fuse" path="encfs#/dir") for this if you run an encfs of the 1.3 generation.

  • Toni says:

    Once again thanks 🙂 Can't reconfigure stuff right now, will give a try when possible.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.