Files
diskless-workstation/files/stig/diskless-tailoring.xml
T

178 lines
13 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!--
STIG tailoring for the diskless fleet image.
Extends the SSG RHEL9 STIG profile and UNSELECTS rules that are structurally
inapplicable to this architecture (immutable erofs+dm-verity root on a tmpfs
overlay, UKI/no-GRUB, autologin kiosk, key-only admin, no per-host state) or
that would be dangerous to auto-remediate (FIPS off per decision; firewall off;
AIDE = nondeterministic db; smartcard = login lockout). Every unselect here has
a matching entry in docs/stig-deviations.md with its compensating control.
Hand-written (not autotailor) on purpose: oscap reads this directly as a
tailoring file and silently ignores idrefs that don't exist in the installed
datastream, so a renamed rule can't break the build — it just won't be waived
(and will then surface in the generated deviations report for review).
Used by oscap xccdf eval against ssg-rhel9-ds.xml, selecting the tailored
profile id below and passing this file as the tailoring file.
-->
<xccdf:Tailoring xmlns:xccdf="http://checklists.nist.gov/xccdf/1.2"
id="xccdf_org.ssgproject.content_tailoring_diskless">
<xccdf:benchmark href="/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml"/>
<xccdf:version time="2026-06-18T00:00:00">1</xccdf:version>
<xccdf:Profile id="xccdf_org.ssgproject.content_profile_stig_diskless"
extends="xccdf_org.ssgproject.content_profile_stig">
<xccdf:title>DISA STIG for RHEL 9 — diskless fleet tailoring</xccdf:title>
<xccdf:description>STIG with rules inapplicable to the diskless/UKI/kiosk architecture unselected; see docs/stig-deviations.md.</xccdf:description>
<!-- FIPS: disabled for now (decision). Revisit with signing/Secure Boot. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_enable_fips_mode" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_enable_fips_mode" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_package_dracut-fips_installed" selected="false"/>
<!-- AIDE / file integrity: dm-verity is the compensating control (whole RO
root cryptographically verified). AIDE would also add a nondeterministic
db, breaking the reproducible verity hash. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_package_aide_installed" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_aide_build_database" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_aide_periodic_cron_checking" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_aide_scan_notification" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_aide_verify_acls" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_aide_verify_ext_attributes" selected="false"/>
<!-- Bootloader: UKI, no GRUB. The audit/slub/page-poison/vsyscall/etc kernel
params are set in the signed UKI cmdline (extract-artifacts.sh) instead —
the compensating control. GRUB password rules are N/A. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_uefi_password" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_admin_username" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_audit_argument" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_audit_backlog_limit_argument" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_slub_debug_argument" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_page_poison_argument" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_vsyscall_argument" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_init_on_alloc_argument" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_pti_argument" selected="false"/>
<!-- Partitioning: single erofs root + tmpfs overlay; cannot create separate
/var,/home,/tmp,... partitions. Intent met via nodev/nosuid/noexec tmpfs
mount options (see provisioner). -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_partition_for_var" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_partition_for_var_log" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_partition_for_var_log_audit" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_partition_for_tmp" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_partition_for_home" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_partition_for_var_tmp" selected="false"/>
<!-- Firewall: disabled on the isolated boot LAN (egress controlled at the
serving/firewall layer). Auto-enabling firewalld/nftables risks the
NVMe/TCP (4420) + NM paths. Re-enable as future hardening. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_service_firewalld_enabled" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_package_firewalld_installed" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_set_firewalld_default_zone" selected="false"/>
<!-- Remote audit offload: done via rsyslog (provisioner 2f) to the lab
collector. The audisp-remote native-protocol rules stay waived. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_auditd_audispd_configure_remote_server" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_auditd_audispd_encrypt_sent_records" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_auditd_audispd_network_failure_action" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_rsyslog_remote_loghost" selected="false"/>
<!-- rsyslog TLS offload: these force gtls + x509 peer auth + a CA file for ALL
forwarding. The lab boot LAN is isolated and plaintext (HTTP boot, no
MACsec); applying them makes rsyslog require TLS and BREAKS the plaintext
2f forward to serving/audit-collector (no CA, plaintext :514). Waived for
the lab; TLS offload is tracked as production hardening (docs/TODO.md #2).
Re-select once the collector has a cert + the CA is bundled in the image. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_rsyslog_encrypt_offload_defaultnetstreamdriver" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_rsyslog_encrypt_offload_actionsendstreamdrivermode" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_rsyslog_encrypt_offload_actionsendstreamdriverauthmode" selected="false"/>
<!-- Smart card: diskless, key-based admin; no PKI/smartcard reader. Enabling
smartcard-required login would lock the host out. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_require_smart_card_login" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_sssd_enable_smartcard" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_install_smartcard_packages" selected="false"/>
<!-- Admin sudo: the baked admin is key-only (no password), so sudo can't
prompt for one — NOPASSWD is required for it to function. Documented. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_sudo_remove_nopasswd" selected="false"/>
<!-- ================================================================== -->
<!-- Report triage 2026-06-19 (scan app-9f7d8d1): dispositions for the -->
<!-- remaining REVIEW rows. Every entry here is justified in -->
<!-- docs/stig-deviations.md #12. -->
<!-- ================================================================== -->
<!-- Bucket A — covered by an existing register entry. -->
<!-- Partitions (#1): single erofs+tmpfs root, no separate partitions. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_encrypt_partitions" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_auditd_audispd_configure_sufficiently_large_partition" selected="false"/>
<!-- Bootloader (#2): UKI, no GRUB. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_grub2_password" selected="false"/>
<!-- FIPS off (#5): crypto.fips_enabled + FIPS-validated SSH MACs. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_sysctl_crypto_fips_enabled" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_harden_sshd_macs_openssh_conf_crypto_policy" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_harden_sshd_macs_opensshserver_conf_crypto_policy" selected="false"/>
<!-- Firewall off for the isolated lab boot LAN (#4). -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_configured_firewalld_default_deny" selected="false"/>
<!-- No SSSD/PKI/smartcard (#7): host is local key-only, no domain join. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_sssd_enable_certmap" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_sssd_has_trust_anchor" selected="false"/>
<!-- Bucket B — architecturally absent (notchecked); N/A, justified #12. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_account_temp_expire_date" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_accounts_user_home_paths_only" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_libreswan_approved_tunnels" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_security_patches_up_to_date" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_ssh_keys_passphrase_protected" selected="false"/>
<!-- Bucket C — decisions, justified #12. -->
<!-- Rocky IS vendor-supported; the rule only fails because the RHEL
datastream checks for an RHEL subscription/CPE. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_installed_OS_is_vendor_supported" selected="false"/>
<!-- Single DHCP-provided resolver by design (boot LAN); multi-DNS N/A. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_network_configure_name_resolution" selected="false"/>
<!-- KEEP user namespaces enabled — the Chromium kiosk sandbox needs them
(this is the check-only "_no_remediation" variant). -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_sysctl_user_max_user_namespaces_no_remediation" selected="false"/>
<!-- Authorized-local-users check doesn't know the key-only appliance
accounts (fleetadmin, kiosk); see #10. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_accounts_authorized_local_users" selected="false"/>
<!-- postfix removed (no MTA needed on the appliance; audit-failure
notification is via remote offload, not email) -> the rule that
requires postfix installed becomes N/A. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_package_postfix_installed" selected="false"/>
<!-- Consequence of removing postfix: auditd's STIG space_left_action=email
has no MTA, so it's repointed to SYSLOG (alert rides the remote audit
offload). This rule wants 'email', so waive it. admin_space_left_action
stays 'single' (unaffected). See #12. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_auditd_data_retention_space_left_action" selected="false"/>
<!-- USBGuard (decision: ENABLE with a hardware-independent allowlist).
usbguard is already installed + the service enabled, but its policy was
generated on the build VM, which has no real USB input — under the
default block target a physical console keyboard/mouse would be blocked.
SELECT the HID + hub allow rules (class-based, hardware-independent) so
the eval of record verifies them; the provisioner writes these + the
LinuxAudit backend before that eval. NOTE: bench-verify physical console
input on real hardware. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_usbguard_allow_hid" selected="true"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_usbguard_allow_hub" selected="true"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_usbguard_allow_hid_and_hub" selected="true"/>
<!-- Ctrl+Alt+Del reboot hotkey (decision 2026-06-20): KEEP the console
reboot hotkey working on these diskless kiosks. The STIG masks
ctrl-alt-del.target + sets CtrlAltDelBurstAction=none to stop an
unauthenticated console reboot, but the hosts are STATELESS (immutable
erofs+verity root, tmpfs overlay) so a console reboot has no data-loss
or persistence risk, and a field tech needs to recover a wedged kiosk
without SSH. Unselect both so remediation leaves the systemd default
(hotkey reboots). Justified in docs/stig-deviations.md #13. -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_reboot" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_burstaction" selected="false"/>
</xccdf:Profile>
</xccdf:Tailoring>