Contents

udev auto mount LUKS encrypted partition by UUID

Sunday, July 1st, 2012

Here is the overview

  • When a device is detected, check to see if it is a hard drive
    (eg: sda, sdb, sdc, and so on).

  • If it is not, we are done, and go to the end of this rule file.

  • If it is a hard drive, check it using the blkid program to see if there is a partition type of “crypto_LUKS” present.

  • If it is a “crypto_LUKS” container, unlock the encrypted container using the key file you created earlier.

The cryptsetup command is passed to the temporary device node %N (a temporary node which udev creates to reference the device before the device’s final device node is created) and the kernel’s device node %k (eg: sde).

This command is responsible for unlocking the encrypted container and creating the block device node in /dev/mapper as seen previously.

  • Now that the LUKS container has unlocked the real partition, perform a mount based on it’s known UUID.

  • Next, if the udev rule was called because the device has been removed, unmount the real partition using the umount command.

  • Additionally, if the udev rule was called because the device has been removed, then a command is run to close the encrypted container and remove the device-mapper block node in /dev/mapper so we are ready the next time a disk is plugged in!

cat /etc/udev/rules.d/45-offsite-LUKS.rules

######## LUKS ENCRYPTED DISK OPEN/CLOSE – MOUNT/UMOUNT LINUX UDEV RULE ########
### ASSUMES THAT YOUR DISK IS EXTERNAL, TRANSIENT OR BOTH ###
# created 07-01-2012 by RTWM
# based on concepts found at: http://www.revpol.com/node/140

#SECTION 1
#Assume that the offsite backup disk will be /dev/sdb or higher. Change as needed if your system already has several internal disks that are always present.
KERNEL!="sd[b-z]*", GOTO="end"
ACTION=="add", PROGRAM!="/sbin/blkid -p %N", GOTO="end"
#
#Check to see if the newly connected disk has a LUKS partition. That’s all we’re interested in.
PROGRAM=="/sbin/blkid -o value -p -s TYPE %N", RESULT=="crypto_LUKS", ENV{crypto}="mapper/", ENV{device}="/dev/mapper/%k"
ENV{crypto}!="?*", ENV{device}="%N"
#if there is a LUKS partiton on the disk, try to unlock it using our private key.
ACTION=="add", ENV{crypto}=="?*", RUN+="/sbin/cryptsetup luksOpen –key-file=/etc/offsite/test.key %N %k"
#test to see if our private key unlocked the LUKS partiton by seeing if there is a new device in /dev/mapper
ACTION=="add", ENV{crypto}=="?*", TEST!="/dev/mapper/%k"

#SECTION 2
#the next section gives you several options depending on your preferences.
#assuming your private has unlocked the LUKS partiton, because you know the disk,
#if you only want to mount partitons that you already know the UUID of
#add a mount statment below with a real uuid for each partition that should be mounted.
#this method could be considered the most secure or restrictive, because two factors have to both be true:
# 1.your private key has to be able to unlock the LUKS partition on th disk.
# 2 you have to know in advance what the real uuid’s are for each (encrypted) partition that you intend to mount automatically.
# The downside with this method is that there is labor involved to update this udev rule, anytime a new disk is added to the backup system.

#the following assumes that your private key has unlocked the LUKS partiton, and there is a now a new uuid in /dev/disk/by-uuid which is your backup destination.
#this is the method I have chosen to use.
#add a mount statement for each real uuid that you intend to mount at any point in time. uuid’s not currently present will just be ignored.
ACTION=="add", ENV{crypto}=="?*", RUN+="/bin/mount -o noatime,nodiratime /dev/disk/by-uuid/eda68ee0-9e43-4e05-b82b-797fae464ab4 /offsite-backup/", GOTO="end"
ACTION=="add", ENV{crypto}=="?*", RUN+="/bin/mount -o noatime,nodiratime /dev/disk/by-uuid/edb69ee0-9e43-4e05-b82b-797fae464ab5 /offsite-backup/", GOTO="end"
ACTION=="add", ENV{crypto}=="?*", RUN+="/bin/mount -o noatime,nodiratime /dev/disk/by-uuid/edc60ee0-9e43-4e05-b82b-797fae464ab6 /offsite-backup/", GOTO="end"

#if you want a less restrictive method of mounting each real partiton, you can simply mount any real partiton that your private key will unlock.
#the following assumes that your private key has unlocked the LUKS partiton, and just mounts your real partiton by the block node id. i.e. sdb
#ACTION=="add", ENV{crypto}=="?*", RUN+="/bin/mount -o noatime,nodiratime /dev/mapper/%k /offsite-backup/", GOTO="end"

#SECTION 3
#auto unmounting and closing
#The following steps have to occur in the correct order. First, umount the real partiton, second, close the LUKS partiton.
#automatically unmount the real partiton when the disk is unplugged
ACTION=="remove", ENV{crypto}=="?*", RUN+="/bin/umount /offsite-backup/"

#automatically close the LUKS partiton when the disk is unplugged so the system is ready as soon as another LUKS disk is plugged in.
ACTION=="remove", ENV{crypto}=="?*", RUN+="/sbin/cryptsetup luksClose %k"
LABEL="end"