Add banner and debug shell

This commit is contained in:
Audiobuzz
2026-06-19 00:06:39 +00:00
parent 6608818902
commit 5e2bfef575
3 changed files with 83 additions and 1 deletions
+63 -1
View File
@@ -136,6 +136,12 @@ variable "enable_stig" {
default = true default = true
} }
variable "debug_shell" {
type = bool
description = "DEBUG/LAB ONLY. true: enable systemd's debug-shell.service — a passwordless root /bin/sh on tty2 (Ctrl+Alt+F2) that bypasses login/PAM entirely. (Placed on tty2, with the login getty there masked, because constrained consoles often expose only tty1-6; tty1 stays the kiosk.) Use to get into a hardened image when login is broken (locked root + key-only accounts). This is a deliberate security hole; NEVER ship it. Default false."
default = true
}
variable "sb_key" { variable "sb_key" {
type = string type = string
description = "Secure Boot signing key (PEM) for the UKI. Empty = unsigned lab build. Production: CI/HSM-held; never enters the build VM." description = "Secure Boot signing key (PEM) for the UKI. Empty = unsigned lab build. Production: CI/HSM-held; never enters the build VM."
@@ -412,7 +418,10 @@ build {
# the main config) overrides the ks's PermitRootLogin yes. Takes effect on # the main config) overrides the ks's PermitRootLogin yes. Takes effect on
# the next boot only (sshd isn't restarted), so the live build session is # the next boot only (sshd isn't restarted), so the live build session is
# unaffected. # unaffected.
"printf 'PermitRootLogin no\\nPasswordAuthentication no\\nKbdInteractiveAuthentication no\\n' > /etc/ssh/sshd_config.d/50-fleet-hardening.conf", # Banner: show the fleet (starship) login notice pre-auth. The banner file
# itself is written by the '2e. Fleet login banner' step below (after STIG,
# so it overrides the DoD banner). Set here too so it works with enable_stig=false.
"printf 'PermitRootLogin no\\nPasswordAuthentication no\\nKbdInteractiveAuthentication no\\nBanner /etc/issue.net\\n' > /etc/ssh/sshd_config.d/50-fleet-hardening.conf",
"chmod 0644 /etc/ssh/sshd_config.d/50-fleet-hardening.conf", "chmod 0644 /etc/ssh/sshd_config.d/50-fleet-hardening.conf",
"restorecon /etc/ssh/sshd_config.d/50-fleet-hardening.conf", "restorecon /etc/ssh/sshd_config.d/50-fleet-hardening.conf",
# Guarantee sshd is enabled (it's our ONLY way in once root is locked and # Guarantee sshd is enabled (it's our ONLY way in once root is locked and
@@ -426,6 +435,35 @@ build {
] ]
} }
# --- 2c-debug. Break-glass root shell (DEBUG/LAB ONLY) -------------------
# debug_shell=true enables systemd's debug-shell.service: a passwordless root
# /bin/sh on tty9 (Ctrl+Alt+F9) that does NOT go through login/PAM — so you can
# get into a hardened image even when root is locked, the accounts are key-only,
# and login/sshd are broken. This is a deliberate security hole for diagnosing
# boot/login regressions; never ship it. The symlink into sysinit.target.wants
# guarantees it starts early regardless of the unit's [Install] section.
provisioner "shell" {
environment_vars = ["DEBUG_SHELL=${var.debug_shell}"]
inline = [
"set -e",
"if [ \"$DEBUG_SHELL\" != \"true\" ]; then echo 'debug_shell=false -> no debug shell baked.'; exit 0; fi",
"echo '############################################################'",
"echo '## WARNING: debug_shell=true — PASSWORDLESS ROOT on tty2. ##'",
"echo '## DEBUG/LAB IMAGE ONLY. Do NOT deploy to production. ##'",
"echo '############################################################'",
"systemctl enable debug-shell.service 2>/dev/null || true",
"mkdir -p /etc/systemd/system/sysinit.target.wants",
"ln -sf /usr/lib/systemd/system/debug-shell.service /etc/systemd/system/sysinit.target.wants/debug-shell.service",
# Default debug-shell is tty9 (outside the getty range) — but constrained
# consoles (noVNC/SPICE) often only expose tty1-6. Move it to tty2, which
# IS reachable, and mask the login getty there so they don't fight over the
# VT. Result: Ctrl+Alt+F2 = passwordless root shell. (tty1 stays the kiosk.)
"mkdir -p /etc/systemd/system/debug-shell.service.d",
"printf '[Service]\\nTTYPath=/dev/tty2\\n' > /etc/systemd/system/debug-shell.service.d/tty.conf",
"systemctl mask getty@tty2.service autovt@tty2.service 2>/dev/null || true",
]
}
# --- 2c-STIG. DISA STIG hardening (OpenSCAP + SSG), diskless/UKI/kiosk tailored # --- 2c-STIG. DISA STIG hardening (OpenSCAP + SSG), diskless/UKI/kiosk tailored
# Runs after admin (so it hardens the full system incl. the admin/sshd config) # Runs after admin (so it hardens the full system incl. the admin/sshd config)
# and BEFORE hygiene 2d (so 2d can strip the scanner tooling + reports). The # and BEFORE hygiene 2d (so 2d can strip the scanner tooling + reports). The
@@ -524,6 +562,30 @@ build {
] ]
} }
# --- 2e. Fleet login banner (starship-themed) ----------------------------
# Replaces the DoD/USG warning banner STIG writes (banner_etc_issue*) with the
# fleet (ISV AURELIAN) notice. Runs AFTER the STIG step so it overrides what
# remediation wrote; the sshd 'Banner /etc/issue.net' directive is set in 2c.
# Keeps a (themed) monitored/authorized-only notice — that warning is the
# banner's actual security purpose; only the wording changes. This makes the
# STIG banner-content rules fail by design (documented: stig-deviations.md #11).
provisioner "file" {
source = "files/banner"
destination = "/tmp/"
}
provisioner "shell" {
inline = [
"set -eux",
# /etc/issue = console getty (pre-login); issue.net = SSH pre-auth banner;
# motd = post-login. Same fleet notice in all three.
"install -D -m0644 /tmp/banner/fleet-issue /etc/issue",
"install -D -m0644 /tmp/banner/fleet-issue /etc/issue.net",
"install -D -m0644 /tmp/banner/fleet-issue /etc/motd",
"restorecon /etc/issue /etc/issue.net /etc/motd",
"rm -rf /tmp/banner",
]
}
# --- 2d. Final image hygiene: strip caches/logs after the LAST dnf step -- # --- 2d. Final image hygiene: strip caches/logs after the LAST dnf step --
# MUST be the last provisioner. The `dnf clean all` in step 2 runs BEFORE the # MUST be the last provisioner. The `dnf clean all` in step 2 runs BEFORE the
# kiosk (2b) and admin (2c) provisioners, and 2b enables EPEL + installs # kiosk (2b) and admin (2c) provisioners, and 2b enables EPEL + installs
+2
View File
@@ -32,6 +32,8 @@ Posture decisions (2026-06-18, lab phase):
| 9 | **GUI / autologin / GDM** (gnome screensaver, GDM banner, automatic-login rules) | No GNOME/GDM is installed; the kiosk is an **intentional** autologin single-app (weston + Chromium) session on kiosk builds. | Kiosk user is unprivileged and passwordless; the session runs a single locked-down browser (no shell, no nav). Applies to kiosk builds only; non-kiosk builds don't install the GUI stack. | | 9 | **GUI / autologin / GDM** (gnome screensaver, GDM banner, automatic-login rules) | No GNOME/GDM is installed; the kiosk is an **intentional** autologin single-app (weston + Chromium) session on kiosk builds. | Kiosk user is unprivileged and passwordless; the session runs a single locked-down browser (no shell, no nav). Applies to kiosk builds only; non-kiosk builds don't install the GUI stack. |
| 10 | **Password aging / faillock on the key-only APPLIANCE ACCOUNTS** (`accounts_*_age_*`, `account_disable_post_pw_expiration`, `pam_faillock` account phase) — applied to the *system* but **exempted for the `fleetadmin` and `kiosk` users** | These two accounts are **passwordless / key-only**. The hardened PAM *account* phase (faillock + password aging/inactivity) treats a passwordless account as expired/lockable, which **locked the fleet out**: the kiosk autologin session never opened (getty kept tty1) and sshd denied the valid key with `Permission denied (publickey)` (pubkey auth succeeds, then `pam_acct_mgmt` fails). Fixed 2026-06-18. | The exemption is **scoped to these two appliance accounts only** (post-STIG `chage -M -1 -m 0 -I -1 -E -1` + `faillock --reset`; kiosk uses a dedicated `/etc/pam.d/kiosk`; sshd gets an `account sufficient pam_succeed_if.so user = fleetadmin` bypass as its first account rule). Every other account keeps the full STIG password policy + faillock. These accounts have **no password to age** and (key-only, `PasswordAuthentication no`) **no password-auth path for faillock to protect**. Folds into the per-host/rotatable access model (SSH CA / config-agent). | | 10 | **Password aging / faillock on the key-only APPLIANCE ACCOUNTS** (`accounts_*_age_*`, `account_disable_post_pw_expiration`, `pam_faillock` account phase) — applied to the *system* but **exempted for the `fleetadmin` and `kiosk` users** | These two accounts are **passwordless / key-only**. The hardened PAM *account* phase (faillock + password aging/inactivity) treats a passwordless account as expired/lockable, which **locked the fleet out**: the kiosk autologin session never opened (getty kept tty1) and sshd denied the valid key with `Permission denied (publickey)` (pubkey auth succeeds, then `pam_acct_mgmt` fails). Fixed 2026-06-18. | The exemption is **scoped to these two appliance accounts only** (post-STIG `chage -M -1 -m 0 -I -1 -E -1` + `faillock --reset`; kiosk uses a dedicated `/etc/pam.d/kiosk`; sshd gets an `account sufficient pam_succeed_if.so user = fleetadmin` bypass as its first account rule). Every other account keeps the full STIG password policy + faillock. These accounts have **no password to age** and (key-only, `PasswordAuthentication no`) **no password-auth path for faillock to protect**. Folds into the per-host/rotatable access model (SSH CA / config-agent). |
| 11 | **Login banner content** (`banner_etc_issue`, `banner_etc_issue_net`, `banner_etc_motd`) | STIG requires the verbatim DoD/USG "you are accessing a U.S. Government Information System" text. This is a fictional starship fleet, not a USG system, so `/etc/issue{,.net}` + `/etc/motd` carry the fleet (ISV AURELIAN) notice instead (provisioner step 2e, `files/banner/fleet-issue`). The content rules therefore fail by design. | The banner **keeps its security function**: it still states authorized-crew-only, that the terminal is monitored/logged, and that unauthorized access is prohibited — only the wording is themed. `sshd_enable_warning_banner` (Banner is shown) still passes. |
## Things that are NOT deviations (kept / enforced) ## Things that are NOT deviations (kept / enforced)
- **SELinux enforcing** (`selinux --enforcing`; labels preserved into the erofs). - **SELinux enforcing** (`selinux --enforcing`; labels preserved into the erofs).
+18
View File
@@ -0,0 +1,18 @@
+===================================================================+
| |
| I S V A U R E L I A N |
| |
| Lancer-class Deep Survey Cruiser |
| Fleet Registry FN-774 |
| |
+===================================================================+
| |
| AUTHORIZED CREW ONLY. This terminal is bonded to the ship's |
| core AI; every keystroke is logged to the bridge. Unauthorized |
| access is a breach of the Fleet Charter and will be met with |
| containment protocols. If you are not cleared for this vessel, |
| disconnect now and report to your duty station. |
| |
| Safe travels, and mind the airlocks. |
| |
+===================================================================+