Part 3 of a 3 part series on how to built a DISA STIG compliant RHEL 10 server.
☐ Since we added an httpd server and made changes to the firewall in the last part, we need
to reboot the server and re-run the OpenSCAP scan just to be sure the scan picks up all the
changes.
# shutdown -r now
☐ SSh back into the RHEL10 server and re-run the scan with the --remediate option,
and then again without the --remediate option. (sometimes the remediation does not
work as expected)
$ sudo -i
[sudo] password for john: ********
# oscap xccdf eval --report /var/www/html/openscap/rhel10.html --profile stig --remediate /usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml
# oscap
xccdf eval --report /var/www/html/openscap/rhel10.html --profile stig /usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml
☐ Refresh the RHEL 10 OpenSCAP evaluation report and note the change to the number
of failed rules.
☐ The first red highlighted fail we come to in the OpenSCAP evaluation report is:
"Only Authorized Local User Accounts Exist on Operating System". Click on the entry and
read through what the rule is looking for.
☐ We can use a "tailoring.xml" file with the oscap scan command to modify the test
criteria and override the authorized local users test. This will allow for our admin
user and the other default accounts that were created during the install. On our test
system we will add the following as authorized accounts: "yggdrasil-worker", "yggdrasil",
"john", "apache", "unbound", "fapolicyd", and "postfix". (replace john with the admin
username you added in part 1)
# cd /usr/share/xml/scap/ssg/content
# vim rhel10-tailoring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Override the authorized local users regex variable -->
<Tailoring xmlns="http://checklists.nist.gov/xccdf/1.2" id="xccdf_org.ssgproject.content_tailoring_custom">
<version time="2026-07-10T08:00:00">1</version>
<Profile id="xccdf_org.ssgproject.content_profile_stig_customized" extends="xccdf_org.ssgproject.content_profile_stig">
<title xml:lang="en">RHEL 10 STIG with Authorized Local Users Customization</title>
<description xml:lang="en">Customized local user account rules.</description>
<set-value idref="xccdf_org.ssgproject.content_value_var_accounts_authorized_local_users_regex">^(root|bin|daemon|adm|lp|sync|shutdown|halt|mail|operator|games|ftp|nobody|tss|systemd-coredump|dbus|polkitd|avahi|colord|rtkit|pipewire|clevis|sssd|geoclue|flatpak|setroubleshoot|libstoragemgmt|systemd-oom|gdm|cockpit-ws|cockpit-wsinstance|gnome-initial-setup|sshd|chrony|dnsmasq|tcpdump|admin|yggdrasil|yggdrasil-worker|john|apache|unbound|fapolicyd|postfix)$</set-value>
</Profile>
</Tailoring>
☐ Re-run the scan using the --tailoring-file option. (From now on we need to use the --tailoring-file option when we run the OpenSCAP scan.)
# oscap xccdf eval --tailoring-file /usr/share/xml/scap/ssg/content/rhel10-tailoring.xml --report /var/www/html/openscap/rhel10.html --profile xccdf_org.ssgproject.content_profile_stig_customized /usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml
☐ Refresh the RHEL 10 OpenSCAP evaluation report and notice that the medium (cat 2) rules
dropped from 5 to 4 and that the "Only Authorized Local User Accounts Exist on Operating System"
rule passed.
☐ Now the first red highlighted failed rule we come to in the OpenSCAP evaluation report is:
"Set the Boot Loader Admin Username to a Non-Default Value" followed by
"Set Boot Loader Password in grub2". Click on each entry and read through what the rules
are looking for.
Here is a simplified solution to fix both of these Cat 1 findings:
☐ Edit the /etc/grub.d/01_users file and replace the root user account name with something else (in this example csadm means cybersecurity admin):# vi /etc/grub.d/01_users
#!/bin/sh -e
cat << EOF
if [ -f \${prefix}/user.cfg ]; then
source \${prefix}/user.cfg
if [ -n "\${GRUB2_PASSWORD}" ]; then
set superusers="csadm"
export superusers
password_pbkdf2 csadm \${GRUB2_PASSWORD}
fi
fi
EOF
<ESC>:wq
☐ Set the UEFI Boot Loader Password
# grub2-setpassword
Enter password: **********
Confirm password: **********
☐ Generate a new GRUB configuration file
# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Adding boot menu entry for UEFI Firmware Settings ...
done
☐ Reboot
the system, log back in and re-run the scan as the root user and view
the new report and check to make sure the high (Cat 1) violations were
taken care of.
# shutdown -r now
...
$ sudo -i
# oscap xccdf eval --tailoring-file /usr/share/xml/scap/ssg/content/rhel10-tailoring.xml --report /var/www/html/openscap/rhel10.html --profile xccdf_org.ssgproject.content_profile_stig_customized /usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml
Good Job, we are down to just 4 medium (cat2) findings and no high (cat 1) findings.
☐ The next red highlighted failed rule we come to is: "Configure Multiple DNS Servers
in /etc/resolve.conf". Click on the entry and read through what the rule is looking for.
☐ In a production environment these should be internal DNS server entries, for our test system
we can just add google's DNS server (8.8.8.8) or Cloud flare's (1.1.1.1) using the Network Manager
Command Line Interface (nmcli).
# nmcli connection show --active
NAME UUID TYPE DEVICE
enp1s0 cd739700-07ed-3ca8-b971-637c1a013e21 ethernet enp1s0
lo 3c155504-c9bf-4e6d-903f-7a10e45239cb loopback lo
# nmcli connection show enp1s0|grep -i ip4.dns
IP4.DNS[1]: 192.168.122.1
# nmcli connection modify enp1s0 +ipv4.dns "8.8.8.8"
# nmcli connection up enp1s0
Connection successfully activated (D-Bus active path:
/org/freedesktop/NetworkManager/ActiveConnection/3)
# nmcli connection show enp1s0|grep -i ip4.dns
IP4.DNS[1]: 8.8.8.8
IP4.DNS[2]: 192.168.122.1
☐ Re-run the oscap scan and examine the results.
# oscap xccdf eval --tailoring-file /usr/share/xml/scap/ssg/content/rhel10-tailoring.xml --report /var/www/html/openscap/rhel10.html --profile xccdf_org.ssgproject.content_profile_stig_customized /usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml
☐ We should now be down to 3 medium (cat 2) failed rules. the next highlighted failed
rule is: "Elevate The SELinux Context When An Administrator Calls The Sudo Command". Click on the entry and read through what the rule is looking for.
The fix:
# cd /etc/sudoers.d
# visudo -f selinux.conf
%wheel ALL=(ALL) TYPE=sysadm_t ROLE=sysadm_r ALL
<ESC>
:wq
# chmod 755 selinux.conf(note
this can break your ability to sudo if it is wrong, and you will need
to login as root from the console and delete the file and start over,
ask me how I know)
☐ Re-run the oscap scan and examine the results.
# oscap xccdf eval --tailoring-file /usr/share/xml/scap/ssg/content/rhel10-tailoring.xml --report /var/www/html/openscap/rhel10.html --profile xccdf_org.ssgproject.content_profile_stig_customized /usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml ☐ We should now be down to 2 medium (cat 2) failed rules. the next highlighted failed
rule is: "Enable the SSSD Service" followed by "Enable Certmap in SSSD".
We need to modify the /etc/sssd/sssd.conf so that it exactly matches the following:
# vim /etc/sssd/sssd.conf
[sssd]
services = nss, pam
domains = local_files
certificate_verification = ocsp_dgst=sha512
[domain/local_files]
# RHEL 10 replacement for legacy 'files' provider
id_provider = proxy
proxy_lib_name = files
# Use proxy module pointing to standard system pam loops instead of legacy
auth_provider = proxy
proxy_pam_target = sssd-shadowutils
access_provider = permit
cache_credentials = true
[certmap/local_files/rule_name]
matchrule = <SAN>.*EDIPI@mil
maprule = (userCertificate;binary={cert!bin})
domains = local_files
[pam]
offline_credentials_expiration=1
pam_cert_auth=True
<ESC>:wq
# systemctl enable sssd --now
# systemctl status sssd
● sssd.service - System Security Services Daemon
Loaded: loaded (/usr/lib/systemd/system/sssd.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-09-02 16:03:01 UTC; 5s ago
Invocation: 6d8c9ab5dfb54ec8bb415b40c66585d9
...
☐ Re-run the oscap scan and examine the results.
#
oscap xccdf eval --tailoring-file
/usr/share/xml/scap/ssg/content/rhel10-tailoring.xml --report
/var/www/html/openscap/rhel10.html --profile
xccdf_org.ssgproject.content_profile_stig_customized
/usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml
☐ OK, the report now says we passed all tests, but just to be sure, we need to reboot and re-run the scan one last time (hopefully)/
# shutdown -r now
☐ SSh back into the RHEL10 server and re-run the scan
# sudo -i
# oscap xccdf eval --tailoring-file
/usr/share/xml/scap/ssg/content/rhel10-tailoring.xml --report
/var/www/html/openscap/rhel10.html --profile
xccdf_org.ssgproject.content_profile_stig_customized
/usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml
CONGRATULATIONS!
You have built a DISA STIG'd Red Hat Enterprise Linux 10 server.
It is a good idea to read through all of the rules marked "notchecked" on the report so
you are familiar with potential issues that could come up in an audit/inspection. For instance the STIG calls for disk partitions to be encrypted, but the OpenSCAP tool does not check for it. In this example build we didn't bother doing it, but in typical production environments the underlying hypervisor would be configured to encrypt it's physical hard drives, making encrypting virtual disks redundant.