November 6, 2008

Automatically mount encrypted filesystems at login with pam_mount

Author: Ben Martin

The pam_mount project lets you unlock an encrypted filesystem automatically when you log in. The same password used to log in is used as the key to unlock the encrypted filesystem, so you only need to type it once. Using this method, you can easily share a laptop and have only a single user's home directory unlocked and mounted when he logs in. And pam_mount can mount any filesystem, not just encrypted filesystems, so you can use it, for example, with an NFS share that you are interested in but which you might not like to leave mounted when you are not logged in.

We've written about other alternatives for providing encrypted filesystems, such as EncFS and Loop-AES, dm-crypt, and Cryptmount, but pam_mount makes the whole process seamless.

Last month the project made a major version jump from 0.49 to 1.2, so don't be too alarmed if your distribution is still offering older code. The distribution repositories for Fedora 9 include pam_mount and it is available as a 1-Click for openSUSE 11. Ubuntu Hardy packages it as libpam-mount. I installed version 0.48 from the Fedora repositories on a 64-bit Fedora 9 machine, but I also tested version 1.2, and it worked exactly the same way. The only change needed (shown below) was that I had to tell mount.crypt which cipher was used:

# vi /etc/security/pam_mount.conf.xml
...
<cryptmount>mount.crypt -o cipher=aes "%(ifnempty=\"-o\" OPTIONS)" %(OPTIONS)
%(VOLUME) %(MNTPT)</cryptmount>

I used a LUKS encrypted volume as an example of pam_mount usage. Although I am using a partition to contain the encrypted filesystem, you can also use a single file mounted through a loopback device if you do not have a spare partition.

To get started, as you'll see in the code below, I formatted /dev/sdc1, destroying all of the data on that partition in order to make a new encrypted volume. I name this encrypted volume myencryptedstuff and create an ext3 filesystem on it. After mounting that filesystem and creating a trivial file I unmount it again and locked the encrypted volume. I then used mount.crypt from the pam_mount package to unlock the encrypted volume and mount it at /mnt/t. As the mount.crypt command is what pam_mount uses to mount a filesystem, it is convenient to try it from the command line first to verify that things work. Finally, I ran the umount.crypt command, which umounts the filesystem and then relocks the encrypted volume. These two actions are the equivalent of the umount and cryptsetup luksClose commands.

# cryptsetup luksFormat /dev/sdc1

WARNING!
========
This will overwrite data on /dev/sdc1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase:
Verify passphrase:
Command successful.

# cryptsetup luksOpen /dev/sdc1 myencryptedstuff
Enter LUKS passphrase for /dev/sdc1:
key slot 0 unlocked.
Command successful.

# mkfs.ext3 /dev/mapper/myencryptedstuff
mke2fs 1.41.0 (10-Jul-2008)
...

# mount /dev/mapper/myencryptedstuff /mnt/t
# date > /mnt/t/df1.txt
# cat /mnt/t/df1.txt
Mon Oct 27 09:20:22 EST 2008

# umount /mnt/t
# cryptsetup luksClose myencryptedstuff

# mount.crypt -o cipher=aes /dev/sdc1 /mnt/t
# umount.crypt /mnt/t

As the name pam_mount implies, the project works with the Pluggable Authentication Modules system used for authentication on Linux systems. Linux.com has covered PAM in detail in past articles; interested readers should see Understanding PAM, Let PAM take care of GNU/Linux security for you, and Hardening the PAM framework for more details on PAM itself.

In a nutshell, PAM reads files for services from /etc/pam.d and performs actions (such as denying service) when somebody attempts to use those services. For example, /etc/pam.d/login controls what needs to happen for somebody to log in to your system. The pam.d files control not only what happens for authentication but also how to set up the initial session for the service.

Each line in one of the files can tell PAM if the action defined for that line is required to succeed, is optional, or if it succeeds then PAM should stop there and assume success. This last type of entry is called "sufficient"; you must have your new pam_mount entry before such a line to ensure that pam_mount always gets a chance to execute.

PAM also has support for grabbing passwords from the user. Each line can tell PAM that it wants a password and whether to reuse a password that has already been obtained from the user (use_first_pass), or to reuse a password if one has already been obtained, or prompt for one (try_first_pass). This is handy because, if you use try_first_pass and two lines in the PAM authentication part for a service, the authentication services called from both of the PAM lines will want a password, but PAM will make it so you'll only get prompted once.

You configure pam_mount itself in /etc/security/pam_mount.conf.xml. The XML file defines how various helper programs are invoked, the owner of mounted filesystems, whether users are allowed to have their own pam_mount configurations, and a collection of volume elements that tell pam_mount how to actually mount things. One option you might like to set while testing is <debug enable="2" /> which will produce information in /var/log/messages telling you what happens when you try to authenticate so you might be able to fix a configuration issue.

I prefer to use per-user configurations rather than lumping everything into /etc/security/pam_mount.conf.xml. With per-user configuration each user gets the ability to set up their own encrypted volumes and bind mounts. Per-user configuration files are disabled by default; to enable them, add or uncomment the following line:

<luserconf name=".pam_mount.conf.xml" />

The per-user configuration file is shown below for the ben user on my system. The configuration file will mount the encrypted LUKS filesystem created above in a subdirectory of my home directory. Specifying that the filesystem type (fstype) is crypt tells pam_mount to mount and unmount the filesystem with the mount.crypt commands. The only other two things you need to specify are where the encrypted volume is (/dev/sdc1) and where you want to mount it (~/protected).

$ cat /home/ben/.pam_mount.conf.xml
<?xml version="1.0" encoding="utf-8" ?>

<pam_mount>

<volume fstype="crypt" path="/dev/sdc1" mountpoint="~/protected" />

</pam_mount>

The only tasks left are to edit your /etc/pam.d files to actually call pam_mount so that your encrypted filesystem is mounted when you want it, and possibly change one filesystem permission setting. In the /etc/pam.d/gdm file, which controls the GNOME Display Manager graphical login utility, the two lines I added are shown in bold below:

# cd /etc/pam.d
# cat gdm
#%PAM-1.0
auth optional pam_mount.so try_first_pass
auth [success=done ignore=ignore default=bad] pam_selinux_permit.so
auth required pam_env.so
auth substack system-auth
auth optional pam_gnome_keyring.so
account required pam_nologin.so
account include system-auth
password include system-auth
session optional pam_mount.so
session required pam_selinux.so close
session required pam_loginuid.so
session optional pam_console.so
session required pam_selinux.so open
session optional pam_keyinit.so force revoke
session required pam_namespace.so
session optional pam_gnome_keyring.so auto_start
session include system-auth

Because I was mounting an entire partition as an encrypted volume, I had to also change the ownership of that partition with chown ben.disk /dev/sdc1 so that pam_mount would work.

Once I completed all of that, I logged in at gdm I found that ~/protected was unlocked and mounted for me automatically. I started an SSH session from another machine before I logged in with gdm and kept it open when I logged out. On logout, ~/protected was unmounted and the encrypted volume was locked again automatically.

Keep in mind that you can use pam_mount to mount filesystem types like NFS, FUSE, and bind mounts. Put simply, a bind mount makes a filesystem available at two different paths at the same time. With per-user configuration files enabled you can rearrange how the filesystem looks automatically on login. Bind mounts can be handy when you have multiple NFS mounts with paths that you use often. For example, the below example makes a longer path from an NFS mount available directly under my home directory.

<volume path="/Fileserver2007/Docs/ben" mountpoint="~/docs" options="bind" />

Caveat

Fedora systems use authconfig to update some of the /etc/pam.d files. In particular, the system-auth file is called by many other files. Other Linux distributions probably have similar tools to authconfig. When authconfig runs, it can undo some of your pam_mount configuration by overriding some files in /etc/pam.d to save its changes. To make sure that doesn't happen, you'll have to make sure you edit only the files in /etc/pam.d that your system tools do not assume they can clobber. The main thing to investigate and keep in mind is which of the /etc/pam.d files are overwritten by such tools. For example, system-auth states that it will be overwritten and not to edit it. In this case that wasn't an issue because we focused on a single service and didn't edit system-auth.

With pam_mount you can have filesystems mounted and unmounted automatically at login and logout times. If you use a single password for login and to unlock an encrypted filesystem volume, you can set up the system so you only have to type your password once and have your personal documents protected by encryption when you are not logged in.

Categories:

  • Security
  • System Administration