Automatic LUKS USB Decryption and Mounting
A Gentoo/OpenRC init.d script for unlocking a LUKS-encrypted external disk at boot and mounting it reliably using cryptsetup in non-interactive mode

Create /etc/conf.d/usbcrypt (set correct <password>)
# /etc/conf.d/usbcrypt
# LUKS container UUID (TYPE="crypto_LUKS")
USBCRYPT_DEV="/dev/disk/by-uuid/<uuid_to_luks_drive>"
# Mapping name: creates /dev/mapper/<name>
USBCRYPT_NAME="usb"
# Mountpoint after unlocking
USBCRYPT_MOUNTPOINT="/mnt/usb"
# FS type of the decrypted filesystem (optional but recommended)
USBCRYPT_FSTYPE="ext4"
# Mount options
USBCRYPT_MOUNTOPTS="defaults,noatime"
# Plaintext passphrase (chmod 600 this file)
USBCRYPT_PASSPHRASE="<password>"
EOF
Lock above down
chown root:root /etc/conf.d/usbcrypt
chmod 600 /etc/conf.d/usbcrypt
Configure /etc/init.d/autocrypt
cat << "EOF" > /etc/init.d/usbcrypt
#!/sbin/openrc-run
# /etc/init.d/usbcrypt
description="Unlock and mount a LUKS-encrypted external drive at boot"
depend() {
need udev
after modules
}
start() {
local dev="${USBCRYPT_DEV}"
local name="${USBCRYPT_NAME}"
local mp="${USBCRYPT_MOUNTPOINT}"
local mapper="/dev/mapper/${name}"
# Ensure mountpoint exists
checkpath -d -m 0755 "${mp}" || return 1
# Wait up to ~30 seconds for the device to appear; resolve symlink robustly
local i=0
while :; do
local realdev
realdev="$(readlink -f "${dev}" 2>/dev/null)"
if [ -n "${realdev}" ] && [ -b "${realdev}" ]; then
dev="${realdev}"
break
fi
if [ ${i} -ge 30 ]; then
ewarn "Device ${USBCRYPT_DEV} not found; skipping."
return 0
fi
sleep 1
i=$((i+1))
done
# If already opened, skip opening (more reliable than checking -e /dev/mapper/*)
if /sbin/cryptsetup status "${name}" >/dev/null 2>&1; then
einfo "${mapper} already active; skipping luksOpen."
else
local pwlen="${#USBCRYPT_PASSPHRASE}"
if [ "${pwlen}" -le 0 ]; then
eerror "USBCRYPT_PASSPHRASE is empty."
return 1
fi
ebegin "Decrypting ${USBCRYPT_DEV} (LUKS open as '${name}')"
printf '%s' "${USBCRYPT_PASSPHRASE}" | \
/sbin/cryptsetup --batch-mode --key-file=- --keyfile-size="${pwlen}" \
luksOpen "${dev}" "${name}"
rc=$?
eend $rc || return 1
fi
# Mount if not mounted
if mountpoint -q "${mp}"; then
einfo "${mp} already mounted; nothing to do."
return 0
fi
ebegin "Mounting decrypted drive into ${mp}"
if [ -n "${USBCRYPT_FSTYPE}" ]; then
mount -t "${USBCRYPT_FSTYPE}" -o "${USBCRYPT_MOUNTOPTS}" "${mapper}" "${mp}"
else
mount -o "${USBCRYPT_MOUNTOPTS}" "${mapper}" "${mp}"
fi
rc=$?
eend $rc || return 1
}
stop() {
local name="${USBCRYPT_NAME}"
local mp="${USBCRYPT_MOUNTPOINT}"
local mapper="/dev/mapper/${name}"
if mountpoint -q "${mp}"; then
ebegin "Unmounting ${mp}"
umount "${mp}"
rc=$?
eend $rc || return 1
else
einfo "${mp} is not mounted."
fi
if /sbin/cryptsetup status "${name}" >/dev/null 2>&1; then
ebegin "Closing LUKS mapping ${mapper}"
/sbin/cryptsetup luksClose "${name}"
rc=$?
eend $rc || return 1
else
einfo "${mapper} is not active; nothing to close."
fi
}
EOF
Make it executable:
chmod +x /etc/init.d/usbcrypt
Enable on boot
rc-update add usbcrypt default
Start it now to test
rc-service usbcrypt start
Stop it now to test
rc-service usbcrypt stop