Decrypt home partition on login (6 min. read)

Posted on

After switching to systemd a while back, I have been annoyed by having to enter the decryption key for my /home partition on every boot. My root partition is unencrypted, as are all the other partition except /home, but having to enter the key makes the boot process seem slower than it really is since the password prompt appears in a plain white-on-black tty. Also, due to the concurrent nature of a systemd boot, the password prompt is often intermangled with other boot messages. This happens even with the “quiet” boot parameter since fsck results are still printed. For a while I tried to ignore the problem, but one lazy afternoon I decided to come up with a somewhat prettier solution.

Before I get into the exact details, let me start off with my base configuration and what I wanted to achieve:

Configuration

Note that none of these are requirements for the solution I am going to give below apart from the encrypted home partition. Also, it is worth pointing out that my solution is in no way specific to my login manager, my DE (or lack thereof) or anything else except GTK and dm-crypt (and by extension cryptsetup).

Target boot process

  1. System boots
  2. systemd starts all daemons and filesystems EXCEPT /home normally
  3. systemd boot process completes without user intervention
  4. Login manager or login prompt is displayed (yes, this solution can work without a login manager)
  5. An X session is started for a user
  6. Upon login, a password prompt is displayed
  7. Upon typing the correct password, the encrypted home partition is decrypted and mounted
  8. Any user .xinitrc is executed, starting whatever WM/DE and other applications the user wants

Solution

OK, so now that we have gotten the prerequisites and our goals out of the way, let us see how we can accomplish this.

Before digging into the nitty-gritty details, here is a high-level sketch of the solution for the impatient:

Challenges

The nitty-gritty

Although there may be many ways of solving the above, I have decided to solve it by writing two simple applications in C, crypsetup-gui and cryptsetup-gui-gtk. The latter displays a password prompt and, upon the user pressing Enter, prints this password to stdout. The former takes the name of an encrypted partition, looks through /etc/crypttab to find the real disk partition, displays the password prompt by spawning cryptsetup-gui-gtk, calls cryptsetup with the correct parameters to decrypt it, mounts the partition according to /etc/fstab and then returns a value depending on whether all the operation succeeded or not.

To overcome the first problem, I opted for using the setuid bit rather than using sudo both to avoid having a dependency on sudo, but also to prevent system administrators from having to grant sudo rights in order to execute the program. I believe the implementation of cryptsetup-gui should be safe enough to not open any security holes, but please read the README and the code to make sure yourself!

Solving the second problem now becomes very easy, since cryptsetup-gui can simply drop its permissions by setting the effective UID = real UID before opening the password prompt, allowing cryptsetup-gui-gtk to execute with no special permissions.

The third problem is not so much a problem as something one must consider. Fixing it is merely a matter of remembering to copy the .Xauthority file to some temporary location before mounting and then moving it back after mounting.

During the development of this small set of tools, some unanticipated problems did arise:

Luckily, all of these have been overcome, and they are usually mentioned in the source code.

Getting it!

If you’re so lucky you’re also running Arch Linux, I’ve posted all the needed files in the package cryptsetup-gui in the AUR. This will install everything in the correct places, with the correct permissions, except for the bootstrap .xinitrc which you will need to put in place yourself (instructions are provided on install).

On other distributions, install should not really be all that difficult either. Download the source code from GitHub, run make install, or optionally make DESTDIR=/some/directory install if you want to sandbox it, and make will put all the files in the correct places and set the right permissions. Note that this will not let you easily remove the application again. For that, feel free to create a package if you know how, or otherwise ask someone to do it for you. It should be fairly straightforward. The program also only depends (AFAIK) on glib2 and cryptsetup, but if you find any others, let me know!

The only action required after installing cryptsetup-gui or running make install is to put a copy of the .xinitrc bootstrap file (which make install puts in /etc/skel/.xinitrc-cryptsetup-gui) in the unmounted home directory of the users you want to be able to mount /home on boot. This process is fairly straightforward:

  1. Login as root (since /root is not under /home)
  2. `umount /home
  3. cp /etc/skel/.xinitrc-cryptsetup-gui /home//.xinitrc
  4. Repeat above step for every user with a home directory in /home
  5. mount /home
  6. Reboot and enjoy!

Shortcomings

Final remarks

So, that is my little contribution to the world. Hopefully someone will find it useful!

Again, the code is on GitHub. If you find any bugs or potential improvements, or if you just have comments on the design, please feel free to contact me either there using the “issues” tab, via email, or via comments to this post.