Last active
March 21, 2024 22:19
-
-
Save casebeer/b6ef86bd7531995d7f9b69af3749dfef to your computer and use it in GitHub Desktop.
Script to unlock Ubuntu LUKS encrypted volume from initramfs during boot using a keyfile stored on a USB thumb drive with fallback to manual passphrase entry.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# https://tqdev.com/2022-luks-with-usb-unlock | |
# | |
# Script to unlock Ubuntu LUKS encrypted volume from initramfs during boot using | |
# a keyfile stored on a USB thumb drive with fallback to manual passphrase entry. | |
# | |
# Runs in Busybox shell environment in initramfs | |
# After updates to this script or crypttab, update initramfs: | |
# | |
# update-initramfs -u | |
# | |
set -x | |
# see man 5 crypttab | |
crypttabKeyfileArg="${CRYPTTAB_KEY}" | |
usbDiskUuid="$(echo "${crypttabKeyfileArg}" | cut -d ':' -f 1)" | |
keyFile="$(echo "${crypttabKeyfileArg}" | cut -d ':' -f 2 )" | |
mountPoint="/mnt" | |
keyFilePath="${mountPoint}/${keyFile}" | |
# Mount USB by UUID to avoid ambiguity | |
# Alternative considered: Use disk label so we can swap out the USB drive as needed. | |
# use by-uuid device because Busybox mount doesn't support -U {UUID} option | |
mkdir -p "${mountPoint}" | |
mount "/dev/disk/by-uuid/${usbDiskUuid}" "${mountPoint}" | |
# Print debugging variables | |
set +x | |
ls -l "${keyFilePath}" >&2 | |
echo "CRYPTTAB_NAME=${CRYPTTAB_NAME}" >&2 | |
echo "CRYPTTAB_SOURCE=${CRYPTTAB_SOURCE}" >&2 | |
echo "CRYPTTAB_KEY=${CRYPTTAB_KEY}" >&2 | |
echo "CRYPTTAB_TRIED=${CRYPTTAB_TRIED}" >&2 | |
echo "CRYPTTAB_TRIES=${CRYPTTAB_TRIES}" >&2 | |
echo "CRYPTTAB_OPTIONS=${CRYPTTAB_OPTIONS}" >&2 | |
# Pause for a few seconds in case of errors etc. | |
read -p "Press ENTER to continue..." -t 5 discard | |
set -x | |
tryKeyFile() { | |
if [ -z "${keyFile}" -o -z "${usbDiskUuid}" ] ; then | |
echo "ERROR: No keyfile or USB disk configured. Specify in /etc/crypttab as {uuid}:{keyfile}" >&2 | |
#exit 1 | |
return 2 | |
fi | |
if [ -f "${keyFilePath}" ]; then | |
# we've located the keyfile (by name) | |
# dump its contents to stdout | |
# note that if the keyfile is bad, we need to identify that and fail over to passphrase collection | |
if [ "${CRYPTTAB_TRIED}" -gt "0" ] ; then | |
echo "Found keyfile, but previously failed to unlock. Skipping to passphrase collection." >&2 | |
return 3 | |
fi | |
cat "${keyFilePath}" | |
return 0 | |
fi | |
echo "ERROR: Unable to find keyfile." >&2 | |
return 1 | |
} | |
if tryKeyFile ; then | |
echo "Found keyfile." >&2 | |
else | |
# collect passphrase manually since we can't find or can't use the keyfile | |
/lib/cryptsetup/askpass "Enter LUKS passphrase for ${CRYPTTAB_SOURCE}: " | |
fi | |
umount "${mountPoint}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment