linuxboot / heads

A minimal Linux that runs as a coreboot or LinuxBoot ROM payload to provide a secure, flexible boot environment for laptops, workstations and servers.
https://osresearch.net/
GNU General Public License v2.0
1.41k stars 185 forks source link

Heads cant boot from USB-drive with Ventoy #1320

Open fhvyhjriur opened 1 year ago

fhvyhjriur commented 1 year ago

I am using Ventoy to be able to have many ISO files on one USB-Drive and boot the ISO file i need at the moment. Latest Heads version from yesterday ( heads-x230-maximized-v0.2.0-1380-gc4b964c.rom ) cant start Ventoy. Ventoy is able to start on any Coreboot payload i tried. It work fine with SeaBIOS and it works fine with TianoCore. Reason for this wide compatibility is, that Ventoy adds a boot menu for BIOS-mode and a boot menu for EFI-Mode. But Heads cant start Ventoy BIOS-mode and also cant start Ventoy EFI-mode. Ventoy is free software and widely used for the use case of many ISO files on one flash drive to be able to choose from. Could someone take a look why it is not starting with Heads? Such basic functionality (booting from Ventoy USB-drive) should work.

https://github.com/ventoy/Ventoy

tlaurion commented 1 year ago

Screenshots welcome or explanation why you think heads should boot ventoy (kexec into another grub.cfg defined boot entries, multiboot compatible Linux OSes only).

tlaurion commented 1 year ago

@fhvyhjriur input needed

natterangell commented 1 year ago

I also use ventoy from time to time. The reason why @fhvyhjriur might be a little confused is because heads by nature is used to kexec into another linux kernel, not chainload into another boot loader.

If you want to reuse your ventoy usb drive to do USB boot on a machine running heads without having to reformat the drive, there is a workaround. It's actually a little more workable now due to exFAT support in heads, which is what I think most ventoy users will have on the partition containing their ISO-files.

  1. Copy the (linux) iso files you want to use to the root of the partition where you have your ISO folder. This is necessary because heads doesn't scan folders when doing usb boot.
  2. boot heads and enter the recovery console
  3. run mount-usb to detect and mount the usb-drive (this happens in read-only mode)
  4. remount the partition containing ISO-files read-write, e.g.: umount /dev/sdb1 && mkdir /iso && mount /dev/sdb1 /iso. Adjust as necessary if you have several disks in your machine.
  5. cd /iso
  6. gpg --output <iso_name>.sig --detach-sig <iso_name>. This will prompt you for your GPG key PIN, so it needs to be attached. Repeat for all the ISO files you want
  7. reboot and choose usb boot from boot menu, you should now be able to boot the ISO-files from your usb-partition.

This only works for linux distributions, heads (obviously) still need to kexec into the grub entries on the ISO.

Works fine for me. You can boot TAILS this way, if you want, or a live distro if you need to mount LUKS partitions and fix something etc.

@tlaurion, I find the wiki good enough to boot installation media, but maybe it could be expanded a little to clarify exactly what's going on when heads boot from USB. Thoughts?

tlaurion commented 12 months ago

Works fine for me. You can boot TAILS this way, if you want, or a live distro if you need to mount LUKS partitions and fix something etc.\n\n@tlaurion, I find the wiki good enough to boot installation media, but maybe it could be expanded a little to clarify exactly what's going on when heads boot from USB. Thoughts?

Yes. The reason it is not more documented is that as usual I have difficulty documenting things that ideally shouldn't.

Some context at https://github.com/osresearch/heads/issues/1438

Ventoy kinda redo what Heads does natively, but better, for what it actually support. Ventoy doesn't do authenticity +integrity validation. Heads only does it for ISOs that are detached signed. And not all ISOs are detached signed.

Most of the ISOs have hashes file + detached signature of the hash file. This is what #1438 considers so advanced users could generate hashes to be verified prior of signing them.

A bit of history can explain why newer hashing+detached signature are not currently supported under Heads, but is now reconsidered. As you know, Heads uses busybox to provide tools needed, including sha256sum. And then gnupg as gpg toolstacks for signature. And sha256sum doesn't support validating directly those additional hash files unless we create a wrapper that would extract the SHA256 and the local path of the ISO once the hash file integrity and authenticity coukd be validated by detached signature today. It's just not implemented under Heads today.

Concretely, if we take Fedora as an example, there was a time where Fedora was providing ISOs and detached signatures, just like arch Linux tails and QubesOS do today. But they stopped before Fedora 30 if my memory is good about it.

But as most of other OSes, they migrated to separate hash file + detached signature. As documented here: https://labs.fedoraproject.org/en/verify

The ideal would be to support that scheme, and #1438 comes with the same conclusion to present a hash to be verified by the user prior of detach signing it. If upstream distributions don't provide a way to verify integrity of the ISO then signing an iso that isn't verified is not really a good idea, waiting for disaster to happen while installing, creating weird errors and causing random issues that are really hard to troubleshoot and blame to a bad thumb drive of memory issues. When implementrd, even #1438 would be questionable, while still desirable to not do it from command line just like currently documented on wiki @natterangell

Tldr: https://labs.fedoraproject.org/en/verify should be enforced under Heads alongside detached signature verification currently supported under Heads by limited number of Linux distributions. It's easier to demand upstream to produce hash files and detach sign them after the fact then ask them to detach sign their ISOs on the ISO builder. The reasoning is simple, producing a detached signature of the hashes doesn't require to expose the private key to the Continuous Integration (CI) or the builder, they can be signed after the fact. The hash file and iso can be downloaded and tested independently, and if they match be detached signed and the detached signature uploaded after validation, not by the CI.

tlaurion commented 12 months ago

Bing generated workaround on busybox limitation:

#!/bin/bash
# split-checksum.sh: Split a CHECKSUM file into separate files for each algorithm

# Check if a CHECKSUM file is provided as an argument
if [ $# -eq 0 ]; then
    echo "Usage: $0 CHECKSUM"
    exit 1
fi

# Loop through each line of the CHECKSUM file
while read line; do
    # Extract the algorithm and the checksum from the line
    algo=$(echo $line | cut -d' ' -f1)
    checksum=$(echo $line | cut -d' ' -f2)

    # Append the line to a file named after the algorithm
    echo $line >> $algo-CHECKSUM
done < $1

# Verify the checksums of each file using sha256sum
for file in *-CHECKSUM; do
    sha256sum -c $file
done

To be adapted to just extract SHA256 and only check SHA256 after having public keys fused in rom and the hash file verified as authentic and then verify integrity of the iso.

tlaurion commented 12 months ago
Linux Distribution Example of iso file Example of checksum file Example of signature file
Fedora Fedora-Workstation-Live-x86_64-34-1.2.iso Fedora-Workstation-34-x86_64-CHECKSUM Fedora-Workstation-34-x86_64-CHECKSUM.asc
CentOS CentOS-Stream-8-x86_64-latest-dvd1.iso CentOS-Stream-8-x86_64-latest-dvd1.iso-CHECKSUM CentOS-Stream-8-x86_64-latest-dvd1.iso-CHECKSUM.asc
openSUSE openSUSE-Leap-15.3-DVD-x86_64.iso openSUSE-Leap-15.3-DVD-x86_64.iso-CHECKSUM openSUSE-Leap-15.3-DVD-x86_64.iso-CHECKSUM.asc
Debian debian-live-10.9.0-amd64-standard.iso debian-live-10.9.0-amd64-standard.iso-SHA256SUM debian-live-10.9.0-amd64-standard.iso-SHA256SUM.sig
Ubuntu ubuntu-20.04.3-desktop-amd64.iso ubuntu-20.04.3-desktop-amd64.iso-CHECKSUM ubuntu-20.04.3-desktop-amd64.iso-CHECKSUM.asc
Arch Linux archlinux-2021.09.01-x86_64.iso archlinux-2021.09.01-x86_64.iso.sha256 archlinux-2021.09.01-x86_64.iso.sig

To be tested

#!/bin/bash
# verify-checksum.sh: Verify the checksum file against its signature and then verify the SHA256 hash from the checksum file

# Check if an iso file is provided as an argument
if [ $# -ne 1 ]; then
    echo "Usage: $0 ISO"
    exit 1
fi

# Extract the name of the distribution from the iso file name using cut
distro=$(echo $1 | cut -d'-' -f1)

# Search for a checksum file that matches the iso file name with a wildcard pattern using find
checksum_file=$(find . -type f -name "$1-*")

# Check if a checksum file is found
if [ -z "$checksum_file" ]; then
    echo "No checksum file found."
    exit 2
fi

# Search for a signature file that matches the checksum file name with a wildcard pattern using find
signature_file=$(find . -type f -name "$checksum_file.*")

# Check if a signature file is found
if [ -z "$signature_file" ]; then
    echo "No signature file found."
    exit 3
fi

# Verify the checksum file against its detached signature using gpg
gpg --verify $signature_file $checksum_file || die "The checksum file is not verified."

# Extract only the SHA256 hash from the checksum file using grep
sha256=$(grep -oP 'SHA256 \(\S+\) = \K\S+' $checksum_file) || die "The checksum file is not valid."

# Compare the SHA256 hash with the iso file using sha256sum
echo "$sha256  $1" | sha256sum -c || die "The iso file is not verified."

# Print a success message
echo "The checksum and the iso file are verified."
tlaurion commented 12 months ago

Needs to be reworked

#!/bin/bash
# verify-signature.sh: Verify the iso file against its signature

# Source the /etc/functions file to use the die function
. /etc/functions

# Check if an iso file is provided as an argument
if [ $# -ne 1 ]; then
    die "Usage: $0 ISO"
fi

# Check if the iso file provided exists using test command
if [ ! -f $1 ]; then
    die "The iso file does not exist."
fi

# Extract only the directory name from the iso file argument using dirname
iso_dir=$(dirname $1)

# Search for a signature file that matches the iso file name with either .asc or .sig extension using find with -maxdepth 1 and -exec options
find $iso_dir -maxdepth 1 -type f \( -name "$1.asc" -o -name "$1.sig" \) -exec sh -c '
    # Assign the signature file name to a variable
    signature_file=$1

    # Check the content of the signature file using head command
    signature_head=$(head -n 1 $signature_file)

    # Handle different types of signatures using if statement
    if [ "$signature_head" = "-----BEGIN PGP SIGNATURE-----" ]; then # ASCII armored signature
        # No need to convert, use the original signature file for verification
    else # Binary or unknown signature type
        # Convert the binary signature to ASCII armored format using gpg with --enarmor option and save it in /tmp directory
        gpg --enarmor $signature_file > /tmp/$signature_file.asc || die "The signature file cannot be converted."
        # Use the converted signature file for verification
        signature_file=/tmp/$signature_file.asc
    fi

    # Verify the iso file against its detached signature using gpg with --status option
    gpg --status --verify $signature_file $1 || die "The iso file is not verified."

    # Delete the temporary signature file from /tmp directory using rm command
    rm $signature_file

    # Print a success message
    echo "The iso file is verified."
' _ {} \;
tlaurion commented 3 weeks ago

Interest for Ventoy restated on Dasharo Premier support channel (subscribers only) https://matrix.to/#/!RNcjJXCGHiyxXCHpKv:matrix.org/$oVg45lpw9Wev7EL3NTlgBGZin1C-NFVZ8YIAUeHlFU4?via=matrix.org&via=nitro.chat&via=matrix.3mdeb.com

Reopening to see interest and how Heads could support this (booting unverified integrity/authenticity ISOs) or better, detached signed hash files as explained above, and then have all those distro signing keys under Heads.

The latter would be ideal, where I have no funding nor time window to work on this for the moment and collaboration, as usual, would be desired.

tlaurion commented 3 weeks ago

PoC code that could be integrated into "Unsafe USB boot" at https://github.com/linuxboot/heads/issues/1438#issuecomment-1722386799

Comments?

fhvyhjriur commented 4 days ago

It would be great to see any ventoy support in heads. Ventoy even supports secure boot mode and can inject their ventoy key to what i tried out once. Ventoy is essential for things like this: https://github.com/linuxboot/heads/discussions/1722#discussioncomment-10601877 Thanks to ventoy i could work around the issue there.

Maybe interesting for the development: Ventoy is working fine with every seabios version i have ever tried out. Every ventoy version i tried worked always with any seabios version i tried.

natterangell commented 4 days ago

I would also welcome this.

Personally, I'd prefer that ISOs could be booted unsafely without any verification (maybe with a warning) as several distributions don't distribute detached signatures, and signing the iso with your own key does little to increase security of a downloaded ISO, and it's a little clunky to do. Since we can already boot any iso written to a USB without verification, I don't see the difference.

natterangell commented 4 days ago

Not to mention, it makes a whole lot of sense to use ventoy now that most flash drives are pretty large, so it's a better use of space. And with exfat now supported by Heads, the ISO-partition on a ventoy flash drive can be used with exfat and thus available cross-platform. Now problem with large ISO files either.