Skip to content

Update RHEL 9 STIG content to align with DISA STIG v2r7#14382

Merged
Mab879 merged 9 commits intoComplianceAsCode:masterfrom
vojtapolasek:rhel9_stig_update_02_26
Feb 12, 2026
Merged

Update RHEL 9 STIG content to align with DISA STIG v2r7#14382
Mab879 merged 9 commits intoComplianceAsCode:masterfrom
vojtapolasek:rhel9_stig_update_02_26

Conversation

@vojtapolasek
Copy link
Collaborator

Description:

  • Update RHEL 9 STIG reference files to DISA STIG v2r7 (add disa-stig-rhel9-v2r7-xccdf-manual.xml and disa-stig-rhel9-v2r7-xccdf-scap.xml).
  • Implement new STIG control RHEL-09-654097 (audit cron scripts run by root/privileged users) using rules audit_rules_etc_cron_d and audit_rules_var_spool_cron.
  • Switch RHEL-09-232240 from dir_perms_world_writable_root_owned to dir_perms_world_writable_system_owned and assign CCE-86469-4 to the rule.
  • Set GNOME idle timeout to 10 minutes for RHEL-09-271065 by adding inactivity_timeout_value=10_minutes variable selection.
  • Switch logind_session_timeout on RHEL 9 to use a systemd drop-in file (/etc/systemd/logind.conf.d/) instead of modifying /etc/systemd/logind.conf directly, matching the approach used for SLE 15/16.
  • Fix require_emergency_target_auth remediation (RHEL-09-611195) to reset ExecStart= before setting the new value in the drop-in file, which is required for correct systemd override behavior.
  • Update profile stability files for stig and stig_gui profiles to reflect all changes.

Rationale:

  • Aligns RHEL 9 STIG content with the latest DISA STIG v2r7 release, incorporating new controls and updated requirements.
  • The dir_perms_world_writable_system_owned rule is a better match for RHEL-09-232240 than the previous dir_perms_world_writable_root_owned rule, as the STIG requirement allows ownership by root, sys, bin, or application users.
  • Using a systemd drop-in file for logind_session_timeout avoids modifying the vendor-provided /etc/systemd/logind.conf, which is the recommended practice for systemd configuration overrides.
  • The ExecStart= reset line is required by systemd when overriding ExecStart in a drop-in file; without it, the new ExecStart is appended rather than replacing the original.

Review Hints:

  • Affected product: RHEL 9. Build with: ./build_product --datastream-only rhel9
  • Key files to review:
    • products/rhel9/controls/stig_rhel9.yml — new RHEL-09-654097 control, rule swap for RHEL-09-232240, variable addition for RHEL-09-271065
    • linux_os/guide/system/accounts/accounts-physical/logind_session_timeout/ — drop-in file switch (OVAL, Ansible, Bash, tests)
    • linux_os/guide/system/accounts/accounts-physical/require_emergency_target_auth/ — ExecStart reset fix (Ansible, Bash)
    • linux_os/guide/system/permissions/files/dir_perms_world_writable_system_owned/rule.yml — CCE assignment
  • Review approach: Each commit is self-contained and can be reviewed individually. Reviewing in commit order provides the clearest narrative.
  • Automatus testing (if applicable):
    ./tests/automatus.py rule --libvirt qemu:///system rhel9 --datastream build/ssg-rhel9-ds.xml logind_session_timeout
    ./tests/automatus.py rule --libvirt qemu:///system rhel9 --datastream build/ssg-rhel9-ds.xml require_emergency_target_auth
    ./tests/automatus.py rule --libvirt qemu:///system rhel9 --datastream build/ssg-rhel9-ds.xml dir_perms_world_writable_system_owned
    

See https://stigaview.com/products/rhel9/v2r7/ for STIG reference

@vojtapolasek vojtapolasek added this to the 0.1.80 milestone Feb 11, 2026
@vojtapolasek vojtapolasek added RHEL9 Red Hat Enterprise Linux 9 product related. Update Rule Issues or pull requests related to Rules updates. Update Profile Issues or pull requests related to Profiles updates. STIG STIG Benchmark related. labels Feb 11, 2026
@github-actions
Copy link

github-actions bot commented Feb 11, 2026

This datastream diff is auto generated by the check Compare DS/Generate Diff

Click here to see the full diff
bash remediation for rule 'xccdf_org.ssgproject.content_rule_require_emergency_target_auth' differs.
--- xccdf_org.ssgproject.content_rule_require_emergency_target_auth
+++ xccdf_org.ssgproject.content_rule_require_emergency_target_auth
@@ -10,7 +10,6 @@
 
 mkdir -p "${service_dropin_cfg_dir}"
 echo "[Service]" >> "${service_dropin_file}"
-echo "ExecStart=" >> "${service_dropin_file}"
 echo "ExecStart=-$sulogin" >> "${service_dropin_file}"
 
 else

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_require_emergency_target_auth' differs.
--- xccdf_org.ssgproject.content_rule_require_emergency_target_auth
+++ xccdf_org.ssgproject.content_rule_require_emergency_target_auth
@@ -22,7 +22,6 @@
     dest: /etc/systemd/system/emergency.service.d/10-oscap.conf
     block: |-
       [Service]
-      ExecStart=
       ExecStart=-/usr/lib/systemd/systemd-sulogin-shell emergency
   when: '"kernel-core" in ansible_facts.packages'
   tags:

New content has different text for rule 'xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions'.
--- xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions
+++ xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions
@@ -12,6 +12,18 @@
 
     any non-root local partitions.
 
+[warning]:
+This rule checks only local partitions, identified as those backed by
+a device node in /dev. Network file systems such as NFS, CIFS,
+GlusterFS and others are excluded because they do not expose local
+device nodes. The /boot and /efi partitions are
+excluded because they are special partitions usually handled by a
+systemd mount unit, and enforcing nodev on them during
+operating system installation causes issues. Partitions with the
+vfat file system type are excluded because vfat does not
+support Unix device special files, so nodev enforcement on
+them is not meaningful.
+
 [reference]:
 11
 

bash remediation for rule 'xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions' differs.
--- xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions
+++ xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions
@@ -31,6 +31,7 @@
     lustre
     davfs
     fuse.sshfs
+    vfat
 )
 
 for partition_record in "${partitions_records[@]}"; do
@@ -38,6 +39,11 @@
     mount_point="$(echo "${partition_record}" | cut -d " " -f1)"
     device="$(echo "${partition_record}" | cut -d " " -f2)"
     device_type="$(echo "${partition_record}" | cut -d " " -f3)"
+
+    # Skip /boot and /efi partitions
+    if [[ "$mount_point" =~ ^/(boot|efi) ]]; then
+        continue
+    fi
 
     # Skip polyinstantiated directories
     if printf '%s\0' "${polyinstantiated_dirs[@]}" | grep -qxzF "$mount_point"; then
@@ -80,8 +86,8 @@
     fi
 done
 
-# Remediate unmounted /etc/fstab entries
-sed -i -E '/nodev/! s;^\s*(/dev/\S+|UUID=\S+)\s+(/\w\S*)\s+(\S+)\s+(\S+)(.*)$;\1 \2 \3 \4,nodev \5;' /etc/fstab
+# Remediate unmounted /etc/fstab entries, excluding /boot, /efi, and vfat partitions
+sed -i -E '/nodev/! { /^\s*(\/dev\/\S+|UUID=\S+)\s+\/(boot|efi)/! { /^\s*(\/dev\/\S+|UUID=\S+)\s+\/\w\S*\s+vfat\s/! s;^\s*(/dev/\S+|UUID=\S+)\s+(/\w\S*)\s+(\S+)\s+(\S+)(.*)$;\1 \2 \3 \4,nodev \5; } }' /etc/fstab
 
 else
     >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions' differs.
--- xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions
+++ xccdf_org.ssgproject.content_rule_mount_option_nodev_nonroot_local_partitions
@@ -64,6 +64,7 @@
     - lustre
     - davfs
     - fuse.sshfs
+    - vfat
   when: ( not ( "kernel-core" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
     and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
     and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
@@ -98,6 +99,7 @@
     and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
     ["docker", "lxc", "openvz", "podman", "container"] ) )
   - item.mount is match('/\w')
+  - item.mount is not match('/(boot|efi)')
   - item.options is not search('nodev')
   - item.fstype not in excluded_fstypes
   with_items:
@@ -122,7 +124,7 @@
     are present with nodev option in /etc/fstab'
   ansible.builtin.replace:
     path: /etc/fstab
-    regexp: ^\s*(?!#)(/dev/\S+|UUID=\S+)\s+(/\w\S*)\s+(\S+)\s+(?!.*\bnodev\b)(\S+)(.*)$
+    regexp: ^\s*(?!#)(/dev/\S+|UUID=\S+)\s+(/(?!boot|efi)\w\S*)\s+(?!vfat\s)(\S+)\s+(?!.*\bnodev\b)(\S+)(.*)$
     replace: \1 \2 \3 \4,nodev \5
   when: ( not ( "kernel-core" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
     and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages

@Mab879 Mab879 self-assigned this Feb 11, 2026
@Mab879
Copy link
Member

Mab879 commented Feb 11, 2026

/retest-required

@vojtapolasek
Copy link
Collaborator Author

/retest

Copy link
Member

@Mab879 Mab879 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When add rhel9 to these conditionals should we also add rhel10?

{{{ ansible_instantiate_variables("var_logind_session_timeout") }}}

{{% if product in ["sle15", "sle16"] %}}
{{% if product in ["rhel9", "sle15", "sle16"] %}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add rhel10?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it. Technically it should work also on RHEL 8 (according to man page), but I am not adding it because we would be out of sync with STIG. Let's leave this for later.

@openshift-ci
Copy link

openshift-ci bot commented Feb 12, 2026

@vojtapolasek: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-openshift-node-compliance ff74d6e link true /test e2e-aws-openshift-node-compliance

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@Mab879 Mab879 merged commit 1898858 into ComplianceAsCode:master Feb 12, 2026
141 of 143 checks passed
@ggbecker ggbecker added the Highlight This PR/Issue should make it to the featured changelog. label Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Highlight This PR/Issue should make it to the featured changelog. RHEL9 Red Hat Enterprise Linux 9 product related. STIG STIG Benchmark related. Update Profile Issues or pull requests related to Profiles updates. Update Rule Issues or pull requests related to Rules updates.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants