Harden SecureBoot.sh: UEFI check, verify paths, confirm before enroll
- set -euo pipefail and fix pacman --noconfirm typo (was -noconfirm) - abort on non-UEFI systems (/sys/firmware/efi check) - verify sbctl installed and sign targets exist before touching keys - fix x84_64-efi typo, skip missing targets instead of failing silently - require sbctl verify to pass before offering enrollment - prompt y/N before enroll-keys with BIOS/USB recovery guidance - gate success message on final sbctl verify, non-zero exit on failure
This commit is contained in:
+98
-12
@@ -1,25 +1,111 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Detect fish shell and ask user to switch to bash (bash-only syntax)
|
||||
if [ -n "${FISH_VERSION:-}" ] || case "$SHELL" in *fish*) ;; *) false ;; esac; then
|
||||
if [ -n "${FISH_VERSION:-}" ] || case "${SHELL:-}" in *fish*) ;; *) false ;; esac; then
|
||||
echo "Warning: fish shell detected."
|
||||
echo "This script is written for bash and may have syntax issues under fish."
|
||||
echo "Please switch to bash first and re-run it, e.g.: bash $0"
|
||||
if [ -t 0 ] && [ -e /dev/tty ]; then
|
||||
read -r -p "Press Enter to continue anyway, or Ctrl+C to cancel..." </dev/tty || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install Prerequisites
|
||||
sudo pacman -S --needed -noconfirm efibootmgr sbsigntools mokutil sbctl grub
|
||||
# Secure Boot setup only applies to UEFI systems (meaningless on BIOS/CSM)
|
||||
if [ ! -d /sys/firmware/efi ]; then
|
||||
echo "error: this system is not booted in UEFI mode (/sys/firmware/efi is missing)." >&2
|
||||
echo "Secure Boot setup does not apply to BIOS/CSM machines. Aborting." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v pacman >/dev/null; then
|
||||
echo "error: pacman not found. This script only supports Arch-based systems." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install prerequisites
|
||||
sudo pacman -S --needed --noconfirm efibootmgr sbsigntools mokutil sbctl grub
|
||||
|
||||
# Fail early if the toolchain is still missing (do not touch keys otherwise)
|
||||
if ! command -v sbctl >/dev/null; then
|
||||
echo "error: sbctl is not available after installation. Install it manually and re-run." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Candidate sign targets. GRUB's path and the kernel image name vary by
|
||||
# machine, so every path is checked before signing instead of trusted blindly.
|
||||
SIGN_TARGETS=(
|
||||
/boot/EFI/BOOT/BOOTX64.EFI
|
||||
/boot/grub/x86_64-efi/core.efi
|
||||
/boot/grub/x86_64-efi/grub.efi
|
||||
/boot/vmlinuz-linux
|
||||
)
|
||||
|
||||
missing=0
|
||||
for target in "${SIGN_TARGETS[@]}"; do
|
||||
if [ ! -e "$target" ]; then
|
||||
echo "warning: $target does not exist on this machine, skipping" >&2
|
||||
missing=$((missing + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$missing" -eq "${#SIGN_TARGETS[@]}" ]; then
|
||||
echo "error: none of the expected boot files exist; refusing to continue." >&2
|
||||
echo "Adjust SIGN_TARGETS for this machine and re-run." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo sbctl create-keys
|
||||
sudo sbctl enroll-keys --microsoft
|
||||
sudo sbctl verify
|
||||
# use sudo sbctl sign -s for every unsigned item
|
||||
sudo sbctl sign -s /boot/EFI/BOOT/BOOTX64.EFI
|
||||
sudo sbctl sign -s /boot/grub/x84_64-efi/core.efi
|
||||
sudo sbctl sign -s /boot/grub/x86_64-efi/grub.efi
|
||||
sudo sbctl sign -s /boot/vmlinuz-linux
|
||||
|
||||
for target in "${SIGN_TARGETS[@]}"; do
|
||||
if [ -e "$target" ]; then
|
||||
sudo sbctl sign -s "$target"
|
||||
fi
|
||||
done
|
||||
|
||||
# Every file must verify BEFORE enrollment - enrollment is hard to undo
|
||||
echo "Verifying signatures before enrollment..."
|
||||
if ! sudo sbctl verify; then
|
||||
echo "error: sbctl verify reports unsigned or badly signed files." >&2
|
||||
echo "Fix these first (sudo sbctl sign -s <file>). Not enrolling." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "All boot files are signed and verified."
|
||||
echo ""
|
||||
echo "Before enrolling keys, be ready for what can go wrong:"
|
||||
echo " - After enrollment, any file not signed with these keys will not boot."
|
||||
echo " - To recover: enter BIOS and disable Secure Boot (or boot a USB stick),"
|
||||
echo " then run 'sudo sbctl unenroll' or re-sign the missing files."
|
||||
echo " - Keep a bootable USB / BIOS access available for the first reboot."
|
||||
echo ""
|
||||
|
||||
# Only enroll when a human explicitly says so, and only when we have a terminal
|
||||
enroll=""
|
||||
if [ -t 0 ] && [ -e /dev/tty ]; then
|
||||
read -r -p "Enroll Secure Boot keys now? [y/N] " enroll </dev/tty || enroll=""
|
||||
fi
|
||||
|
||||
case "$enroll" in
|
||||
y | Y | yes | YES)
|
||||
sudo sbctl enroll-keys --microsoft
|
||||
;;
|
||||
*)
|
||||
echo "Enrollment skipped. Nothing has been enrolled."
|
||||
echo "When you are ready, run: sudo sbctl enroll-keys --microsoft"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
sudo sbctl status
|
||||
sudo sbctl verify
|
||||
echo "Use sudo sbctl sign -s for every unsigned item"
|
||||
|
||||
if sudo sbctl verify; then
|
||||
echo ""
|
||||
echo "Success: every file is signed and verified."
|
||||
echo "Reboot and confirm the machine boots with Secure Boot enabled."
|
||||
else
|
||||
echo "error: verification failed after signing. Do not reboot yet." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user