Mount a LUKS partition with a password-protected GPG-encrypted key using systemd

I recently took a good resolution for my laptop: increase the security of some sensitive data using LUKS.
Because I'm using a password-protected gpg-encrypted key, I can't use any automatic mount tool like dracut or automount so I use a bunch of systemd service files.

Note: I'm using the user part of systemd, but this article is not about its configuration.

GPG-Agent

The first tool I need is gpg-agent which is not system-wide, so I create an unit file named gpg-agent.service:

If you need the SSH Agent support, append --enable-ssh-support to ExecStart.ExecReload is used to clean the passphrases cache when you want (reload gpg-agent with: systemctl --user reload gpg-agent.service).

Note: Don't forget to append use-agent in ~/.gnupg/gpg.conf and customize the agent configuration with ~/.gnupg/gpg-agent.conf

LUKS

I've found a script for mounting a LUKS partition with automount. I've customized it for my own use:

#!/bin/shkey="{keyname}"# The cryptsetup tool from the package of the same nameCRYPTSETUP=/sbin/cryptsetup
# This is the raw device that we will mountmount_device=/dev/{device}# This is the encryption key file, encrypted using gpgkey_file={keypath}# Mount options for the encrypted fileystemmount_opts="-t ext4 -o defaults,noatime,nodiratime,users,owner,exec"# The mapped block devicecrypt_device=/dev/mapper/$key# Give up if there is no key or setup tool# [ -r $key_file ] || exit 0[ -x $CRYPTSETUP]||exit1# If there is an encrypted device mapped in already, it must be from a# previous mount. It may be out-of-date so remove it now.[ -b $crypt_device]&& sudo $CRYPTSETUP remove $key# Give up if the raw device doesn't have a LUKS header
sudo $CRYPTSETUP isLuks $mount_device||exit2# Open the encrypted block device
gpg --batch --decrypt $key_file2>/dev/null | sudo $CRYPTSETUP -d - luksOpen $mount_device$key >& /dev/null ||exit3# If we ended up with a block device, mount itif[ -b $crypt_device];then
sudo mount $mount_opts /dev/mapper/$key{mountpath}fiexit0

{keyname}: Name of the LUKS device{device}: LUKS disk device{keypath}: absolute path of the gpg-encrypted key to unlock the LUKS device{mountpath}: absolute path of the mount point

Note: I'm using sudo to be able to call cryptsetup and mount with root privileges (without password).

Now with this script, we can make a new unit file for LUKS named luks.service: