add CRYPTROOT_AUTOUNLOCK option and fix CRYPTROOT for uefi builds

fixes #6280
This commit is contained in:
Alex Simkin 2025-10-22 22:16:55 +03:00 committed by Igor
parent 3fcb8ef7b2
commit b47445c990
6 changed files with 44 additions and 9 deletions

View File

@ -24,9 +24,18 @@ function extension_prepare_config__prepare_cryptroot() {
function prepare_root_device__250_encrypt_root_device() {
# We encrypt the rootdevice (currently a loop device) and return the new mapped rootdevice
check_loop_device "$rootdevice"
display_alert "Extension: ${EXTENSION}: Encrypting root partition with LUKS..." "cryptsetup luksFormat $rootdevice" ""
echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksFormat $CRYPTROOT_PARAMETERS $rootdevice -
echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksOpen $rootdevice $CRYPTROOT_MAPPER -
display_alert "Extension: ${EXTENSION}: Encrypting root partition with LUKS..." "cryptsetup luksFormat $CRYPTROOT_PARAMETERS $rootdevice" ""
if [[ $CRYPTROOT_AUTOUNLOCK == "yes" ]]; then
display_alert "Extension: ${EXTENSION}: configuring LUKS autounlock" ""
declare -g cryptroot_autounlock_key_file=$(mktemp)
openssl rand -base64 32 > "$cryptroot_autounlock_key_file"
cryptsetup luksFormat $CRYPTROOT_PARAMETERS "$rootdevice" "$cryptroot_autounlock_key_file"
cryptsetup luksOpen --key-file "$cryptroot_autounlock_key_file" "$rootdevice" $CRYPTROOT_MAPPER
else # CRYPTROOT_PASSPHRASE case
display_alert "Extension: ${EXTENSION}: configuring LUKS password" ""
echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksFormat $CRYPTROOT_PARAMETERS $rootdevice -
echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksOpen $rootdevice $CRYPTROOT_MAPPER -
fi
add_cleanup_handler cleanup_cryptroot
display_alert "Extension: ${EXTENSION}: Root partition encryption complete." "" "ext"
# TODO: pass /dev/mapper to Docker
@ -90,4 +99,4 @@ function post_umount_final_image__750_cryptroot_cleanup(){
function cleanup_cryptroot(){
cryptsetup luksClose "${CRYPTROOT_MAPPER}" 2>&1
display_alert "Cryptroot closed ${CRYPTROOT_MAPPER}" "${EXTENSION}" "info"
}
}

View File

@ -21,6 +21,9 @@ function extension_prepare_config__prepare_grub_standard() {
declare -g IMAGE_PARTITION_TABLE="gpt" # GPT partition table is essential for many UEFI-like implementations, eg Apple+Intel stuff.
declare -g UEFISIZE=260 # in MiB - grub EFI is tiny - but some EFI BIOSes ignore small too small EFI partitions
declare -g BOOTSIZE=0 # No separate /boot when using UEFI.
if [[ $BOOTPART_REQUIRED == "yes" ]]; then # It is important to place this into /boot to have unified boot partition, especially when CRYPTROOT is used
declare -g UEFI_MOUNT_POINT=/boot
fi
declare -g EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-grub" # Unique bsp name.
declare -g UEFI_GRUB_TARGET_BIOS="" # Target for BIOS GRUB install, set to i386-pc when UEFI_ENABLE_BIOS_AMD64=yes and target is amd64
@ -162,7 +165,7 @@ pre_umount_final_image__install_grub() {
}
fi
local install_grub_cmdline="grub-install --target=${UEFI_GRUB_TARGET} --no-nvram --removable" # nvram is global to the host, even across chroot. take care.
local install_grub_cmdline="grub-install --target=${UEFI_GRUB_TARGET} --efi-directory=${UEFI_MOUNT_POINT} --no-nvram --removable" # nvram is global to the host, even across chroot. take care.
display_alert "Extension: ${EXTENSION}: Installing GRUB EFI..." "${UEFI_GRUB_TARGET}" ""
chroot_custom "$chroot_target" "$install_grub_cmdline" || {
exit_with_error "${install_grub_cmdline} failed!"
@ -174,7 +177,12 @@ pre_umount_final_image__install_grub() {
# Irony: let's use grub-probe to find out the UUID of the root partition, and then create a symlink to it.
# Another: on some systems (eg, not Docker) the thing might already exist due to udev actually working.
# shellcheck disable=SC2016 # some wierd escaping going on there.
# Root is needed so that UUID of the unlocked /dev/mapper/armbian-root is discovered by grub-update,
# UUID is then put into grub.cfg instead of raw /dev/mapper/armbian-root which will fail further sanity check
chroot_custom "$chroot_target" mkdir -pv '/dev/disk/by-uuid/"$(grub-probe --target=fs_uuid /)"' "||" true
# Include /boot that might point to a separate boot partition in case one exists (lvm, cryptroot)
# Even if boot partition doesn't exist - the command will be the same as mkdir for / above
chroot_custom "$chroot_target" mkdir -pv '/dev/disk/by-uuid/"$(grub-probe --target=fs_uuid /boot)"' "||" true
display_alert "Extension: ${EXTENSION}: Creating GRUB config..." "grub-mkconfig" ""
chroot_custom "$chroot_target" update-grub || {
@ -285,6 +293,8 @@ configure_grub() {
GRUB_DISABLE_OS_PROBER=false # Have to be explicit about enabling os-prober
GRUB_FONT="/usr/share/grub/unicode.pf2" # Be explicit about the font to use so Ubuntu does not freak out and mess gfxterm
GRUB_GFXPAYLOAD=keep
GRUB_DISABLE_UUID=false # Be explicit about wanting UUID
GRUB_DISABLE_LINUX_UUID=false # Be explicit about wanting UUID
grubCfgFrag
if [[ "a${UEFI_GRUB_DISABLE_OS_PROBER}" != "a" ]]; then

View File

@ -169,8 +169,8 @@ function do_main_configuration() {
# Support for LUKS / cryptroot
if [[ $CRYPTROOT_ENABLE == yes ]]; then
enable_extension "fs-cryptroot-support" # add the tooling needed, cryptsetup
if [[ -z $CRYPTROOT_PASSPHRASE ]]; then # a passphrase is mandatory if rootfs encryption is enabled
exit_with_error "Root encryption is enabled but CRYPTROOT_PASSPHRASE is not set"
if [[ -z $CRYPTROOT_PASSPHRASE ]] && [[ -z $CRYPTROOT_AUTOUNLOCK ]]; then # a passphrase is mandatory if rootfs encryption is enabled, unless CRYPTROOT_AUTOUNLOCK is wanted
exit_with_error "Root encryption is enabled but CRYPTROOT_PASSPHRASE or CRYPTROOT_AUTOUNLOCK is not set"
fi
[[ -z $CRYPTROOT_MAPPER ]] && CRYPTROOT_MAPPER="armbian-root" # TODO: fixed name can't be used for parallel image building (rpardini: ?)
[[ -z $CRYPTROOT_SSH_UNLOCK ]] && CRYPTROOT_SSH_UNLOCK=yes

View File

@ -62,6 +62,7 @@ update_initramfs() {
[[ -d "${chroot_target}/etc/dropbear-initramfs/" ]] && initrd_files_to_hash+=("${chroot_target}/etc/dropbear-initramfs/")
[[ -d "${chroot_target}/etc/dropbear/initramfs/" ]] && initrd_files_to_hash+=("${chroot_target}/etc/dropbear/initramfs/")
fi
initrd_files_to_hash+=("${chroot_target}/etc/crypttab") # for updates to rootdev UUID
fi
# Find all the affected files; parallel md5sum sum them; invert hash and path, and remove chroot prefix.

View File

@ -324,9 +324,19 @@ function prepare_partitions() {
# create fstab (and crypttab) entry
if [[ $CRYPTROOT_ENABLE == yes ]]; then
luks_key_file="none"
if [[ $CRYPTROOT_AUTOUNLOCK == yes ]]; then
luks_key_file="/etc/rootfs.key"
display_alert "Saving rootfs.key and configuration for autounlock" "(location=${luks_key_file})"
mv ${cryptroot_autounlock_key_file:?} ${SDCARD}${luks_key_file}
mkdir -p $SDCARD/etc/initramfs-tools/conf.d/
echo "UMASK=0077" > $SDCARD/etc/initramfs-tools/conf.d/key-umask.conf
echo "" >> $SDCARD/etc/cryptsetup-initramfs/conf-hook
echo "KEYFILE_PATTERN=${luks_key_file}" >> $SDCARD/etc/cryptsetup-initramfs/conf-hook
fi
# map the LUKS container partition via its UUID to be the 'cryptroot' device
physical_root_part_uuid="$(blkid -s UUID -o value $physical_rootdevice)"
echo "$CRYPTROOT_MAPPER UUID=${physical_root_part_uuid} none luks" >> $SDCARD/etc/crypttab
echo "$CRYPTROOT_MAPPER UUID=${physical_root_part_uuid} ${luks_key_file} luks" >> $SDCARD/etc/crypttab
run_host_command_logged cat $SDCARD/etc/crypttab
fi

View File

@ -189,7 +189,12 @@ do_resize_crypt()
# It's probably no need to run 'cryptsetup resize'.
# After reboot, it will auto resize to adapte the partition
# 'cryptsetup resize' requires passphrase, so it will fail.
cryptsetup resize $name
# if /etc/rootfs.key is present - it can be done unattended
if [ -f /etc/rootfs.key ]; then
cryptsetup resize --key-file /etc/rootfs.key "$name"
else
cryptsetup resize "$name"
fi
local parentsize=$(lsblk -n -b -o SIZE $parentdev | head -1)