feat: add mandatory host FDE check for build/test operations

- Add check_host_fde() function to run.sh that detects LUKS encryption
- Block ./run.sh iso if host lacks full disk encryption
- Block ./run.sh test:iso commands if host lacks FDE
- Add FR-011 to PRD.md documenting the host FDE requirement
- Update AGENTS.md with new mandatory requirement
- Add 9 tests for host FDE check in run_comprehensive_test.bats

Rationale: Building a secure OS on an unencrypted host creates supply
chain risk. The host must have LUKS encryption to ensure the entire
build pipeline is secure.

💘 Generated with Crush

Assisted-by: GLM-5 via Crush <crush@charm.land>
This commit is contained in:
Charles N Wyble
2026-02-19 17:11:54 -05:00
parent d4c64b85fa
commit 872da4cf82
5 changed files with 614 additions and 7 deletions

82
run.sh
View File

@@ -39,6 +39,86 @@ log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Create output and build directories if they don't exist
mkdir -p "${OUTPUT_DIR}" "${BUILD_DIR}"
# ============================================================================
# HOST FDE CHECK (MANDATORY)
# ============================================================================
# Check if host system has full disk encryption enabled
# This is MANDATORY - building or testing a secure OS on an unencrypted host
# defeats the entire security model
check_host_fde() {
log_info "Checking host system for Full Disk Encryption..."
local has_luks=false
local encrypted_root=false
# Method 1: Check for LUKS devices via lsblk
if lsblk -o TYPE,FSTYPE 2>/dev/null | grep -q "crypt"; then
has_luks=true
log_info "Found LUKS encrypted partitions"
fi
# Method 2: Check if root filesystem is on a dm-crypt device
if [[ -e /dev/mapper/root ]] || [[ -e /dev/mapper/rootfs ]]; then
encrypted_root=true
log_info "Root filesystem appears to be on encrypted device"
fi
# Method 3: Check /etc/crypttab for configured encrypted partitions
if [[ -f /etc/crypttab ]] && grep -qE "^[^#]" /etc/crypttab 2>/dev/null; then
has_luks=true
log_info "Found encrypted partitions in /etc/crypttab"
fi
# Method 4: Check for dm-crypt devices in /sys/block
if ls /sys/block/dm-* 2>/dev/null | head -1 | grep -q .; then
for dm_dev in /sys/block/dm-*; do
if [[ -f "${dm_dev}/dm/name" ]]; then
local dm_name
dm_name=$(cat "${dm_dev}/dm/name" 2>/dev/null)
# Check if this is a LUKS device
if [[ -f "${dm_dev}/dm/uuid" ]] && grep -qi "CRYPT-LUKS" "${dm_dev}/dm/uuid" 2>/dev/null; then
has_luks=true
log_info "Found LUKS device: ${dm_name}"
fi
fi
done
fi
# Method 5: Check root mount point for encryption
local root_device
root_device=$(findmnt -n -o SOURCE / 2>/dev/null || echo "")
if [[ "$root_device" == /dev/mapper/* ]] || [[ "$root_device" == *"crypt"* ]]; then
encrypted_root=true
log_info "Root filesystem is on encrypted device: $root_device"
fi
# Require at least one indicator of FDE
if [[ "$has_luks" == "true" || "$encrypted_root" == "true" ]]; then
log_info "Host FDE check PASSED"
return 0
fi
# FDE not detected - this is a FATAL error
log_error "============================================================"
log_error "SECURITY REQUIREMENT VIOLATION"
log_error "============================================================"
log_error "Host system does NOT have Full Disk Encryption enabled."
log_error ""
log_error "Building or testing KNEL-Football Secure OS requires the"
log_error "host system to be encrypted with LUKS. An unencrypted host"
log_error "defeats the entire security model."
log_error ""
log_error "To enable FDE on Debian/Ubuntu:"
log_error " 1. Backup all data"
log_error " 2. Reinstall with 'Guided - use entire disk and set up encrypted LVM'"
log_error " 3. Or use: https://github.com/The Firefoxlyer/encrypt-existing-debian"
log_error ""
log_error "This check is MANDATORY and cannot be bypassed."
log_error "============================================================"
return 1
}
# ============================================================================
# VM TESTING FUNCTIONS (merged from test-iso.sh)
# ============================================================================
@@ -485,6 +565,7 @@ main() {
bash
;;
iso)
check_host_fde || exit 1
echo "Building KNEL-Football secure ISO..."
echo "ALL operations run inside Docker container"
echo "Timezone: America/Chicago"
@@ -551,6 +632,7 @@ fi
monitor_build "${2:-180}"
;;
test:iso)
check_host_fde || exit 1
shift # Remove 'test:iso' from args
local subcmd="${1:-help}"
case "$subcmd" in