Hi folks,

I have Alpine Linux installed in an encrypted LUKS partition. I came across this tutorial which shows how to setup a key in a USB drive and when the drive is inserted and the computer booted, the LUKS partition auto-unlocks with the key on the USB drive.

https://askubuntu.com/questions/1414617/configure-ubuntu-22-04-zfs-for-automatic-luks-unlock-on-boot-via-usb-drive

I would like to setup the same thing but I do not have Alpine linux installed on ZFS, so I’m looking for ways to adapt the instructions.

So far, what I’ve done is:

  1. I’ve setup the key on the usb stick and I can unlock the LUKS partition with that key.
  2. create a /etc/mkinitfs/features.d/usb-unlock.sh script with the following content:

(the echo to /dev/kmesg was to check whether the script did indeed run at boot by trying to print to the kernel messages but I can’t find anything in the kernel messages).

#!/bin/sh

echo "usb-unlock script starting..." > /dev/kmsg

USB_MOUNT="/mnt/my-usb-key" # The USB stick mounting point
LUKS_KEY_FILE="awesome.key"  # The name of your keyfile on the USB stick

# Search for the USB stick with the key
for device in $(ls /dev/disk/by-uuid/*); do
    mount $device $USB_MOUNT 2>/dev/null
    if [ -f "$USB_MOUNT/$LUKS_KEY_FILE" ]; then
        # Unlock the LUKS partition
        cryptsetup luksOpen /dev/sda3 cryptroot \
            --key-file "$USB_MOUNT/$LUKS_KEY_FILE" && exit 0
    fi
    umount $USB_MOUNT
done
echo "No USB key found, falling back to password prompt." # this message never appears, despite not having found the key on the usb stick

echo "usb-unlock script ending." > /dev/kmsg
  1. I added usb-unlock to the features in mkinitfs.conf:
mytestalpine:~# cat /etc/mkinitfs/mkinitfs.conf 
features="ata base ide scsi usb virtio ext4 cryptsetup keymap usb-unlock"
  1. run mkinitfs to rebuild the initramfs. Then reboot to test the implementation, which was unsuccessful.

What am I missing / doing wrong? Thank you for your help!

Edit: forgot to add step 4

  • The HobbyistOP
    link
    fedilink
    arrow-up
    1
    ·
    3 days ago

    Thank you for your help. I spent time digging into this rabbit hole, and while I’ve learned a lot, I am struggling to get the basics to work. Right now, I’m focusing on being able to just boot an image I created using dracut, excluding all the initial stuff I wanted, just be able to reproduce the original functionality of being able to unlock my luks partition using my keyboard.

    Where I’m at: I am building my initramfs using the following command: dracut -f -v --add crypt --add lvm --add dm. I get the following output log:

    Output log

    mytestalpine:~# dracut -f -v --add crypt --add lvm --add dm dracut[I]: Executing: /usr/bin/dracut -f -v --add crypt --add lvm --add dm dracut[I]: Module ‘dash’ will not be installed, because command ‘dash’ could not be found! dracut[I]: Module ‘mksh’ will not be installed, because command ‘mksh’ could not be found! dracut[I]: Module ‘caps’ will not be installed, because command ‘capsh’ could not be found! dracut[I]: Module ‘modsign’ will not be installed, because command ‘keyctl’ could not be found! dracut[I]: Module ‘i18n’ will not be installed, because command ‘loadkeys’ could not be found! dracut[I]: Module ‘url-lib’ will not be installed, because command ‘curl’ could not be found! dracut[I]: Module ‘btrfs’ will not be installed, because command ‘btrfs’ could not be found! dracut[I]: Module ‘dmraid’ will not be installed, because command ‘dmraid’ could not be found! dracut[I]: Module ‘dmsquash-live-ntfs’ will not be installed, because command ‘ntfs-3g’ could not be found! dracut[I]: Module ‘mdraid’ will not be installed, because command ‘mdadm’ could not be found! dracut[I]: Module ‘crypt-gpg’ will not be installed, because command ‘gpg’ could not be found! dracut[I]: Module ‘cifs’ will not be installed, because command ‘mount.cifs’ could not be found! dracut[I]: Module ‘iscsi’ will not be installed, because command ‘iscsi-iname’ could not be found! dracut[I]: Module ‘iscsi’ will not be installed, because command ‘iscsiadm’ could not be found! dracut[I]: Module ‘iscsi’ will not be installed, because command ‘iscsid’ could not be found! dracut[I]: 95nfs: Could not find any command of ‘rpcbind portmap’! dracut[I]: Module ‘nvmf’ will not be installed, because command ‘nvme’ could not be found! dracut[I]: Module ‘nvmf’ will not be installed, because command ‘jq’ could not be found! dracut[I]: Module ‘biosdevname’ will not be installed, because command ‘biosdevname’ could not be found! dracut[I]: Module ‘masterkey’ will not be installed, because command ‘keyctl’ could not be found! dracut[I]: Module ‘dash’ will not be installed, because command ‘dash’ could not be found! dracut[I]: Module ‘mksh’ will not be installed, because command ‘mksh’ could not be found! dracut[I]: Module ‘caps’ will not be installed, because command ‘capsh’ could not be found! dracut[I]: Module ‘modsign’ will not be installed, because command ‘keyctl’ could not be found! dracut[I]: Module ‘url-lib’ will not be installed, because command ‘curl’ could not be found! dracut[I]: Module ‘btrfs’ will not be installed, because command ‘btrfs’ could not be found! dracut[I]: Module ‘dmraid’ will not be installed, because command ‘dmraid’ could not be found! dracut[I]: Module ‘dmsquash-live-ntfs’ will not be installed, because command ‘ntfs-3g’ could not be found! dracut[I]: Module ‘mdraid’ will not be installed, because command ‘mdadm’ could not be found! dracut[I]: Module ‘crypt-gpg’ will not be installed, because command ‘gpg’ could not be found! dracut[I]: Module ‘cifs’ will not be installed, because command ‘mount.cifs’ could not be found! dracut[I]: Module ‘iscsi’ will not be installed, because command ‘iscsi-iname’ could not be found! dracut[I]: Module ‘iscsi’ will not be installed, because command ‘iscsiadm’ could not be found! dracut[I]: Module ‘iscsi’ will not be installed, because command ‘iscsid’ could not be found! dracut[I]: 95nfs: Could not find any command of ‘rpcbind portmap’! dracut[I]: Module ‘nvmf’ will not be installed, because command ‘nvme’ could not be found! dracut[I]: Module ‘nvmf’ will not be installed, because command ‘jq’ could not be found! dracut[I]: Module ‘masterkey’ will not be installed, because command ‘keyctl’ could not be found! dracut[I]: *** Including module: sh *** dracut[I]: *** Including module: busybox *** dracut[I]: *** Including module: crypt *** dracut[I]: *** Including module: dm *** dracut[D]: Skipping udev rule: 10-dm.rules dracut[D]: Skipping udev rule: 13-dm-disk.rules dracut[D]: Skipping udev rule: 95-dm-notify.rules dracut[D]: Skipping udev rule: 64-device-mapper.rules dracut[D]: Skipping udev rule: 60-persistent-storage-dm.rules dracut[D]: Skipping udev rule: 55-dm.rules dracut[I]: *** Including module: kernel-modules *** dracut[I]: *** Including module: kernel-modules-extra *** dracut[D]: kernel-modules-extra: configuration source “/run/depmod.d” does not exist dracut[D]: kernel-modules-extra: configuration source “/etc/depmod.d” does not exist dracut[D]: kernel-modules-extra: configuration source “/lib/depmod.d” does not exist dracut[I]: *** Including module: lvm *** dracut[D]: Skipping udev rule: 11-dm-lvm.rules dracut[D]: Skipping udev rule: 64-device-mapper.rules dracut[D]: Skipping udev rule: 56-lvm.rules dracut[D]: Skipping udev rule: 60-persistent-storage-lvm.rules dracut[I]: *** Including module: rootfs-block *** dracut[I]: *** Including module: terminfo *** dracut[I]: *** Including module: udev-rules *** dracut[D]: Skipping udev rule: 70-persistent-net.rules dracut[I]: *** Including module: usrmount *** dracut[I]: *** Including module: base *** dracut[I]: *** Including module: fs-lib *** dracut[I]: *** Including module: shutdown *** dracut[I]: *** Including modules done *** dracut[I]: *** Installing kernel module dependencies *** dracut[I]: *** Installing kernel module dependencies done *** dracut[I]: *** Resolving executable dependencies *** dracut[I]: *** Resolving executable dependencies done *** dracut[I]: *** Hardlinking files *** dracut[D]: Mode: real dracut[D]: Method: sha256 dracut[D]: Files: 457 dracut[D]: Linked: 0 files dracut[D]: Compared: 0 xattrs dracut[D]: Compared: 6 files dracut[D]: Saved: 0 B dracut[D]: Duration: 0.015759 seconds dracut[I]: *** Hardlinking files done *** dracut[I]: Could not find ‘strip’. Not stripping the initramfs. dracut[I]: *** Generating early-microcode cpio image *** dracut[I]: *** Store current command line parameters *** dracut[I]: Stored kernel commandline: dracut[I]: rootfstype=ext4 rootflags=rw,relatime dracut[E]: ldconfig exited ungracefully dracut[I]: *** Creating image file ‘/boot/initramfs-6.6.56-0-lts.img’ *** dracut[I]: Using auto-determined compression method ‘gzip’ dracut[D]: Image: /var/tmp/dracut.Ds3W3x/initramfs.img: 12M dracut[D]: ======================================================================== dracut[D]: Version: dracut-060 dracut[D]: lib/dracut/dracut-060 dracut[D]: dracut[D]: Arguments: -f -v --add ‘crypt’ --add ‘lvm’ --add ‘dm’ dracut[D]: lib/dracut/build-parameter.txt dracut[D]: dracut[D]: dracut modules: dracut[D]: sh dracut[D]: busybox dracut[D]: crypt dracut[D]: dm dracut[D]: kernel-modules dracut[D]: kernel-modules-extra dracut[D]: lvm dracut[D]: rootfs-block dracut[D]: terminfo dracut[D]: udev-rules dracut[D]: usrmount dracut[D]: base dracut[D]: fs-lib dracut[D]: shutdown dracut[D]: lib/dracut/modules.txt dracut[D]: ========================================================================

    <Truncanted due to char limit>

    Then I updated the /boot/extlinux.conf file, adding the following second entry (displaying the first one just for comparison):

    LABEL lts
      MENU DEFAULT
      MENU LABEL Linux lts
      LINUX vmlinuz-lts
      INITRD initramfs-lts
      APPEND root=/dev/mapper/root modules=sd-mod,usb-storage,ext4 cryptroot=<my-uuid> cryptdm=root quiet rootfstype=ext4
    
    LABEL lts
      MENU LABEL dracut-img
      LINUX vmlinuz-lts
      INITRD /boot/initramfs-6.6.56-0-lts.img
      APPEND root=/dev/mapper/root modules=sd-mod,usb-storage,ext4 cryptroot=UUID=<my-uuid> cryptdm=root quiet rootfstype=ext4 rootflags=rw,relatime
    

    I added the rootflags=rw,relatime because this was shown in the dracut log, so I thought perhaps that mattered. But for the most part I left it the same as the previous entry, because I’m trying to do the same thing I suppose. Perhaps I’m mistaken?

    The current result of booting that image leads to a long loading (not asking for the passphrase to unlock the partition) then displaying the following error:

    dracut Warning: Could not boot.
    
    dracut Warning: "/dev/mapper/root" does not exist
    
    Generating "/run/initramfs/rdsosreport.txt"
    You might want to save "/run/initramfs/rdsosreport.txt" to a USB stick or /boot after mounting them and attach it to a bug report.
    
    To get more debug information in the report, reboot with "rd.debug" added to the kernel command line.
    
    Dropping to debug shell.
    

    Before dropping me in a shell, in which I have not found anything useful to do. I am surely missing something basic as my understanding of what’s happening is pretty superfluous.

    What I’m noticing which may be of importance:

    • dracut[E]: ldconfig exited ungracefully, in the dracut output log. Perhaps this matters and should be fixed? An image is nonetheless generated.
    • there are many missing modules when creating an image, but I don’t know if any of them matter, at least for my purpose.
    • One thing I can’t wrap my head around is, how come the original kernal image work, when I had packages such as device-mapper and lvm missing, why did dracut complain about them missing for me to compile my own image? and would I need to add options in the /boot/extlinux.conf file, when they are not required for the original boot entry, when all I’m trying to do (as a start) is just make sure I can reproduce a bootable kernel image?
    • chameleon@fedia.io
      link
      fedilink
      arrow-up
      2
      ·
      2 days ago

      I think you should check your root= line and add a rd.luks.uuid= to make it open it. Dracut will by default open the root FS as /dev/mapper/luks-abcdef... based on the LUKS container UUID. You can get that with cryptsetup luksUUID. /dev/mapper/root is just never going to show up unless you’ve assigned a custom name to that with the barely documented rd.luks.name, and I don’t see that in your setup. The cryptroot and cryptdm parameters aren’t used by Dracut either.

      With all of that missing it’s just gonna wait for that /dev/mapper/root to magically show up out of nowhere, without ever trying to open it.

      A correct cmdline will probably look something along the lines of root=/dev/mapper/luks-<uuid> modules=sd-mod,usb-storage,ext4 rootfstype=ext4 rootflags=rw,relatime rd.luks.uuid=<uuid> and once opening with passphrase works, you can start to mess with rd.luks.key=/awesome.key (and readd quiet when done debugging, if you want it that way).

      ldconfig errors and the missing modules should be fine. musl’s ldconfig is just a bit different but also isn’t required in quite the same way. I don’t think you should need to mess with modules manually. I don’t think you’re using LVM’s userland for your setup, just all the device-mapper kernel modules. Dracut will pull all the necessary bits in for you if you’re setting it up for LUKS.

    • The HobbyistOP
      link
      fedilink
      arrow-up
      1
      ·
      3 days ago

      Darn I’ve run out of chars again, but it seems the formatting is lost for the dracut output log… if it matters, I’ll find another way or somewhere else to paste it (in its entirety).