Red Hat has integrated several SCAP profiles into the OS libraries. Using these and the utilities that support them, we are able to apply the PCI-DSS v3.2.1 security standard to our automated system builds. More information on automating RHEL installations can be found in Provision a Kickstart Server with RHEL8 - Part 1, Part 2, and Part 3. More information on OpenSCAP can be found at: https://www.open-scap.org/.
Harden the Build using %addon
- Open your kickstart configuration file for RHEL8. (sample)
vi rhel8
- Add the %addon security profile before the %anaconda and %post sections.
%addon org_fedora_oscap content-type = scap-security-guide profile = xccdf_org.ssgproject.content_profile_pci-dss %end
- Add a simple web server to the configuration to simplify the audit in later steps.
- If
firewall --enable
is set, extend it by changing it to, at least:firewall --enable --http
- Under %packages, add httpd.
httpd
- Under %post, add a small configuration and enable the service.
echo -e "<html>welcome to rhel8</html>" > /var/www/html/index.html systemctl enable httpd.service
- If
- Install a test VM with the updated kickstart configuration file.
Measure the Compliance Status
- Once the installation is complete, login to the test VM.
- Since our rhel8 pattern produces a simple web server, run the compliance check but send the output to the web directory.
oscap xccdf eval --report /var/www/html/report-pci-dss.html --profile pci-dss /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
- Browse to the HTML report on your test VM. It will be available at http://{Test VM IP}/report-pci-dss.html. In my case it looks like this:
- With the sample RHEL8 VM pattern, I am seeing three failures and one warning.
- Let's unpack each, individually, and manually verify and remediate the results.
Failure One: Ensure System Log Files Have Correct Permissions
If you click on the web link in red Ensure System Log Files Have Correct Permissions, a pop-up window will apprear with a lot of details about the failure. The rule that failed is Rule ID: xccdf_org.ssgproject.content_rule_rsyslog_files_permissions.
We can see some good information about this check, including the CCE number. (In this case CCE-80862-6)
The truly valuable information is down in desription. We just need to make sure that log files referenced in rsyslog.conf
and /etc/rsyslog.d/*.conf
have been set to, at least, chmod 0600 LOGFILE
.
A quick check of the system shows that we are set correctly:
# ls -l /var/log/messages \
/var/log/secure \
/var/log/maillog \
/var/log/cron \
/var/log/spooler \
/var/log/boot.log
-rw-------. 1 root root 0 Jul 25 03:07 /var/log/boot.log
-rw-------. 1 root root 7975 Jul 27 05:01 /var/log/cron
-rw-------. 1 root root 0 Jul 26 03:22 /var/log/maillog
-rw-------. 1 root root 25742 Jul 27 05:35 /var/log/messages
-rw-------. 1 root root 198 Jul 27 04:47 /var/log/secure
-rw-------. 1 root root 0 Jul 26 03:22 /var/log/spooler
Failure Two: Ensure Log Files Are Owned By Appropriate User
If you click on the web link in red Ensure Log Files Are Owned By Appropriate User, a pop-up window will apprear with a lot of details about the failure. The rule that failed is Rule ID: xccdf_org.ssgproject.content_rule_rsyslog_files_ownership.
We can see the CCE number. (In this case CCE-80861-8)
And the description.
Again, a quick check of the system shows that we are set correctly:
# ls -l /var/log/messages \
/var/log/secure \
/var/log/maillog \
/var/log/cron \
/var/log/spooler \
/var/log/boot.log
-rw-------. 1 root root 0 Jul 25 03:07 /var/log/boot.log
-rw-------. 1 root root 7975 Jul 27 05:01 /var/log/cron
-rw-------. 1 root root 0 Jul 26 03:22 /var/log/maillog
-rw-------. 1 root root 25742 Jul 27 05:35 /var/log/messages
-rw-------. 1 root root 198 Jul 27 04:47 /var/log/secure
-rw-------. 1 root root 0 Jul 26 03:22 /var/log/spooler
Failure Three: Ensure Log Files Are Owned By Appropriate Group
If you click on the web link in red Ensure Log Files Are Owned By Appropriate Group, a pop-up window will apprear with a lot of details about the failure. The rule that failed is Rule ID: xccdf_org.ssgproject.content_rule_rsyslog_files_groupownership.
We can see the CCE number. (In this case CCE-80860-0)
And the description.
Again, a quick check of the system shows that we are set correctly:
# ls -l /var/log/messages \
/var/log/secure \
/var/log/maillog \
/var/log/cron \
/var/log/spooler \
/var/log/boot.log
-rw-------. 1 root root 0 Jul 25 03:07 /var/log/boot.log
-rw-------. 1 root root 7975 Jul 27 05:01 /var/log/cron
-rw-------. 1 root root 0 Jul 26 03:22 /var/log/maillog
-rw-------. 1 root root 25742 Jul 27 05:35 /var/log/messages
-rw-------. 1 root root 198 Jul 27 04:47 /var/log/secure
-rw-------. 1 root root 0 Jul 26 03:22 /var/log/spooler
Why does OSCAP Have Failures on rsyslog
If you navigate to the very bottom of any of the three failures you will find that they all failed for the same reason. oscap
code expects some input for subroutines. When none is fed into a routine, the routine can fail the entire sequence. What's failing? ssg-var_rfg_log_files_paths is null.
This is a known issue and should be fixed at a future date. The fix is currently included in the RHEL 8.3 Beta.
Errors resolved, but what about the Warning?
There was a single warning, or what appeared to be. The scoring system shows three colors and only the word "passed" is visable next to the first number. The color coding is as follows:
Color | Value |
---|---|
Green | Passed / Fixed |
Red | Failed / error |
Yellow | Other |
What was our rule which returned other?
It's a rule which could be automated a variety of ways but not universally. What if we've restricted installs or subscripted to channels that never update?
This rule was skipped, but it needs to be integrated into build processes. Either:
- Patch after installations
- Installed from patched repositories
Conclusion
There's a lot that can be done to harden an OS image, and this process just scratches the surface. In many environments, multiple security profiles must be applied, as well as layers of application-specific best practice and security changes. Encapsulating these customizations in reliable, repeatable code is our ultimate goal.
Examples in this post can be found on GitHub