heads/initrd/bin/qubes-init
Trammell Hudson 174bb64957
Move Qubes startup script to /boot/boot.sh
This also adds a set of files in the qubes/ directory that
are meant to be copied to the /boot partition.

Issue #154: for ease of upgrading Qubes, the script should
live on /boot instead of in the ROM.  This requires a GPG
signature on the startup script to avoid attacks by modifying
the boot script.

Issue #123: this streamlines the boot process for Qubes, although
the disk password is still not passed in correctly to the initrd
(issue #29).

This does not address issues #110 of how to find the root device.
The best approach is probably disk labels, which will require
special installation instructions.
2017-04-02 22:21:49 -04:00

90 lines
2.4 KiB
Bash
Executable File

#!/bin/sh
# Boot a Qubes installation that has already been setup.
# This depends on the PCR 4 being "normal-boot":
# f8fa3b6e32e7c6fe04c366e74636e505b28f3b0d
# which is only set if the top level /init script has started
# without user intervention or dropping into a recovery shell.
recovery() {
echo >&2 "!!!!! $@"
rm -f /tmp/secret.key
tpm extend -ix 4 -if recovery
echo >&2 "!!!!! Starting recovery shell"
exec /bin/ash
}
. /config
# TODO: Allow /boot to be encrypted?
# This would require a different TPM key or a user
# passphrase to decrypt it.
mount -o ro "$CONFIG_QUBES_BOOT_DEV" /boot \
|| recovery '$CONFIG_BOOT_DEV: Unable to mount /boot'
BOOT_SCRIPT=/boot/boot.sh
if [ ! -x /boot/boot.sh ]; then
recovery "$BOOT_SCRIPT does not exist"
fi
# Hand control over to the user boot script
echo "+++ Checking $BOOT_SCRIPT"
gpgv "$BOOT_SCRIPT.asc" "$BOOT_SCRIPT" \
|| recovery 'boot script signature failed'
exec "$BOOT_SCRIPT"
recovery 'Boot script exec failed?'
############################
# For historical reference
# TODO: Allow these to be specified on the /boot device
XEN=/boot/xen-4.6.3.heads
INITRD=/boot/initramfs-4.4.31-11.pvops.qubes.x86_64.img
KERNEL=/boot/vmlinuz-4.4.31-11.pvops.qubes.x86_64
echo "+++ Checking $XEN"
gpgv "${XEN}.asc" "${XEN}" \
|| recovery 'Xen signature failed'
echo "+++ Checking $INITRD"
gpgv "${INITRD}.asc" "${INITRD}" \
|| recovery 'Initrd signature failed'
echo "+++ Checking $KERNEL"
gpgv "${KERNEL}.asc" "${KERNEL}" \
|| recovery 'Kernel signature failed'
# Measure the LUKS headers before we unseal the disk key
/bin/qubes-measure-luks $CONFIG_QUBES_DEVS \
|| recovery "LUKS measure failed"
# Attempt to unseal the disk key from the TPM
# should we give this some number of tries?
unseal-key \
|| recovery 'Unseal disk key failed. Starting recovery shell'
# command line arguments are in the hash, so they are "correct".
kexec \
-l \
--module "${KERNEL} root=LABEL=root ro rd.qubes.hide_all_usb rhgb" \
--module "${INITRD}" \
--command-line "no-real-mode reboot=no"
"${XEN}" \
|| recovery "kexec load failed"
kexec -l \
--module "${KERNEL} root=UUID=257b593f-d4ae-46ee-b499-14bc9ffd37d4 ro rd.qubes.hide_all_usb" \
--module "/boot/initramfs-4.4.31-11.pvops.qubes.x86_64.img" \
--command-line "no-real-mode reboot=no" \
/boot/xen-4.6.3.heads
# Last step is to override PCR 6 so that user can't read the key
tpm extend -ix 4 -ic qubes \
|| recovery 'Unable to scramble PCR'
echo "+++ Starting Qubes..."
exec kexec -e