555 lines
No EOL
23 KiB
Text
555 lines
No EOL
23 KiB
Text
#version=DEVEL
|
||
# AlmaLinux 10.2 Unattended Installation Kickstart — BigBoy Sovereign AI Server
|
||
#
|
||
# This kickstart automates Phase 1 (Base OS Installation & Foundation)
|
||
# Designed for 5-drive architecture: 1× NVMe (OS) + 4× SATA (data)
|
||
#
|
||
# Usage:
|
||
# USB method: Insert USB, boot, type: inst.ks=file:///ks.cfg
|
||
# HTTP method: Boot, type: inst.ks=http://<workbench_ip>:8000/alma10-minimal-bigboy.ks
|
||
#
|
||
# Reference: plannng/alma-phase1-install-workflow.md
|
||
#
|
||
# Checksum (validate before use):
|
||
# sha256sum alma10-minimal-bigboy.ks
|
||
# (Note: Update after final edits)
|
||
#
|
||
# BEFORE USING THIS FILE — fill in both placeholders below:
|
||
# <user-name> — your administrator account username
|
||
# <sha512-hash> — output of `openssl passwd -6`, run on any Linux box.
|
||
# NEVER put a plaintext password in this file — it is
|
||
# committed to git and lives in history permanently.
|
||
#
|
||
# ============================================================================
|
||
|
||
# ============================================================================
|
||
# INSTALLATION MODE & FIRST BOOT
|
||
# ============================================================================
|
||
|
||
# Use text mode installer (no GUI needed for headless server)
|
||
text
|
||
|
||
# Do not run Setup Agent on first boot (we handle via Ansible Phase 2)
|
||
firstboot --disable
|
||
|
||
# ============================================================================
|
||
# LOCALIZATION & SYSTEM CONFIGURATION
|
||
# ============================================================================
|
||
|
||
# Keyboard layout: US (standard for IT infrastructure)
|
||
keyboard --xlayouts='us'
|
||
|
||
# System language: English (UTF-8 for international support)
|
||
lang en_US.UTF-8
|
||
|
||
# System timezone: Europe/Rome UTC (CE headquarters timezone)
|
||
# Logs will use this timezone for consistency across deployment
|
||
timezone Europe/Rome --utc
|
||
|
||
# ============================================================================
|
||
# NETWORK CONFIGURATION
|
||
# ============================================================================
|
||
|
||
# Network: DHCP on primary interface (enp4s0)
|
||
# Will typically receive an address on the workbench bench LAN
|
||
# (192.168.0.0/24) during build/maintenance. Phase 13 later migrates
|
||
# BigBoy to the home LAN (192.168.1.0/24).
|
||
network --bootproto=dhcp --device=link --activate --hostname=bigboy --ipv6=off
|
||
|
||
# ============================================================================
|
||
# SECURITY & AUTHENTICATION
|
||
# ============================================================================
|
||
|
||
# Root password: LOCK (no password login allowed)
|
||
# All administrative access happens through the account below, plus sudo.
|
||
rootpw --lock
|
||
|
||
# ----------------------------------------------------------------------
|
||
# USER ACCOUNT (Administrator access)
|
||
# ----------------------------------------------------------------------
|
||
#
|
||
# Password login is enabled deliberately for initial bring-up — not every
|
||
# device John works from has an SSH key provisioned yet. This is an
|
||
# intentional, temporary loosening: Phase 9 (Security Hardening) disables
|
||
# PasswordAuthentication and moves to key-only, matching the same
|
||
# kickstart-lenient / Ansible-hardens pattern used for SELinux and
|
||
# firewalld elsewhere in this file. Don't remove password login without
|
||
# confirming a working key-based login first — until Phase 9 runs, this
|
||
# password is the only way in.
|
||
#
|
||
# The value below MUST be a hash, never a plaintext password — this file
|
||
# is committed to git and the value lives in history permanently even if
|
||
# changed later. Generate with:
|
||
# openssl passwd -6
|
||
# on any Linux box, then paste the resulting $6$... hash in place of
|
||
# <sha512-hash>.
|
||
|
||
user --name=<user-name> --groups=wheel --shell=/bin/bash --password=<sha512-hash> --iscrypted
|
||
|
||
# SELinux: Disabled for initial deployment (Phase 9 enables in Permissive)
|
||
# Allows us to monitor denials during first month without blocking services
|
||
selinux --disabled
|
||
|
||
# ----------------------------------------------------------------------
|
||
# FIREWALL: Enabled from first boot — LAN-only SSH access
|
||
# ----------------------------------------------------------------------
|
||
#
|
||
# Originally planned as disabled-until-Phase-9. That plan assumed
|
||
# key-only SSH from the start; since password auth is enabled above for
|
||
# initial bring-up, leaving the firewall off would mean password-auth SSH
|
||
# is reachable from anywhere that can route to this box — not acceptable
|
||
# even temporarily.
|
||
#
|
||
# firewalld starts enabled; the default zone carries no blanket SSH
|
||
# allowance. %post below adds rich rules restricting SSH specifically to
|
||
# the two known LAN ranges:
|
||
# 192.168.1.0/24 — home LAN (also covers WireGuard VPN clients, which
|
||
# Fritz bridges directly into this range — confirmed
|
||
# 2026-07-16, no separate VPN subnet exists)
|
||
# 192.168.0.0/24 — workbench bench LAN (BigBoy's build/maintenance
|
||
# network; also what's reached by devices whose
|
||
# home-LAN traffic workbench NATs onto the bench
|
||
# switch — arrives with workbench's bench-LAN address,
|
||
# already covered by this same range)
|
||
#
|
||
# No forwarded port 22 exists on the router, so this firewall rule is a
|
||
# second layer, not the only thing standing between BigBoy and the open
|
||
# internet — but it's the correct posture regardless, especially with
|
||
# password auth active.
|
||
#
|
||
# Phase 9 still applies its broader hardening pass on top of this
|
||
# baseline; that pass should also revoke the temporary password-login
|
||
# exception above, not just review the firewall further.
|
||
|
||
firewall --enabled
|
||
|
||
# ============================================================================
|
||
# REPOSITORY CONFIGURATION
|
||
# ============================================================================
|
||
|
||
# Base URL: AlmaLinux 10 official repositories
|
||
# Uses kickstart mirror for fastest package downloads during install
|
||
url --url="https://repo.almalinux.org/almalinux/10/BaseOS/x86_64/kickstart/"
|
||
|
||
# AppStream repository (applications, runtimes, development tools)
|
||
repo --name="almalinux10-appstream" --mirrorlist="https://mirrors.almalinux.org/mirrorlist/10/appstream"
|
||
|
||
# CodeReady Linux Builder (CRB, equivalent to AlmaLinux 8 PowerTools)
|
||
# Contains development packages needed for Phase 4 GPU driver compilation
|
||
repo --name="almalinux10-crb" --mirrorlist="https://mirrors.almalinux.org/mirrorlist/10/crb/"
|
||
|
||
# EPEL (Extra Packages for Enterprise Linux)
|
||
# Additional packages not in standard RHEL repos
|
||
repo --name="epel10" --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=epel-10&arch=x86_64"
|
||
|
||
# NOTE: these repos require real outbound internet access during install,
|
||
# not just reachability within the bench LAN — confirm this path is open
|
||
# before booting, not after a stalled package download mid-install.
|
||
|
||
# ============================================================================
|
||
# BOOTLOADER CONFIGURATION
|
||
# ============================================================================
|
||
|
||
# Bootloader: UEFI (modern standard)
|
||
# Boot drive: NVMe (primary OS drive)
|
||
# Location: partition (for UEFI boot)
|
||
bootloader --location=partition --boot-drive=nvme0n1
|
||
|
||
# ============================================================================
|
||
# DISK PARTITIONING SCHEME
|
||
# ============================================================================
|
||
#
|
||
# Design:
|
||
# NVMe (500GB): EFI boot (1GB) + btrfs OS (~499GB)
|
||
# SATA Drive 1 (RAG): Single btrfs partition (mounted by Phase 3 Ansible)
|
||
# SATA Drive 2 (Prompt): Single btrfs partition (mounted by Phase 3 Ansible)
|
||
# SATA Drive 3 (Backup): Single btrfs partition (mounted by Phase 3 Ansible)
|
||
# SATA Drive 4 (AI Logs): Single btrfs partition (mounted by Phase 3 Ansible)
|
||
#
|
||
# Important: SATA partitions are created but NOT mounted during kickstart.
|
||
# Phase 3 Ansible role handles subvolume creation, mounting, and fstab.
|
||
#
|
||
# Drive identity confirmed 2026-07-16 via blkid labels prior to wipe:
|
||
# sda = BACKUPDRV, sdb = RAGLIB, sdc = AILOGS, sdd = PROMPTLIB
|
||
# (labels are destroyed by the wipe/reinstall — recorded here for
|
||
# provenance only; Phase 3 re-establishes them from group_vars/bigboy.yml)
|
||
# ============================================================================
|
||
|
||
# Do not erase existing partitions (safety measure)
|
||
clearpart --none --initlabel
|
||
|
||
# ============================================================================
|
||
# NVMe PARTITIONING (Primary OS drive)
|
||
# ============================================================================
|
||
|
||
# Partition 1: EFI System Partition
|
||
# Size: 1 GB (sufficient for kernel + bootloader)
|
||
# Filesystem: vfat (EFI standard)
|
||
# Mount: /boot/efi (handled by Anaconda)
|
||
part /boot/efi --fstype=efi --size=1024 --ondrive=nvme0n1
|
||
|
||
# Partition 2: OS Root (btrfs)
|
||
# Size: Grow to fill remaining NVMe space (~499 GB)
|
||
# Filesystem: btrfs (enables snapshots, compression, subvolumes)
|
||
# Mount: / (root filesystem)
|
||
# Note: Anaconda will create default btrfs layout; Phase 3 Ansible reconfigures
|
||
part / --fstype=btrfs --size=1 --grow --ondrive=nvme0n1
|
||
|
||
# ============================================================================
|
||
# SATA DRIVE PARTITIONING (Data drives — Phase 3 handles subvolumes)
|
||
# ============================================================================
|
||
|
||
# Note: Device naming in installer:
|
||
# Physical: /dev/nvme0n1 (NVMe), /dev/sda-/dev/sdd (SATA)
|
||
# Installer may refer to them differently; use physical names
|
||
#
|
||
# All SATA drives created as single btrfs partitions here.
|
||
# Phase 3 Ansible will:
|
||
# - Create subvolumes on each drive
|
||
# - Mount them at /srv/rag-library, /srv/prompt-library, etc.
|
||
# - Configure fstab with UUIDs (from HARDWARE.md)
|
||
# - Set compression and mount options
|
||
|
||
# SATA Drive 1 (sda): Backup partition — was labeled BACKUPDRV
|
||
# Will be mounted at /srv/backup in Phase 3
|
||
part /srv/backup-raw --fstype=btrfs --size=1 --grow --ondrive=sda
|
||
|
||
# SATA Drive 2 (sdb): RAG Library partition — was labeled RAGLIB
|
||
# Will be mounted at /srv/rag-library in Phase 3
|
||
part /srv/rag-raw --fstype=btrfs --size=1 --grow --ondrive=sdb
|
||
|
||
# SATA Drive 3 (sdc): AI Logs partition — was labeled AILOGS
|
||
# Will be mounted at /srv/ai-logs in Phase 3
|
||
part /srv/ai-raw --fstype=btrfs --size=1 --grow --ondrive=sdc
|
||
|
||
# SATA Drive 4 (sdd): Prompt Library partition — was labeled PROMPTLIB
|
||
# Will be mounted at /srv/prompt-library in Phase 3
|
||
part /srv/prompt-raw --fstype=btrfs --size=1 --grow --ondrive=sdd
|
||
|
||
# ============================================================================
|
||
# PACKAGE SELECTION
|
||
# ============================================================================
|
||
|
||
%packages
|
||
|
||
# ============================================================================
|
||
# CORE OS PACKAGES
|
||
# ============================================================================
|
||
|
||
# @core: Essential OS packages (required)
|
||
@core
|
||
|
||
# Kernel and headers (required for GPU driver compilation in Phase 4)
|
||
kernel
|
||
kernel-devel
|
||
kernel-headers
|
||
|
||
# UEFI bootloader and shim (required for secure boot compatibility)
|
||
grub2-efi-x64
|
||
shim-x64
|
||
efibootmgr
|
||
|
||
# ============================================================================
|
||
# BUILD ESSENTIALS (for Phase 4 NVIDIA driver installation)
|
||
# ============================================================================
|
||
|
||
# GCC compiler (required by NVIDIA driver kernel module compilation)
|
||
gcc
|
||
|
||
# Make build tool (required by NVIDIA driver Makefile)
|
||
make
|
||
|
||
# Patch utility (sometimes needed by driver post-install scripts)
|
||
patch
|
||
|
||
# Perl (sometimes used in driver installation scripts)
|
||
perl
|
||
|
||
# ============================================================================
|
||
# SYSTEM UTILITIES (minimal essential set)
|
||
# ============================================================================
|
||
|
||
# Networking and file transfer
|
||
curl
|
||
wget
|
||
|
||
# Text editors (vim for configuration editing)
|
||
vim
|
||
|
||
# Version control (git for CI/CD in future phases)
|
||
git
|
||
|
||
# Terminal multiplexer (tmux for Ansible session management)
|
||
tmux
|
||
|
||
# System monitoring (htop for real-time system observation)
|
||
htop
|
||
|
||
# ============================================================================
|
||
# SYSTEM ADMINISTRATION
|
||
# ============================================================================
|
||
|
||
# OpenSSH client and server (SSH access for Ansible Phase 2+)
|
||
openssh-clients
|
||
openssh-server
|
||
|
||
# Sudo (will be configured for Ansible non-root operations, Phase 2)
|
||
sudo
|
||
|
||
# ============================================================================
|
||
# STORAGE & MONITORING UTILITIES
|
||
# ============================================================================
|
||
|
||
# btrfs-progs: Tools for btrfs filesystem management (Phase 3, Phase 11)
|
||
btrfs-progs
|
||
|
||
# smartmontools: SMART disk health monitoring (Phase 11 thermal testing)
|
||
smartmontools
|
||
|
||
# util-linux: Standard Linux system utilities (mount, fdisk, etc.)
|
||
util-linux
|
||
|
||
# ============================================================================
|
||
# EXPLICITLY EXCLUDED PACKAGES (reduce footprint)
|
||
# ============================================================================
|
||
|
||
# Localization packages (not needed; en_US already specified)
|
||
-kde-l10n-*
|
||
-kde-l10n-common
|
||
|
||
# Network Manager GUI (not needed; CLI only)
|
||
-network-manager-applet
|
||
-nm-connection-editor
|
||
|
||
%end
|
||
|
||
# ============================================================================
|
||
# SERVICES CONFIGURATION
|
||
# ============================================================================
|
||
|
||
# Enabled services:
|
||
# - sshd: SSH daemon (required for Ansible Phase 2+)
|
||
# - NetworkManager: Network management daemon (handles DHCP, interfaces)
|
||
#
|
||
# Disabled services:
|
||
# - avahi-daemon: mDNS/Bonjour (not needed on server)
|
||
services --enabled=sshd,NetworkManager --disabled=avahi-daemon
|
||
|
||
# ============================================================================
|
||
# POST-INSTALLATION SCRIPT
|
||
# ============================================================================
|
||
#
|
||
# This script runs after package installation, before reboot.
|
||
# Handles kickstart-specific setup that Anaconda can't do automatically.
|
||
#
|
||
# Logs: Written to /root/anaconda-post.log (check if install fails)
|
||
# ============================================================================
|
||
|
||
%post --log=/root/anaconda-post.log
|
||
#!/bin/bash
|
||
|
||
# ============================================================================
|
||
# LOGGING INITIALIZATION (EU Sovereignty Policy)
|
||
# ============================================================================
|
||
|
||
# Create deployment log directory (used by all Ansible phases)
|
||
# Phase 0 (CE EU AI-Cloud Sovereignty Policy) requires structured logging
|
||
mkdir -p /srv/deployment-log
|
||
chmod 0755 /srv/deployment-log
|
||
|
||
# Log kickstart completion timestamp and system info
|
||
{
|
||
echo "=== Kickstart Installation Completed ==="
|
||
echo "Timestamp: $(date -Iseconds)"
|
||
echo "Hostname: $(hostname)"
|
||
echo "Kernel: $(uname -r)"
|
||
echo "AlmaLinux version: $(cat /etc/almalinux-release)"
|
||
echo ""
|
||
echo "Installed packages:"
|
||
rpm -qa | wc -l
|
||
echo ""
|
||
echo "Disk layout:"
|
||
lsblk
|
||
echo ""
|
||
echo "Network configuration:"
|
||
ip addr show enp4s0
|
||
echo ""
|
||
echo "Repositories:"
|
||
dnf repolist
|
||
} >> /srv/deployment-log/kickstart.log 2>&1
|
||
|
||
# ============================================================================
|
||
# GPU DRIVER PREPARATION (Phase 4 NVIDIA driver installation)
|
||
# ============================================================================
|
||
|
||
# Blacklist nouveau (open-source NVIDIA driver) before GPU driver install
|
||
# This prevents conflicts during Phase 4 NVIDIA proprietary driver installation
|
||
cat >> /etc/modprobe.d/blacklist-nouveau.conf << 'EOF'
|
||
# Blacklist nouveau to allow proprietary NVIDIA driver installation (Phase 4)
|
||
blacklist nouveau
|
||
options nouveau modeset=0
|
||
EOF
|
||
|
||
# Rebuild initramfs without nouveau module
|
||
# This ensures nouveau won't load on next boot
|
||
dracut --force 2>&1 >> /srv/deployment-log/kickstart.log
|
||
|
||
# ============================================================================
|
||
# SUDO BOOTSTRAP (temporary — narrow NOPASSWD exception)
|
||
# ============================================================================
|
||
#
|
||
# Phase 2 (Ansible) is what actually configures the real sudoers policy for
|
||
# the wheel group. But Phase 2 itself needs to run privileged commands to
|
||
# do that — and without this, there is no path to escalate privilege at
|
||
# all between first boot and Phase 2 completing. This drop-in is narrowly
|
||
# scoped to <user-name> only, clearly temporary, and is expected to be
|
||
# superseded (not just left in place) once Phase 2's real sudoers policy
|
||
# is applied. Verify Phase 2 actually replaces this rather than assuming
|
||
# it does.
|
||
|
||
cat > /etc/sudoers.d/00-bootstrap-<user-name> << 'EOF'
|
||
# Temporary bootstrap exception — superseded by Phase 2 Ansible sudoers policy.
|
||
# If you are reading this after Phase 2 has run, something did not get
|
||
# cleaned up correctly; check ansible/roles/phase-2-*/ for the real policy.
|
||
<user-name> ALL=(ALL) NOPASSWD: ALL
|
||
EOF
|
||
chmod 0440 /etc/sudoers.d/00-bootstrap-<user-name>
|
||
|
||
# ============================================================================
|
||
# SSH DAEMON SETUP (Foundation for Phase 2+ Ansible)
|
||
# ============================================================================
|
||
|
||
# Explicitly enable password authentication — don't rely on the distro
|
||
# default, which can vary and may already be hardened in the base image.
|
||
# Phase 9 flips this back to 'no' once key-based auth is confirmed working.
|
||
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
||
|
||
# Enable SSH daemon to start on boot
|
||
systemctl enable sshd
|
||
|
||
# Start SSH immediately (allows manual access if needed before Phase 2)
|
||
systemctl start sshd
|
||
|
||
# Restart to pick up the PasswordAuthentication change above
|
||
systemctl restart sshd
|
||
|
||
# Log SSH readiness
|
||
{
|
||
echo "SSH daemon enabled and started, password auth explicitly enabled"
|
||
systemctl status sshd | head -1
|
||
} >> /srv/deployment-log/kickstart.log 2>&1
|
||
|
||
# ============================================================================
|
||
# FIREWALL: Restrict SSH to known LAN ranges only
|
||
# ============================================================================
|
||
#
|
||
# firewalld is enabled (see FIREWALL block above) but the default zone has
|
||
# no blanket ssh service allowance — only these two specific source ranges
|
||
# can reach sshd at all. Anything outside 192.168.1.0/24 or 192.168.0.0/24
|
||
# is dropped by the zone default, before authentication is even attempted.
|
||
#
|
||
# firewall-cmd --permanent writes directly to the zone's XML config on
|
||
# disk; this works correctly here even though firewalld isn't actively
|
||
# running yet inside the install chroot — the rules take effect the
|
||
# moment firewalld starts on first real boot.
|
||
|
||
firewall-cmd --permanent --zone=public \
|
||
--add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
|
||
firewall-cmd --permanent --zone=public \
|
||
--add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" service name="ssh" accept'
|
||
|
||
{
|
||
echo "Firewall rich rules applied: SSH restricted to LAN ranges"
|
||
echo " Allowed: 192.168.1.0/24 (home LAN, incl. WireGuard VPN clients)"
|
||
echo " Allowed: 192.168.0.0/24 (workbench bench LAN)"
|
||
} >> /srv/deployment-log/kickstart.log 2>&1
|
||
|
||
# ============================================================================
|
||
# POST-SCRIPT COMPLETION LOG
|
||
# ============================================================================
|
||
|
||
{
|
||
echo ""
|
||
echo "=== Kickstart Post-Installation Complete ==="
|
||
echo "Timestamp: $(date -Iseconds)"
|
||
echo "Deployment directory: /srv/deployment-log/"
|
||
echo "Next phase: Ansible Phase 2 (System Configuration)"
|
||
} >> /srv/deployment-log/kickstart.log 2>&1
|
||
|
||
# Exit success
|
||
exit 0
|
||
|
||
%end
|
||
|
||
# ============================================================================
|
||
# KDUMP CONFIGURATION (disable for minimal footprint)
|
||
# ============================================================================
|
||
|
||
%addon com_redhat_kdump --disable
|
||
%end
|
||
|
||
# ============================================================================
|
||
# ANACONDA PASSWORD POLICY
|
||
# ============================================================================
|
||
#
|
||
# Note: Root password is locked (rootpw --locked above)
|
||
# These policies apply to the user account created during installation
|
||
# ============================================================================
|
||
|
||
%anaconda
|
||
# Root password policy (not applicable due to locked root)
|
||
# pwpolicy root --minlen=6 --minquality=50 --notstrict --nochanges --notempty
|
||
|
||
# User account policy — the account has a real (hashed) password per the
|
||
# USER ACCOUNT section above, so this is not left empty-ok as it was when
|
||
# no user account existed.
|
||
pwpolicy user --minlen=8 --minquality=50 --notstrict --nochanges --notempty
|
||
|
||
# LUKS encryption policy (if encrypted partitions created)
|
||
pwpolicy luks --minlen=6 --minquality=50 --notstrict --nochanges --notempty
|
||
%end
|
||
|
||
# ============================================================================
|
||
# INSTALLATION COMPLETION
|
||
# ============================================================================
|
||
|
||
# Reboot automatically after installation completes
|
||
# --eject: Attempt to eject installation media (USB) if possible
|
||
reboot --eject
|
||
|
||
# ============================================================================
|
||
# END OF KICKSTART FILE
|
||
# ============================================================================
|
||
#
|
||
# Verification checklist before use:
|
||
# [ ] Replaced <user-name> with the actual administrator username
|
||
# (appears in THREE places: user --name=, sudoers filename, sudoers
|
||
# file content — a find/replace across the whole file is safest)
|
||
# [ ] Replaced <sha512-hash> with the actual `openssl passwd -6` output
|
||
# [ ] NVMe device name is correct (nvme0n1)
|
||
# [ ] SATA device names are correct (sda, sdb, sdc, sdd)
|
||
# [ ] Network interface (enp4s0) matches hardware
|
||
# [ ] Hostname (bigboy) is correct
|
||
# [ ] Timezone (Europe/Rome) is correct
|
||
# [ ] Repositories are accessible (test with: curl <repo_url>)
|
||
# [ ] Real outbound internet access confirmed (not just bench LAN reachability)
|
||
# [ ] Post-install script has no syntax errors
|
||
#
|
||
# Expected outcome (Phase 1):
|
||
# - AlmaLinux 10.2 minimal installation
|
||
# - NVMe partitioned: EFI (1GB) + btrfs root (~499GB)
|
||
# - SATA drives partitioned: single btrfs partition each
|
||
# - <user-name> account created, wheel group, password login enabled
|
||
# - Temporary NOPASSWD sudo bootstrap in place for <user-name>
|
||
# - SSH daemon running, password auth explicitly enabled
|
||
# - Firewall enabled, SSH restricted to 192.168.1.0/24 and 192.168.0.0/24
|
||
# - /srv/deployment-log/ created and logged
|
||
# - Nouveau blacklisted, initramfs rebuilt
|
||
# - System reboots automatically
|
||
#
|
||
# Known temporary states this file creates, both closed out by Phase 9:
|
||
# 1. Password-based SSH login (Phase 9 → key-only)
|
||
# 2. Blanket NOPASSWD sudo bootstrap (Phase 9/Phase 2 → real sudoers policy)
|
||
#
|
||
# Next phase: Phase 2 (System Configuration & Secondary Drive Preparation)
|
||
# ============================================================================ |