scripts/iso R-61 slice 1: the baked root password becomes knowable (v1.24.0 train, part 1/3)
The ISO build now writes the minted throwaway root plaintext to a 0600 sibling file (<iso>.rootpw.txt: password + ISO name + build date) — the single record of truth. Never stdout/logs/manifest; the manifest carries only a pointer line. OUT_ISO naming hoisted above the mint (the sibling is named after the ISO); the mint itself and ROOT_PLAIN's lifetime are unchanged beyond the one file write. FELHOM_ISO_KEEP_WORK=1 debug escape added for the harness. New test/rootpw-emission.sh: dry-run emission, 0600, plaintext<->answer-hash cross-check (openssl -6 -salt), no plaintext on stdout, manifest-heredoc guard. Red-proof run: plaintext injected into the manifest heredoc -> harness FAILs -> restored. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UuFPHmHNrCJj1VhY6QdDMU
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
#===============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
ISO_VERSION="1.22.0" # Felhom release the ISO is tagged to (aligns with felhom-host-install SCRIPT_VERSION).
|
||||
ISO_VERSION="1.24.0" # Felhom release the ISO is tagged to (aligns with felhom-host-install SCRIPT_VERSION).
|
||||
IMAGE="${FELHOM_ISO_ASSISTANT_IMAGE:-felhom-iso-assistant:trixie}"
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
@@ -208,7 +208,15 @@ fi
|
||||
# --- workspace ------------------------------------------------------------------------------------
|
||||
WORK="$(mktemp -d "${TMPDIR:-/tmp}/felhom-iso.XXXXXX")"
|
||||
# chmod first: the mkimage surgery's osirrox extract leaves read-only file modes that rm can't clear.
|
||||
cleanup() { chmod -R u+w "$WORK" 2>/dev/null || true; rm -rf "$WORK"; }
|
||||
# FELHOM_ISO_KEEP_WORK=1 is a DEBUG/TEST escape: keep $WORK for post-mortem (the rootpw-emission
|
||||
# harness cross-checks the emitted plaintext against the rendered answer's hash). Never a build mode.
|
||||
cleanup() {
|
||||
if [[ "${FELHOM_ISO_KEEP_WORK:-0}" == "1" ]]; then
|
||||
log_warn "FELHOM_ISO_KEEP_WORK=1 — workspace KEPT at $WORK (debug/test only; delete it yourself)"
|
||||
return 0
|
||||
fi
|
||||
chmod -R u+w "$WORK" 2>/dev/null || true; rm -rf "$WORK"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
mkdir -p "$OUT_DIR" "$WORK/tmp"
|
||||
ISO_DIR="$(cd "$(dirname "$PVE_ISO")" && pwd)"; ISO_BASE="$(basename "$PVE_ISO")"
|
||||
@@ -226,13 +234,27 @@ EOF
|
||||
log_info "generated secret-free pairing env (hub=$PAIR_HUB_URL)"
|
||||
fi
|
||||
|
||||
# --- resolve the output ISO name (needed by the mint below: the rootpw sibling file is named after
|
||||
# the ISO). Rule 4: the loader mode is loud in the filename — a '-mkimage' ISO implies
|
||||
# Secure-Boot-off prep. -----------------------------------------------------------------------
|
||||
LOADER_SUFFIX=""; [[ "$LOADER" != "shim" ]] && LOADER_SUFFIX="-${LOADER}"
|
||||
MODE_SUFFIX=""; $PAIRING && MODE_SUFFIX="-generic" # the secret-free universal ISO is unmistakable
|
||||
OUT_ISO="$OUT_DIR/felhom-pve-${PVE_VERSION}-v${ISO_VERSION}-${PROFILE_NAME}${MODE_SUFFIX}${LOADER_SUFFIX}.iso"
|
||||
|
||||
# --- mint fresh THROWAWAY root hash ---------------------------------------------------------------
|
||||
log_step "minting fresh throwaway root password hash"
|
||||
ROOT_PLAIN="felhom-throwaway-$(head -c12 /dev/urandom | base64 | tr -dc 'A-Za-z0-9')"
|
||||
ROOT_HASH="$(openssl passwd -6 "$ROOT_PLAIN")"
|
||||
# R-61 slice 1: the baked root password becomes KNOWABLE. The plaintext is written to a 0600 sibling
|
||||
# file next to the ISO — the SINGLE record of truth — and nowhere else: never stdout/stderr/logs,
|
||||
# never the manifest (manifests get pasted into committed REPORTs; a separate file cannot ride along
|
||||
# by accident). A fixed well-known password stays REJECTED (operator ruling 2026-07-21): a
|
||||
# pre-pairing box sits on a stranger's LAN. Note: an aborted build can leave a rootpw file for an
|
||||
# ISO that was never produced; the next build of the same name overwrites it.
|
||||
( umask 077; printf '%s %s built %s\n' "$ROOT_PLAIN" "$(basename "$OUT_ISO")" "$(date -Is)" > "$OUT_ISO.rootpw.txt" )
|
||||
unset ROOT_PLAIN
|
||||
[[ -n "$ROOT_HASH" ]] || die "failed to mint root hash"
|
||||
log_info "throwaway root hash written to the answer file (value stored out-of-band, not logged)"
|
||||
log_info "throwaway root hash written to the answer file; plaintext in $(basename "$OUT_ISO").rootpw.txt (0600, operator-only — value not logged)"
|
||||
|
||||
# --- render answer.toml (pure bash param-expansion; no metachar hazards) ---------------------------
|
||||
log_step "rendering answer.toml"
|
||||
@@ -283,10 +305,7 @@ chmod 0755 "$STUB"
|
||||
grep -q '@@BOOTSTRAP_.*_B64@@' "$STUB" && die "stub still has unfilled markers — injection failed"
|
||||
|
||||
# --- prepare-iso ----------------------------------------------------------------------------------
|
||||
# Rule 4: the loader mode is loud in the filename — a '-mkimage' ISO implies Secure-Boot-off prep.
|
||||
LOADER_SUFFIX=""; [[ "$LOADER" != "shim" ]] && LOADER_SUFFIX="-${LOADER}"
|
||||
MODE_SUFFIX=""; $PAIRING && MODE_SUFFIX="-generic" # the secret-free universal ISO is unmistakable
|
||||
OUT_ISO="$OUT_DIR/felhom-pve-${PVE_VERSION}-v${ISO_VERSION}-${PROFILE_NAME}${MODE_SUFFIX}${LOADER_SUFFIX}.iso"
|
||||
# (OUT_ISO is resolved above the mint — the rootpw sibling file is named after it.)
|
||||
GRUB_VERSION="" # populated by the mkimage surgery (the grub-mkimage build used)
|
||||
log_step "building ISO: $(basename "$OUT_ISO")"
|
||||
if $DRY_RUN; then
|
||||
@@ -361,6 +380,7 @@ boot-menu : ${BRAND_NOTE}
|
||||
$( $BRAND && cat "$WORK/brand-report.txt" 2>/dev/null || true )
|
||||
host-install-url : $(grep -oE 'FELHOM_INSTALL_URL=[^ ]*' "$BOOTSTRAP_ENV" 2>/dev/null || echo 'https://felhom.eu/scripts/felhom-host-install.sh (default)')
|
||||
secret-bearing : ${SECRET_BEARING}$( $PAIRING && echo ' (GENERIC ISO — carries NO customer secret)' || echo ' (embeds the customer retrieval passphrase — supervised/single-use, delete after the run)')
|
||||
root-password : see $(basename "$OUT_ISO").rootpw.txt (operator-only; NEVER commit or paste into REPORTs)
|
||||
output : $(basename "$OUT_ISO")
|
||||
output-sha256 : ${OUT_SHA}
|
||||
output-size-bytes : ${OUT_SIZE}
|
||||
@@ -370,6 +390,7 @@ log_success "ISO built: $OUT_ISO"
|
||||
log_info "sha256 : $OUT_SHA"
|
||||
log_info "size : $OUT_SIZE bytes"
|
||||
log_info "manifest : $OUT_ISO.manifest.txt"
|
||||
log_info "root-pw : $OUT_ISO.rootpw.txt (0600, operator-only — the console credential for this build; never commit/paste)"
|
||||
if $PAIRING; then
|
||||
log_success "GENERIC secret-free ISO — carries NO customer secret. Bind the box on the hub after it registers."
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user