Update kickstart with ssh and other details
This commit is contained in:
parent
a695324e38
commit
ac231b790a
1 changed files with 159 additions and 24 deletions
|
|
@ -8,12 +8,18 @@
|
|||
# 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: /home/john/projects/bigboy-alma/alma-phase1-install-workflow.md
|
||||
# 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.
|
||||
#
|
||||
# ============================================================================
|
||||
|
||||
# ============================================================================
|
||||
|
|
@ -45,8 +51,9 @@ timezone Europe/Rome --utc
|
|||
# ============================================================================
|
||||
|
||||
# Network: DHCP on primary interface (enp4s0)
|
||||
# Will typically receive 192.168.0.240 on Fritzy bench LAN
|
||||
# Phase 2 (Ansible) may configure static IP or DHCP reservation
|
||||
# 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
|
||||
|
||||
# ============================================================================
|
||||
|
|
@ -54,16 +61,67 @@ network --bootproto=dhcp --device=link --activate --hostname=bigboy --ipv6=off
|
|||
# ============================================================================
|
||||
|
||||
# Root password: LOCK (no password login allowed)
|
||||
# SSH key-based auth will be set up in Phase 2 (Ansible)
|
||||
# This prevents accidental password-based access
|
||||
# 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: Disabled during installation (Phase 9 hardens with firewalld)
|
||||
firewall --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
|
||||
|
|
@ -84,6 +142,10 @@ repo --name="almalinux10-crb" --mirrorlist="https://mirrors.almalinux.org/mirror
|
|||
# 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
|
||||
# ============================================================================
|
||||
|
|
@ -106,6 +168,11 @@ bootloader --location=partition --boot-drive=nvme0n1
|
|||
#
|
||||
# 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)
|
||||
|
|
@ -143,21 +210,21 @@ part / --fstype=btrfs --size=1 --grow --ondrive=nvme0n1
|
|||
# - Configure fstab with UUIDs (from HARDWARE.md)
|
||||
# - Set compression and mount options
|
||||
|
||||
# SATA Drive 1 (sda): RAG Library partition
|
||||
# Will be mounted at /srv/rag-library in Phase 3
|
||||
part /srv/rag-raw --fstype=btrfs --size=1 --grow --ondrive=sda
|
||||
|
||||
# SATA Drive 2 (sdb): Prompt Library partition
|
||||
# Will be mounted at /srv/prompt-library in Phase 3
|
||||
part /srv/prompt-raw --fstype=btrfs --size=1 --grow --ondrive=sdb
|
||||
|
||||
# SATA Drive 3 (sdc): Backup partition
|
||||
# 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=sdc
|
||||
part /srv/backup-raw --fstype=btrfs --size=1 --grow --ondrive=sda
|
||||
|
||||
# SATA Drive 4 (sdd): AI Logs partition
|
||||
# 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=sdd
|
||||
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
|
||||
|
|
@ -327,22 +394,76 @@ EOF
|
|||
# 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"
|
||||
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
|
||||
# ============================================================================
|
||||
|
|
@ -372,15 +493,17 @@ exit 0
|
|||
# ============================================================================
|
||||
#
|
||||
# Note: Root password is locked (rootpw --locked above)
|
||||
# These policies apply only to user account creation during installation
|
||||
# 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 (lenient; Ansible Phase 2 will harden)
|
||||
pwpolicy user --minlen=6 --minquality=50 --notstrict --nochanges --emptyok
|
||||
# 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
|
||||
|
|
@ -399,22 +522,34 @@ reboot --eject
|
|||
# ============================================================================
|
||||
#
|
||||
# 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
|
||||
# - SSH daemon running and ready for Ansible
|
||||
# - <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)
|
||||
# ============================================================================
|
||||
Loading…
Add table
Add a link
Reference in a new issue