unixabg / cryptmypi

Project to assist users in building an encrypted raspberry pi
GNU General Public License v3.0
63 stars 20 forks source link

/etc/unlock.sh missing after rebuilding initramfs on RaspberryPi #64

Open ph1387 opened 8 months ago

ph1387 commented 8 months ago

As promised, here is a list of all steps including the configuration for how I managed to get an updated Debian instance running on the RaspberryPi.

Setup:

  1. Proxmox VM Debian 12 Bookworm as host for executing the scripts
  2. RaspberryPi 3B+ (named "ares")
  3. next-4.x branch of the repository

Configuration

Steps to Reproduce

Initial setup

  1. Use Proxmox VM host
  2. Delete existing "build" directory in "./cryptmypi.sh examples/debian-encrypted-basic-dropbear"
  3. Switch to next-4.x branch
  4. Apply configuration mentioned above
  5. Switch to root via su -
  6. Run ./cryptmypi.sh examples/debian-encrypted-basic-dropbear stage 1 and stage 2
  7. Since I am not sure which initramfs is being used (/boot or /boot/firmware) check all generated ones. They should all display the same result:
    1. lsinitramfs examples/debian-encrypted-basic-dropbear/build/root/boot/initramfs.gz | grep -P "(crypttab|fstab|unlock.sh)" -> reference initramfs image
      1. cryptroot/crypttab
      2. cryptroot/fstab
      3. etc/crypttab
      4. etc/fstab
      5. etc/unlock.sh
    2. lsinitramfs examples/debian-encrypted-basic-dropbear/build/root/boot/initrd.img-6.1.0-13-arm64 | grep -P "(crypttab|fstab|unlock.sh)"
    3. lsinitramfs examples/debian-encrypted-basic-dropbear/build/root/boot/firmware/initrd.img-6.1.0-13-arm64 | grep -P "(crypttab|fstab|unlock.sh)"
  8. Put the sd card into the RaspberryPi
  9. Start the RaspberryPi
  10. Verify dropbear configuration by logging in from another system via ssh: ssh root@192.168.188.247 -p 2222 -i ares_luks
  11. Debian starts up and root can log in with the _ROOTPASSWD on the RaspberryPi itself
  12. Enable ssh for root user since it makes the next steps easier:
    1. nano /etc/ssh/sshd_config -> PermitRootLogin yes
    2. systemctl restart ssh.service

Updating (fails by default)

  1. Connect to the RaspberryPi as root via ssh: ssh root@192.168.188.247 -i ares_luks
  2. Make a copy/note down content of "/boot/firmware/cmdline.txt", as it can get replaced during the update process
  3. Update the RaspberryPi via apt update && apt upgrade -y -> keep the local ssh configuration if asked
  4. Check for new version with ls /lib/modules -> In my case this returns 6.1.0-13-arm64 6.1.0-18-arm64
  5. Create a new initramfs mkinitramfs -o /boot/initramfs.gz 6.1.0-18-arm64
  6. Check the created initramfs via lsinitramfs /boot/initramfs.gz | grep -P "(crypttab|fstab|unlock.sh)" -> this will only include the following:
    1. cryptroot/crypttab
    2. etc/fstab
  7. Notice the missing "etc/unlock.sh" script but continue regardless
  8. Do the same as the scripts by moving the created initramfs around to make it load on boot:
    1. mv /boot/firmware/initrd.img-6.1.0-18-arm64 /boot/firmware/initrd.img-6.1.0-18-arm64-oos
    2. mv /boot/initrd.img-6.1.0-18-arm64 /boot/initrd.img-6.1.0-18-arm64-oos
    3. mv /boot/initramfs.gz /boot/firmware/initrd.img-6.1.0-18-arm64
  9. Check "/boot/firmware/config.txt", it should load the created initramfs since it mentiones the "initrd.img-6.1.0-18-arm64" image
  10. Replace the content of "/boot/firmware/cmdline.txt" with the copied content from before
  11. Reboot
  12. Verify dropbear configuration by logging in from another system via ssh: ssh root@192.168.188.247 -p 2222 -i ares_luks
  13. Fail the unlock since "/etc/unlock.sh" can not be found:

$ ssh root@192.168.188.247 -p 2222 -i ares_luks The authenticity of host '[192.168.188.247]:2222 ([192.168.188.247]:2222)' can't be established. ED25519 key fingerprint is SHA256:lLYugILqU7OqgXlQ9JX3B2woKFNEay71SZ27KjP7+v0. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[192.168.188.247]:2222' (ED25519) to the list of known hosts. Enter passphrase for key 'ares_luks': sh: /etc/unlock.sh: not found Connection to 192.168.188.247 closed.

Fix

  1. Manually decrypt the filesystem in the initramfs by pressing "Enter" once and providing the correct decryption password
  2. Connect to the RaspberryPi as root via ssh: ssh root@192.168.188.247 -i ares_luks
  3. Make a copy/note down content of "/boot/firmware/cmdline.txt", as it can get replaced during the update process
  4. Create an initramfs hook for copying the missing file:
    1. nano /etc/initramfs-tools/hooks/luks_unlock
#!/bin/sh -e
PREREQS=""
case $1 in
        prereqs) echo "${PREREQS}"; exit 0;;
esac

. /usr/share/initramfs-tools/hook-functions
copy_file config /etc/initramfs-tools/unlock.sh /etc/unlock.sh
  1. Make it executable chmod 755 /etc/initramfs-tools/hooks/luks_unlock
  2. Create a new initramfs mkinitramfs -o /boot/initramfs.gz 6.1.0-18-arm64
  3. Check the created initramfs via lsinitramfs /boot/initramfs.gz | grep -P "(crypttab|fstab|unlock.sh)"-> this will include the previously missing unlock.sh:
    1. cryptroot/crypttab
    2. etc/fstab
    3. etc/unlock.sh
  4. Do the same as the scripts by moving the created initramfs around to make it load on boot:
    1. mv /boot/firmware/initrd.img-6.1.0-18-arm64 /boot/firmware/initrd.img-6.1.0-18-arm64-oos
    2. mv /boot/initramfs.gz /boot/firmware/initrd.img-6.1.0-18-arm64
  5. Replace the content of "/boot/firmware/cmdline.txt" with the copied content from before
  6. Reboot
  7. Verify dropbear configuration by logging in from another system via ssh: ssh root@192.168.188.247 -p 2222 -i ares_luks
  8. Unlocking the device with dropbear works as expected

Test whether keeping hook in script fixes problem

A possible solution for this problem would be the removal of the previously mentioned https://github.com/unixabg/cryptmypi/blob/52227dfaf905ace65fa8555fb3999e9a75b299f5/hooks/7500-stage2-chroot-final.hook#L6

  1. Comment out the mentioned line with nano hooks/7500-stage2-chroot-final.hook
  2. Remove any previous builds
  3. Run ./cryptmypi.sh examples/debian-encrypted-basic-dropbear stage 1 and stage 2
  4. Start RaspberryPi
  5. Login as Root and enable ssh login again
  6. Verify that the initramfs hook is present: ls -l /etc/initramfs-tools/hooks/ -> zz-cryptsetup
  7. Make a copy/note down content of "/boot/firmware/cmdline.txt", as it can get replaced during the update process
  8. Update the RaspberryPi via apt update && apt upgrade -y -> keep the local ssh configuration if asked
  9. Check for new version with ls /lib/modules -> In my case this returns 6.1.0-13-arm64 6.1.0-18-arm64
  10. Create a new initramfs mkinitramfs -o /boot/initramfs.gz 6.1.0-18-arm64
  11. Check the created initramfs via lsinitramfs /boot/initramfs.gz | grep -P "(crypttab|fstab|unlock.sh)" -> "/etc/unlock.sh" should be in the list
  12. Do the same as the scripts by moving the created initramfs around to make it load on boot:
    1. mv /boot/firmware/initrd.img-6.1.0-18-arm64 /boot/firmware/initrd.img-6.1.0-18-arm64-oos
    2. mv /boot/initrd.img-6.1.0-18-arm64 /boot/initrd.img-6.1.0-18-arm64-oos
    3. mv /boot/initramfs.gz /boot/firmware/initrd.img-6.1.0-18-arm64
  13. Check "/boot/firmware/config.txt", it should load the created initramfs since it mentiones the "initrd.img-6.1.0-18-arm64" image
  14. Replace the content of "/boot/firmware/cmdline.txt" with the copied content from before
  15. Reboot
  16. Verify dropbear configuration by logging in from another system via ssh: ssh root@192.168.188.247 -p 2222 -i ares_luks
  17. Dropbear works and the filesystem is decrypted

As far as I can tell removing this single line of code allows for updating the initramfs as long as you also adjust the "/boot/firmware/cmdline.txt" as well. I am not sure if the "{DESTDIR}" parts of the hook interfere with anything though.