Auto mount LUKS without a filesystem
One of my friends recently installed a new storage server in our shared lab environment and graciously gave me some storage space on it via iSCSI. I use Proxmox for my personal lab, and I intended to store some non-critical VM disks on this new storage so I could play around with properly using HA (High Availability) with Proxmox. Additionally, I wanted to gain some experience using iSCSI at the same time. While I trust my friend, the storage itself is outside of my control, so I figured it would be good practice to encrypt my data. The general go-to solution for this would seem to be LUKS.
After setting up iSCSI and multipath, my system can see the storage LUN without any problems.
# multipath -ll san (36589cfc000000c0d01729cc32c52ecc4) dm-9 TrueNAS,iSCSI Disk size=2.0T features='0' hwhandler='0' wp=rw `-+- policy='round-robin 0' prio=15 status=active |- 3:0:0:0 sdb 8:16 active ready running `- 4:0:0:0 sdc 8:32 active ready running
I plan to use LVM on LUKS, which essentially means the LUN in its entirety is encrypted and needs to be correctly decrypted before anything on it can be detected by LVM. I set up
/etc/crypttab with the appropriate key files and proceeded to test if it opens correctly without any prompting. This seemed to work as expected (san_luks is just the name I gave it in
# systemctl status systemd-cryptsetup@san_luks.service ● systemd-cryptsetup@san_luks.service - Cryptography Setup for san_luks Loaded: loaded (/etc/crypttab; generated) Active: active (exited) since Fri 2023-06-23 20:02:33 BST; 18h ago Docs: man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8) Main PID: 1935 (code=exited, status=0/SUCCESS) Tasks: 0 (limit: 48147) Memory: 0B CGroup: /system.slice/system-systemd\x2dcryptsetup.slice/systemd-cryptsetup@san_luks.service Jun 23 20:02:28 pve1 systemd: Starting Cryptography Setup for san_luks... Jun 23 20:02:28 pve1 systemd-cryptsetup: Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/disk/by-uuid/4dfbd655-258b-42f8-b1a7-94155bdf1465. Jun 23 20:02:33 pve1 systemd: Finished Cryptography Setup for san_luks.
I proceeded to reboot, and… it didn’t open the volume. I confirmed that iSCSI and multipath were fine, but the volume just didn’t open on boot.
I tried enabling the cryptsetup service:
# systemctl enable systemd-cryptsetup@san_luks.service Failed to enable unit: Unit /run/systemd/generator/systemd-cryptsetup@san_luks.service is transient or generated.
I tried all sorts of arguments in
/etc/crypttab, but nothing seemed to work.
After a fair amount of digging, it became apparent that the typical use-case for this kind of setup is to open an encrypted volume and then mount a filesystem that resides on it. All the articles I could find were geared towards this and hinted that you need to have crypttab set to automatically open the encrypted volume (which I did), but you also need a corresponding entry in
/etc/fstab that references it. This reference, when systemd tries to mount it, actually triggers cryptsetup, and everything just works nicely.
This is a problem because I am not mounting a filesystem.
Update: See addendum below
Ultimately, I settled on a dirty workaround to ensure my encrypted volume was opened correctly on system boot. I had already confirmed that it works without any prompts from me, so I created a new systemd unit file that should run after multipath is started and set a requirement for my unit to trigger
This should run after multipath is loaded, so I have access to the block device it creates, and then trigger cryptsetup. The unit file runs once at boot and basically does nothing. I’m sure there’s a nicer way to do this, but for me, this worked.
# cat /etc/systemd/system/luks_auto_open.service [Unit] Description=LUKS Auto open After=multipathd.service Requires=systemd-cryptsetup@san_luks.service [Service] Type=oneshot ExecStart=/usr/bin/echo User=root [Install] WantedBy=multi-user.target
I don’t like this workaround at all, but it gets the job done and allows me to continue setting up the new storage for use in Proxmox.
I suspect there’s a more elegant way to do this that doesn’t involve a makeshift unit file, but my Google-fu has failed me.
As it turns out, there is indeed a better way to do this. My friend Dataforce also ran into this problem and refused to accept there wasn’t a better way to do this.
“I’m convinced there must be a better more correct way”. 😄
He was so perturbed at my solution that he actually spent some more time than I did doing research and found the answer:
systemctl enable remote-cryptsetup.target
Initial testing seems to actually do what we want, rather than having to use my artisanal unit file. Check out his page for more details