Tightening Stig hardening

This commit is contained in:
Audiobuzz
2026-06-20 00:05:19 +00:00
parent b9258e7490
commit b67a23e718
8 changed files with 847 additions and 24 deletions
+61 -1
View File
@@ -493,7 +493,10 @@ build {
destination = "/tmp/"
}
provisioner "shell" {
environment_vars = ["ENABLE_STIG=${var.enable_stig}"]
environment_vars = [
"ENABLE_STIG=${var.enable_stig}",
"ADMIN_USER=${var.admin_user}",
]
inline = [
"set -e",
"if [ \"$ENABLE_STIG\" != \"true\" ]; then echo 'enable_stig=false -> skipping STIG hardening.'; mkdir -p /root; echo '<html><body>STIG hardening disabled for this build (enable_stig=false).</body></html>' > /root/stig-report.html; : > /root/stig-arf.xml; exit 0; fi",
@@ -514,6 +517,63 @@ build {
"echo \"==> Remediating against tailored STIG profile using $DS (this changes a lot)\"",
# --remediate returns nonzero when rules remain failed (expected) — tolerate.
"oscap xccdf eval --remediate --profile xccdf_org.ssgproject.content_profile_stig_diskless --tailoring-file /etc/stig/diskless-tailoring.xml --results-arf /root/stig-arf.xml --report /root/stig-report.html \"$DS\" || true",
# --- Supplemental remediations (report triage 2026-06-19, scan app-9f7d8d1).
# Applied BETWEEN --remediate and the clean eval so the report of record
# reflects them. See docs/stig-deviations.md #12.
# (a) postfix: remove the unused local MTA. The appliance sends no mail and
# ships audit off-box via rsyslog (2f), so an MTA is dead surface. This
# makes postfix_prevent_unrestricted_relay N/A; package_postfix_installed
# is waived in the tailoring to match.
"echo '==> supplemental: removing unused MTA (postfix)'",
"dnf remove -y postfix >/dev/null 2>&1 || true",
# (b) USBGuard: usbguard is already installed + enabled, but its policy was
# generated on the build VM (no real USB input). Add the LinuxAudit audit
# backend (configure_usbguard_auditbackend) AND a hardware-independent
# HID/hub allowlist so a physical console keyboard/mouse keep working
# under the default block target (a plain keyboard = HID only, a keyboard
# with built-in hub = HID+hub, so all three allow forms are needed).
# BENCH-VERIFY physical console input on real hardware.
"echo '==> supplemental: usbguard LinuxAudit backend + HID/hub allowlist'",
"if rpm -q usbguard >/dev/null 2>&1; then",
" [ -f /etc/usbguard/usbguard-daemon.conf ] || touch /etc/usbguard/usbguard-daemon.conf",
" sed -i '/^[ \\t]*AuditBackend=/Id' /etc/usbguard/usbguard-daemon.conf",
" printf 'AuditBackend=LinuxAudit\\n' >> /etc/usbguard/usbguard-daemon.conf",
" touch /etc/usbguard/rules.conf",
" for rule in 'allow with-interface match-all { 03:*:* }' 'allow with-interface match-all { 09:00:* }' 'allow with-interface match-all { 03:*:* 09:00:* }'; do",
" grep -qF \"$rule\" /etc/usbguard/rules.conf || printf '%s\\n' \"$rule\" >> /etc/usbguard/rules.conf",
" done",
" restorecon /etc/usbguard/usbguard-daemon.conf /etc/usbguard/rules.conf 2>/dev/null || true",
"else",
" echo 'WARNING: usbguard not installed; skipping (configure_usbguard_auditbackend stays a finding).'",
"fi",
# (c) selinux_context_elevation_for_sudo: STIG wants sudo to ELEVATE the
# SELinux context. SSG ships no auto-fix. Decision (2026-06-20):
# REMEDIATE WITH CONFINEMENT. Two parts:
# 1. Rewrite the admin sudoers rule to add the role/type transition
# (KEEP NOPASSWD — the admin is key-only; #8). This is what the
# OVAL check looks for, so it makes the rule pass.
# 2. Map the admin to the confined **staff_u** SELinux user so the
# staff_r->sysadm_r sudo transition is actually authorized at
# runtime (unconfined_u cannot reach sysadm_r). staff_u (NOT
# sysadm_u) so SSH login isn't gated by the ssh_sysadm_login bool.
# ⚠ BENCH-VERIFY: admin SSH login succeeds AND `sudo` works AND every
# privileged op the admin needs runs under the sysadm_t transition. If
# this locks the admin out, enable_stig=false is the escape hatch and
# this rule reverts to a justified deviation. ⚠ REPRODUCIBILITY: confirm
# the verity hash is stable across two builds — semanage rebuilds the
# SELinux policy store and may write nondeterministic content; if it
# drifts, normalize in 2d.
"if [ -n \"$ADMIN_USER\" ] && id \"$ADMIN_USER\" >/dev/null 2>&1; then",
" echo \"==> supplemental: sudo SELinux elevation — confining $ADMIN_USER to staff_u + sudoers role/type\"",
" command -v semanage >/dev/null 2>&1 || dnf install -y policycoreutils-python-utils",
" printf '%s ALL=(ALL) TYPE=sysadm_t ROLE=sysadm_r NOPASSWD:ALL\\n' \"$ADMIN_USER\" > \"/etc/sudoers.d/$ADMIN_USER\"",
" chmod 0440 \"/etc/sudoers.d/$ADMIN_USER\"",
" visudo -cf \"/etc/sudoers.d/$ADMIN_USER\"",
" restorecon \"/etc/sudoers.d/$ADMIN_USER\"",
" if semanage login -l 2>/dev/null | grep -qE \"^$ADMIN_USER[[:space:]]\"; then semanage login -m -s staff_u \"$ADMIN_USER\"; else semanage login -a -s staff_u \"$ADMIN_USER\"; fi",
" restorecon -R \"/home/$ADMIN_USER\" 2>/dev/null || true",
" echo \"==> $ADMIN_USER mapped to staff_u; sudo elevates to sysadm_r/sysadm_t\"",
"fi",
# Clean post-remediation eval = the report/ARF of record (no --remediate).
"oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_stig_diskless --tailoring-file /etc/stig/diskless-tailoring.xml --results-arf /root/stig-arf.xml --report /root/stig-report.html \"$DS\" || true",
# GUARD: a scan with 0 evaluated rules (everything notapplicable/notselected)