pam_mount + EncFS
- Introduction + Update
- pam_mount vs EncFS
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 :/
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 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 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).
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.
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…
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.
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">
version 1.0 published Feb 7th 2008
update 1 published Feb 9th 2008