Automount LUKS encrypted USB drive on boot

Hi Folks,

I've got a LUKS encrypted HDD that I'd like to mount automatically when my Netgear R6100 boots. I can successfully decrypt & mount the drive manually from the command line, so I've got the necessary packages installed.

On my Linux (Arch) laptop, I simply need to add an entry to /etc/crypttab to have the drive automounted. There is a systemd unit that parses this file, generates a unit for each /etc/crypttab line/entry and those entry-specific units then decrypt the drives.

What is the best way to handle this in Lede/OpenWrt? I suppose I could add the required cryptsetup command to /etc/rc.local and the creation of the decrypted drive in /dev/mapper/* would trigger the corresponding /etc/fstab entry. Is there a better, SysV Init style way to handle this?

Look into /etc/hotplug.d/ folders. There's probably a trigger for disks or at least USB devices.

1 Like

Thanks. It looks like a page was recently added to the documentation for this topic: https://lede-project.org/docs/user-guide/hotplug_lede .

The hotplug scripts below seem to do the trick.

A couple of observations/questions:

  1. It seems as though these scripts are triggered quite early on startup, before network services. On my (admittedly slow) router, the cryptsetup open command takes between 1-2 minutes which delays network availability for this amount of time. Is there a way to have the hotplug scripts run later? As mentioned above one could simply execute these commands in /etc/rc.local which would solve this problem, but would result in the loss of runtime plug-ability.
  2. When the mapped drive is created both add and change events are triggered. I haven't found much info on the change event and the snippets below use add but the events occur in quick succession so I expect either would work.

/etc/hotplug.d/block/80-decrypt-external-drive

#decrypt sda1 partition when detected
RUN="/usr/sbin/cryptsetup open /dev/sda1 external --key-file /etc/router-luks.txt"

if [ "${DEVNAME}" = "sda1" ] && [ "${DEVTYPE}" = "partition" ]; then
	if [ "${ACTION}" = "add" ]; then
		${RUN}
	fi
fi

/etc/hotplug.d/block/90-mount-external-drive

#mount '/dev/mapper/external' when detected
DECRYPTED_DRIVE="/dev/mapper/external"
RUN="/sbin/block mount"

if [ "${DEVNAME}" = "dm-0" ] && [ -b "${DECRYPTED_DRIVE}" ]; then
	if [ "${ACTION}" = "add" ]; then
		${RUN}
	fi
fi

Use ${RUN} & in your decrypt script.

And look at bash/shell job control.

I did try this, but it didn't seem to make a difference. I tried:
${RUN} &
and...
RUN="/usr/sbin/cryptsetup open /dev/sda1 external --key-file /etc/router-luks.txt &"

Searching produced some results (https://askubuntu.com/questions/667922/udev-script-doesnt-run-in-the-background) describing the inability to run a udev script in the background so perhaps it is not in fact possible to run a hotplug script as a background task?

I think he meant $( RUN ) & <-- this won't block your process

Maybe it shouldn't be done this way for some reason however, it works for auto-opening & auto-mounting on boot for a SATA attached HDD, and vice-versa on shutdown/reboot.

/etc/init.d/fstab

boot() {
    /usr/sbin/cryptsetup open /dev/sdX <map-name> --key-file <path-to-keyfile>
    sleep 3; /sbin/block mount
}

+Add this to the end of the init fstab file

shutdown() {
    /bin/umount <mount-point>; sleep 3; /usr/sbin/cryptsetup close /dev/mapper/<map-name>
}

/etc/config/fstab

config mount
    option target '<mount-point>'
    option uuid '<UUID>'
    option enabled '1'