Too much time and an unencrypted hard disk on a notebook, lying next to me, are enough reasons to find a comfortable solution to encrypt single user home directories.
The basic setup looks like:
- encrypt a container file or partition with dm-crypt
- use openssl to encrypt the needed keyfile
- configure pam_mount to automatically mount the home dir on login
After you have read some howto‘s about using dm-crypt you should have an usable kernel running. Now it’s time to install the packages we need with the following commands:
doep ~ # emerge -av sys-fs/cryptsetup doep ~ # emerge -av sys-auth/pam_mount
Because I couldn’t use a whole partition for the home dirs, I hat to use a container file instead. Depending on the container size, the creation takes a bit, so relax.
doep ~ # dd if=/dev/urandom of=/home/doep.img bs=1M count=2048
After the container was written, you have to create a loop back device for it. If loop0 is already taken, use the next available one, but remember on later commands 😉
doep ~ # losetup /dev/loop0 /home/doep.img
As mentioned before, the container will be encrypted using a key file. This key file we have to encrypt with the user’s password. The regexp stuff removed the \n at the ending, otherwise you can get some problems mounting the device.
doep ~ # KEY=$(tr -cd [:graph:] < /dev/urandom | head -c 1024) doep ~ # echo $KEY | perl -pe 's{\n}{}gs' | openssl aes-256-cbc > /home/doep.key doep ~ # chown doep:doep /home/doep.key doep ~ # chmod 0400 /home/doep.key
Now we can start formatting the container with cryptsetup. With cat /proc/crypto you can see, which ciphers are available on your system. If your preferred one is missing, change your kernel config. After everything went fine, you should have a new mapper device in /dev/mapper/doep.img; you also can delete the plain-text key now.
doep ~ # echo $KEY | cryptsetup luksFormat -c aes-cbc-essiv:sha256 -s 256 /dev/loop0 doep ~ # echo $KEY | cryptsetup luksOpen /dev/loop0 doep.img doep ~ # KEY=""
This mapper device can now be formatted with your preferred filesystem, ext4 in my case. If you want, you can test if the filesystem is mountable. Then remove the LUKS mapping with cryptsetup and the loop device.
doep ~ # mkfs.ext4 /dev/mapper/doep.img doep ~ # mount /dev/mapper/doep.img /home/doep_new doep ~ # umount /home/doep_n doep ~ # cryptsetup luksClose doep.img doep ~ # losetup -d /dev/loop0
Now we need to configure the pam_mount plugin to automatically mount the user directory if a new session starts. Therefore add the to lines to your /etc/pam.d/login file
session optional /lib/security/pam_mount.so auth optional /lib/security/pam_mount.so
and add this entry to the <pam_mount> section in the /etc/security/pam_mount.conf.xml file. if you used different ciphers earlier, specify them here.
<volume fstype="crypt" user="doep" options="loop,cipher=aes-cbc-essiv:sha256" mountpoint="/home/%(USER)_new" path="/home/doep.img" fskeycipher="aes-256-cbc" fskeypath="/home/%(USER).key" fskeyhash="md5" />
Now switch to VT and try to login. You will get some verbose output but your container file should be mounted.
doep ~ # df -h Filesystem Size Used Avail Use% Mounted on /dev/loop0 2.0G 35M 1.9G 2% /home/doep_new
If you got some errors, try to mount the container manually with mount.crypt_LUKS to locate the error.
doep ~ # mount.crypt_LUKS -v -ov -o keyfile=/home/doep.key -o fsk_cipher=aes-256-cbc -o fsk_hash=MD5 /dev/loop0 /home/doep_new
If everything works, you can move your files into the container and then replace /home/doep_new with your real $HOME. To work with your desktop manager (XXX), also add the 2 lines you added to /etc/pam.d/login to /etc/pam.d/XXX.