Add banner and debug shell
This commit is contained in:
+63
-1
@@ -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
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|||||||
@@ -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. |
|
||||||
|
| |
|
||||||
|
+===================================================================+
|
||||||
Reference in New Issue
Block a user