Files
archy/scripts/install-kernel-security.sh

42 lines
2.5 KiB
Bash

#!/usr/bin/env bash
# Explicit administrator/prerequisite operation; never called as a generic RPC.
# Installs a verified Debian kernel. It does not reboot or claim the running
# kernel is fixed. Keep the existing kernel/boot entries for recovery.
set -euo pipefail
[[ $(id -u) == 0 ]] || { echo 'Root administrator required' >&2; exit 1; }
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
source /etc/os-release
[[ ${ID:-} == debian ]] || { echo 'Vendor-specific kernel qualification required' >&2; exit 1; }
case "${VERSION_CODENAME:-}" in
trixie) series=6.12; minimum=6.12.113-1 ;;
bookworm) series=6.1; minimum=6.1.190-1 ;;
*) echo 'Unsupported suite: qualify its fixed kernel before installation' >&2; exit 1 ;;
esac
arch=$(dpkg --print-architecture)
case "$arch" in amd64|arm64) ;; *) echo 'Unsupported kernel architecture' >&2; exit 1 ;; esac
[[ $(uname -r) == "$series".* ]] || {
echo 'Kernel series differs from the suite default; qualify its backport/vendor upgrade instead of downgrading it' >&2; exit 1;
}
# A vendor/Raspberry Pi kernel cannot be replaced with a generic Debian kernel
# without its own firmware/boot qualification.
running_package="linux-image-$(uname -r)"
case "$running_package" in *rpi*|*rpt*|*raspi*)
echo 'Pi vendor boot path requires separate qualification' >&2; exit 1 ;;
esac
source_package=$(dpkg-query -W -f='${source:Package}' "$running_package" 2>/dev/null || true)
case "$source_package" in linux|linux-6.12|linux-signed-amd64|linux-signed-arm64) ;;
*) echo 'Running vendor/unowned kernel: refusing a generic replacement' >&2; exit 1 ;;
esac
export DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=l
apt-get update
package="linux-image-$arch"
candidate=$(LC_ALL=C apt-cache policy "$package" | python3 -c 'import re,sys;m=re.search(r"^\s*Candidate:\s*(\S+)",sys.stdin.read(),re.M);print(m.group(1) if m else "")')
[[ "$candidate" == "$series".* ]] && dpkg --compare-versions "$candidate" ge "$minimum" || {
echo "No qualified fixed $package candidate is available (minimum $minimum)" >&2; exit 1;
}
# Normal authenticated APT verification remains enabled. No blanket upgrade,
# autoremove, native-service restart, key change or automatic reboot.
apt-get -o APT::Get::AllowUnauthenticated=false install -y --no-install-recommends "$package=$candidate" python3-apt
python3 "$ROOT/kernel-security.py" --installed --record-provenance
echo 'Fixed kernel installed. Reboot and pass kernel-security.py --running before calling this node patched.'