diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..082b4ff --- /dev/null +++ b/.dockerignore @@ -0,0 +1,40 @@ +# Build artifacts +output/ +tmp/ +tmp2/ +*.iso +*.sha256 +*.md5 +*.img +*.log + +# Build intermediates +knel-build/ +knel-iso/ +knel-custom/ +knel-final/ +artifacts/ +.chroot/ +.cache/ +.build/ + +# Secrets and keys +*key* +*.pem +*.crt +*.gpg +secrets/ +config/secureboot-keys/ + +# IDE and OS +.vscode/ +.idea/ +.DS_Store +*.swp +*.swo +*~ + +# Downloaded files +debian-*.iso +*.tar.gz +*.tar.xz diff --git a/.gitignore b/.gitignore index 1eca865..6c2dbbb 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,8 @@ debian-*.iso *.tar.xz # Security - don't commit sensitive configs -*key* +*.key *.pem *.crt -secrets/ \ No newline at end of file +secrets/ +secureboot-keys/ \ No newline at end of file diff --git a/STATUS.md b/STATUS.md index 1e88150..145f3a2 100644 --- a/STATUS.md +++ b/STATUS.md @@ -6,10 +6,22 @@ --- -## Current Status: 🔧 REMEDIATION IN PROGRESS +## Current Status: 🔧 REMEDIATION IN PROGRESS (Batch 3 - Honest Assessment) ### Executive Summary -Deep audit completed (2026-05-08). Report: `DeepReport-2026-05-08.md`. 39 findings total (6 CRITICAL, 9 HIGH, 12 MEDIUM, 7 LOW, 5 INFO). Now executing Phase 1 & 2 remediation. Compliance claims acknowledged as aspirational — technical controls being fixed now. +Deep audit (DeepReport-2026-05-08.md) had 39 findings. Three batches of fixes applied. +22 findings genuinely fixed, 6 remain open (3 deferred, 3 need human action). +ISO has NOT been rebuilt since fixes — needs `./run.sh iso` to validate. + +### What Changed in Batch 3 +- C-01 Argon2id: Fixed properly via preseed `partman/early_command` patching partman-crypto +- COMPLIANCE.md: Marked CMMC/FedRAMP as aspirational (not certified) +- VERIFICATION-REPORT.md: Added self-review warning, fixed preseed path +- Removed sshd_config generation from src/security-hardening.sh entirely +- Fixed AIDE init to report errors instead of swallowing them +- Added .dockerignore, fixed .gitignore `*key*` pattern +- Fixed phantom script reference in COMPLIANCE.md +- Added Argon2id early_command to demo.preseed.cfg --- diff --git a/config/hooks/installed/encryption-setup.sh b/config/hooks/installed/encryption-setup.sh index 8fd4ddd..2bc1864 100755 --- a/config/hooks/installed/encryption-setup.sh +++ b/config/hooks/installed/encryption-setup.sh @@ -86,7 +86,7 @@ Encryption Details: - Cipher: AES-256-XTS - Key Size: 512 bits - Hash: SHA-512 -- KDF: Argon2id +- KDF: Argon2id (configured via preseed early_command patch) Key Slots: - Slot 0: Primary passphrase (set during installation) diff --git a/config/hooks/installed/luks-kdf-configure.sh b/config/hooks/installed/luks-kdf-configure.sh index c336c64..6666c5e 100755 --- a/config/hooks/installed/luks-kdf-configure.sh +++ b/config/hooks/installed/luks-kdf-configure.sh @@ -1,17 +1,15 @@ #!/bin/bash -# LUKS KDF configuration hook - Auto-convert PBKDF2 to Argon2id -# Addresses C-01: Argon2id KDF not actually enforced -# -# Debian partman-crypto creates LUKS2 with PBKDF2 by default. -# This hook automatically converts to Argon2id during installation, -# before the system boots for the first time. +# LUKS KDF verification hook +# PRD FR-001 requires Argon2id. The preseed early_command patches +# partman-crypto to use --pbkdf argon2id at format time. This hook +# verifies the conversion succeeded and creates fallback tools if not. # # Reference: PRD.md FR-001, security-model.md # Copyright 2026 Known Element Enterprises LLC # License: GNU Affero General Public License v3.0 only set -euo pipefail -echo "Configuring LUKS KDF - auto-converting to Argon2id..." +echo "Verifying LUKS KDF configuration..." # Find the LUKS device LUKS_DEVICE="" @@ -22,42 +20,24 @@ for dev in /dev/sda3 /dev/nvme0n1p3 /dev/nvme1n1p3 /dev/vda3; do fi done -# Also try lsblk discovery if [ -z "$LUKS_DEVICE" ] && command -v lsblk >/dev/null 2>&1; then LUKS_DEVICE=$(lsblk -lnpo NAME,FSTYPE 2>/dev/null | awk '$2 == "crypto_LUKS" {print $1; exit}') fi if [ -z "$LUKS_DEVICE" ]; then - echo "WARNING: No LUKS device found for KDF conversion" - echo "Creating manual conversion helper instead..." + echo "WARNING: No LUKS device found for KDF verification" else echo "Found LUKS device: $LUKS_DEVICE" - - # Check current KDF CURRENT_KDF=$(cryptsetup luksDump "$LUKS_DEVICE" 2>/dev/null | grep -E "^\s+KDF:" | head -1 | awk '{print $2}' || echo "unknown") echo "Current KDF: $CURRENT_KDF" if [ "$CURRENT_KDF" = "argon2id" ]; then - echo "KDF is already Argon2id - no conversion needed." + echo "KDF verification PASSED: Argon2id confirmed" touch /var/lib/knel-kdf-optimized else - echo "Converting KDF from $CURRENT_KDF to Argon2id..." - echo "This requires the encryption passphrase set during installation." - - # Attempt non-interactive conversion - # The user's passphrase was just set during install and is in the installer env - if cryptsetup luksConvertKey "$LUKS_DEVICE" --pbkdf argon2id \ - --pbkdf-memory 524288 --pbkdf-parallel 4 --pbkdf-iterations 4 2>/dev/null; then - echo "SUCCESS: KDF converted to Argon2id" - touch /var/lib/knel-kdf-optimized - - # Verify - NEW_KDF=$(cryptsetup luksDump "$LUKS_DEVICE" 2>/dev/null | grep -E "^\s+KDF:" | head -1 | awk '{print $2}') - echo "Verified KDF: $NEW_KDF" - else - echo "WARNING: Automatic KDF conversion failed (likely passphrase prompt)" - echo "Manual conversion will be prompted on first login." - fi + echo "WARNING: KDF is $CURRENT_KDF, expected argon2id" + echo "The early_command patch may not have applied." + echo "Run /usr/local/bin/convert-luks-kdf.sh after first boot to convert." fi fi diff --git a/config/hooks/live/security-hardening.sh b/config/hooks/live/security-hardening.sh index 6a6892f..b07edb8 100755 --- a/config/hooks/live/security-hardening.sh +++ b/config/hooks/live/security-hardening.sh @@ -204,7 +204,12 @@ systemctl enable auditd # Initialize AIDE database if command -v aideinit >/dev/null 2>&1; then - aideinit --force 2>/dev/null || true + if aideinit --force; then + echo "AIDE database initialized successfully" + else + echo "WARNING: AIDE database initialization failed" + echo "Run 'aideinit --force' manually after installation" + fi fi # Create daily AIDE check cron job diff --git a/config/includes.installer/demo.preseed.cfg b/config/includes.installer/demo.preseed.cfg index 24b1fef..dafb514 100644 --- a/config/includes.installer/demo.preseed.cfg +++ b/config/includes.installer/demo.preseed.cfg @@ -105,6 +105,7 @@ d-i partman-crypto/cipher aes-xts-plain64 d-i partman-crypto/keysize 512 d-i partman-crypto/lvm boolean true d-i partman-crypto/use-luks2 boolean true +d-i partman/early_command string sed -i 's/cryptsetup luksFormat/cryptsetup --pbkdf argon2id --pbkdf-memory 524288 --pbkdf-parallel 4 luksFormat/g' /lib/partman-crypto/crypto-base.sh 2>/dev/null || true # Confirm partitioning d-i partman-partitioning/confirm_write_new_label boolean true diff --git a/config/includes.installer/preseed.cfg b/config/includes.installer/preseed.cfg index 8044df7..dc2ab6b 100644 --- a/config/includes.installer/preseed.cfg +++ b/config/includes.installer/preseed.cfg @@ -115,6 +115,11 @@ d-i partman-crypto/lvm boolean true # LUKS2 format (modern, more secure) d-i partman-crypto/use-luks2 boolean true +# Force Argon2id KDF by patching partman-crypto before it runs +# Debian's partman-crypto defaults to PBKDF2 even with LUKS2 +# This early_command patches crypto-base.sh to add --pbkdf argon2id +d-i partman/early_command string sed -i 's/cryptsetup luksFormat/cryptsetup --pbkdf argon2id --pbkdf-memory 524288 --pbkdf-parallel 4 luksFormat/g' /lib/partman-crypto/crypto-base.sh 2>/dev/null || true + # Confirm partitioning d-i partman-partitioning/confirm_write_new_label boolean true d-i partman/choose_partition select finish diff --git a/docs/COMPLIANCE.md b/docs/COMPLIANCE.md index 4673e70..d7bf2cc 100644 --- a/docs/COMPLIANCE.md +++ b/docs/COMPLIANCE.md @@ -4,15 +4,24 @@ This document maps security compliance requirements to implementation components in the KNEL-Football secure Debian 13 ISO build system. +> **IMPORTANT**: CMMC Level 3 and FedRAMP are **aspirational targets** for future production release. +> They require organizational controls (policies, assessments, 3PAO reviews) that do not yet exist. +> Current implementation covers **technical controls only**. No organizational certification has been obtained. +> DISA STIG IDs are adapted from RHEL STIGs (no Debian 13 STIG exists) and represent technical best-effort alignment. + **Copyright © 2026 Known Element Enterprises LLC** **License: GNU Affero General Public License v3.0 only** ## Compliance Frameworks -- **CMMC Level 3** - Entry point to tier0 infrastructure supporting ITAR/SECRET systems -- **FedRAMP LI-SaaS** - For RackRental.net federal government product -- **DISA STIG** - Debian STIG requirements (adapted from Debian 11 to Debian 13) -- **CIS Benchmarks** - Center for Internet Security Debian Linux Benchmark +| Framework | Status | Notes | +|-----------|--------|-------| +| **CMMC Level 3** | 🎯 Aspirational | Requires 130+ practices, 3PAO assessment | +| **FedRAMP LI-SaaS** | 🎯 Aspirational | Requires agency sponsorship, ConMon | +| **DISA STIG** | 🔧 Adapted | RHEL STIG IDs applied to Debian 13 (no Debian STIG exists) | +| **CIS Benchmarks** | ✅ Technical controls | Center for Internet Security Debian Linux Benchmark | +| **NIST SP 800-53** | ✅ Partial | ~12 controls mapped (800-53 has 1,000+) | +| **NIST SP 800-111** | ✅ Implemented | LUKS2 disk encryption configured | ## Security Controls Mapping @@ -78,11 +87,17 @@ This document maps security compliance requirements to implementation components ### In-ISO Validation -The built ISO includes test capabilities for post-installation validation: +Post-installation validation can be performed using: ```bash -# Run compliance validation on installed system -/usr/local/bin/knel-compliance-check.sh +# Check encryption status +/usr/local/bin/check-encryption.sh + +# Check security hardening status +/usr/local/bin/security-hardening.sh + +# Convert LUKS KDF to Argon2id (if not already done) +/usr/local/bin/convert-luks-kdf.sh ``` ## Compliance Evidence diff --git a/docs/VERIFICATION-REPORT.md b/docs/VERIFICATION-REPORT.md index cc138ed..0571b89 100644 --- a/docs/VERIFICATION-REPORT.md +++ b/docs/VERIFICATION-REPORT.md @@ -1,6 +1,11 @@ # KNEL-Football Secure OS - Work Verification Report -**Date**: 2026-02-19 +> **WARNING**: This report was generated by the same AI agent that wrote the code. +> It contains contradictions (two different build times: 72min vs 37min, two different +> checksum sets). It should NOT be relied upon as independent verification. +> A proper third-party security assessment is recommended before production deployment. + +**Date**: 2026-02-19 (updated 2026-05-08 with audit corrections) **Purpose**: Double-check all work completed for mandatory FDE and password complexity --- @@ -23,11 +28,11 @@ **Requirement**: All systems MUST use full disk encryption with LUKS2 **Verification**: -- ✅ **config/preseed.cfg**: Partition method set to "crypto" -- ✅ **config/preseed.cfg**: LUKS2 format enabled -- ✅ **config/preseed.cfg**: AES-XTS-plain64 cipher configured -- ✅ **config/preseed.cfg**: 512-bit key size configured -- ✅ **config/preseed.cfg**: LVM within encrypted partition +- ✅ **config/includes.installer/preseed.cfg**: Partition method set to "crypto" +- ✅ **config/includes.installer/preseed.cfg**: LUKS2 format enabled +- ✅ **config/includes.installer/preseed.cfg**: AES-XTS-plain64 cipher configured +- ✅ **config/includes.installer/preseed.cfg**: 512-bit key size configured +- ✅ **config/includes.installer/preseed.cfg**: LVM within encrypted partition - ✅ **config/hooks/installed/encryption-setup.sh**: LUKS2 configuration hook created - ✅ **config/hooks/installed/encryption-validation.sh**: Encryption validation hook created @@ -55,7 +60,7 @@ partman-crypto/use-luks2 boolean true **Requirement**: 14+ character minimum with complexity requirements **Verification**: -- ✅ **config/preseed.cfg**: Default passphrase set to 24-char complex password +- ✅ **config/includes.installer/preseed.cfg**: Default passphrase set to 24-char complex password - ✅ **config/hooks/installed/encryption-validation.sh**: Passphrase strength validation function - ✅ **PRD.md**: Detailed passphrase requirements documented - ✅ **AGENTS.md**: MANDATORY requirements section with passphrase requirements @@ -83,7 +88,7 @@ passwd/root-password-crypted string ! **Verification**: - ✅ **src/security-hardening.sh**: Enhanced password policy configured -- ✅ **config/preseed.cfg**: libpam-pwquality package included +- ✅ **config/includes.installer/preseed.cfg**: libpam-pwquality package included - ✅ **PRD.md**: Password complexity requirements documented - ✅ **AGENTS.md**: MANDATORY requirements section with password requirements @@ -404,7 +409,7 @@ knel-football-secure.iso: OK ✅ | File | Size | Status | |------|------|--------| -| config/preseed.cfg | 4.2 KB | ✅ Updated | +| config/includes.installer/preseed.cfg | 4.2 KB | ✅ Updated | | src/security-hardening.sh | Updated | ✅ Updated | ### 6.3 Hook Scripts ✅ diff --git a/src/security-hardening.sh b/src/security-hardening.sh index b5d5961..2dbe5a2 100755 --- a/src/security-hardening.sh +++ b/src/security-hardening.sh @@ -84,33 +84,16 @@ EOF echo "SSH client configuration created at $output_file" } -# Function to configure SSH hardening (server config as defense-in-depth) -# System is SSH client-only per PRD FR-006, but sshd_config is hardened defensively +# Function to ensure no SSH server configuration exists +# PRD FR-006: Client-only system. No sshd_config should ever exist. configure_ssh() { local output_file="${1:-/etc/ssh/sshd_config}" - cat >"$output_file" <<'EOF' -# SSH Server Hardening Configuration (defense-in-depth) -# Reference: PRD FR-006 - Client-only system, sshd not installed -# This config exists as a security baseline if sshd is ever installed - -# Protocol -Protocol 2 - -# Authentication -PermitRootLogin no -PermitEmptyPasswords no -MaxAuthTries 3 - -# Session -ClientAliveInterval 300 -ClientAliveCountMax 2 - -# Forwarding -X11Forwarding no -EOF - - echo "SSH hardening configuration created at $output_file" + # Remove any existing sshd_config to prevent accidental activation + if [[ -f "$output_file" && "$output_file" == /etc/ssh/sshd_config ]]; then + rm -f "$output_file" + fi + echo "SSH server config removed per PRD FR-006 (client-only system)" } # Function to configure password policy