The original words of Phanes, tirelessly carved into a slab of "No'".

DISA STIG Hardening on AlmaLinux 8

So, a while back I posted an article on setting FIPS mode for CentOS 9, but it was originally supposed to be an article on DISA STIG hardening, and, unfortunately at the time of that writing, the OSCAP profiles were not in a mature enough state where that article could be reasonably written without a great deal more effort than I’d want to put into an article, to be honest.

AlmaLinux 8 doesn’t have that problem, though, because their team is absolutely on top of shit and they’ve done a great job staying on mission despite all the obstacles their upstream sources have thrown their way.

So, we’re going to do full DISA STIG hardening, and even up it a notch with a little extra hardening you can tinker with to HARDEN THE BALLS of a vanilla installation of AlmaLinux 8.

At the time of writing this, my preferred hosting provider, Linode, has mutilated their images such that you cannot perform these steps on their images under the mistaken belief that they would have to recertify FIPS 140 compliance to host an image that allows FIPS mode, and by all appearances appear immune to the clarification that they do not need to recertify according to an embarrassingly handled ticket I filed and got a response from. Yikes.

That’s okay though, because over the last few years, Digital Ocean has improved alot, and picked up the ball that Linode dropped in this area, and has full support for this. They also seem to have categorically better firewall and VPC support, so, there may be some relationship shifts soon in terms of hosting for SILO GROUP assets. It really boils down to balancing security posture and cost on that note.


Anyway, before we start, get your vanilla install of AlmaLinux 8 up, and do a dnf -y update. You may need to import a key as the stock image has an outdated one, which breaks dnf unless you disable GPG checks (you really shouldn’t if you care enough to apply the DISA STIG anyway). You can do this with:

# rpm --import
# dnf -y update

That’ll take a bit.

After you’re done, at least on Digital Ocean’s stock AlmaLinux 8 image, you’ll want to update /etc/cloud/cloud.cfg to set the ssh_genkeytypes option:

ssh_genkeytypes:  ['rsa', 'ecdsa', 'ed25519']

The reason for this is explained better than I care to explain here. One of the updates set this value to null, and it’s a surprise tool that will help us later.

Add an Entry User

Next, you’re going to lock out the root user from opensshd in this process, so I’ll want to create a new user called phanes:

# useradd -G wheel -s /bin/bash phanes
# passwd phanes

If there’s already a group or you want to do something special:

# visudo

To keep it all nice and clean, go ahead and give that machine a reboot when you’re done just to make sure everything’s going to come up happy and be pointing at the right things when you set fips mode.

Enable FIPS Mode

It’s easy to turn on when the image hasn’t been mutilated. Set FIPS mode (as root):

# fips-mode-setup --enable

It takes a bit. This doesn’t just set the fips=1 bit in GRUB, it has to generate a new initramfs with dracut and all that jazz.

Go ahead and reboot again so we can validate, since the system has to start in FIPS mode.

Next you can validate with one of the following commands:

[ ] << ~ >>

[- fips-mode-setup --check
FIPS mode is enabled.

[ ] << ~ >>

[- cat /proc/sys/crypto/fips_enabled 

With that second command, you’re traversing the proc filesystem to check directly with the kernel about whether it thinks it is running in FIPS mode or not. The first command is preferred though as when you set certain crypto policies that are not FIPS compliant it’ll nag you there, and it’s good to know where your gaps are if you have any. The stock configuration we’ve followed should show as above. On mine, I’ve enabled a custom policy that isn’t relevant to this tutorial, but just to show you what a non-compliant crypto policy would look like when running fips-mode-setup --check:

[ ] << ~ >>

[- fips-mode-setup --check
FIPS mode is enabled.
The current crypto policy (DEFAULT:AD-SUPPORT) is not a FIPS policy.

So far, super simple stuff. You’re now running in FIPS mode, which isn’t inherently more secure in some contexts by the nature of what it is, but most certainly puts you on a path to be.

Let’s go ahead and apply the DISA STIG, which is absolutely a leveling up of posture (as long as you maintain it and pair it with other practices I won’t cover here).

Install the OSCAP Packages

# dnf install openscap-scanner openscap-utils scap-security-guide -y

Fetch your OSCAP Profile Resources

This step is a little unnecessary because the eval call will pull everything too when supplied the --fetch-remote-resources switch, but, doing this first lets you know if there’s an issue ahead of time so you can not wait an hour to find out you failed and fix it before running the real deal.

# oscap info \
  --fetch-remote-resources \

Apply the DISA STIG Profile for AlmaLinux 8

This is actually probably not the best way to apply it, as you should review the changes being applied first, but, this will give you a “baseline” to clean up as you go if you’re lazy (I am, because I’m not going to cover reviewing the STIG remediations here, only how to apply the remediations). Apply the remediations automatically as you scan with OSCAP:

# oscap xccdf eval \
  --remediate \
  --fetch-remote-resources \
  --profile xccdf_org.ssgproject.content_profile_stig \
  --report /tmp/$(date +%Y-%m-%d)-STIG-Compliance-Report-PRE.html \

Make sure and clench a little as you hit enter because it’s going to check a whole bunch of shit, it’s going to fail a shitload of those checks, and you’re going to see it do a shitload of changes to various parts of the disparate security components of your AlmaLinux 8 system. While an explanation of each of these changes is beyond the scope of this article, what I will do is post a followup that shows you how to generate a compliance report that gives you a nifty view of what’s not compliant with the DISA STIG that you can choose to run before applying the above command as you get more comfortable with hardening. That approach will allow you to see the “suggested remediation” and give you an opportunity to perhaps close the security hole in a different way or accept it as a risk if you don’t want to deal with the side effects of that change and have other mitigations in place.

In my case, I underprovisioned the host to only have 1GB of RAM, so it failed miserably the first time. So, I upgraded to 2GB and ran it again. Unfortunately, this is where the cost profile of Digital Ocean starts to suck, by moving from $6/mo -> $12/mo.

Before you reboot to see the glory of your new hardened system, you’ll want to modify the sshd config and inspect your firewall config to make sure you’ll be able to get back in again. Check that sshd is set to bind to port 22 and allows key and/or password authentication and make sure the firewall config allows 22/tcp.

So, having run it again, I see that the changes were applied, because I can no longer ssh 🙂

Unfortunately, I wish that were the end. In my case, selinux was now preventing sshd from launching, so, there’s a little more work to do. I temporarily set selinux to permissive mode by editing /etc/selinux/config on a rescue boot mount.

From there I was able to get in and run restorecon -vR /etc. After turning selinux back into enforcing mode and rebooting, all is well. In your case, you’ll want to run that before that last reboot.

You are now running a pretty hardened machine. Go ahead and run this report to see where your compliance with the DISA STIG stands, and check out where your remaining gaps are. And remember: This is just one piece in a well hardened environment:

# oscap xccdf eval \
  --fetch-remote-resources \
  --profile xccdf_org.ssgproject.content_profile_stig \
  --report /tmp/$(date +%Y-%m-%d)-STIG-Compliance-Report-POST.html \

After you run it, you’ll see two files with today’s date in /tmp that has your compliance scan results and suggested remediations for those issues from both before and after you applied remediations. Take special note that you can (and should once you figure out what’s going on here) run this version without the automated remediations so that you can close gaps one at a time using changes that you yourself made, so you know what you’re getting into a little better. I’d recommend that the first like 50 times you harden a system like this that you do that, so, this article is really just kind of a “get up and running” guide.

Additional Hardening Steps

You can take some additional steps to improve both the visibility and security posture of your system by:

  1. Enabling auditd.
  2. Installing and enabling fapolicyd
  3. If you have more than one host, using centralized identity management, which won’t be covered in this article.
  4. Likewise if you have more than one host, centralized collection of logs through rsyslogd or syslog-ng (my preference). This is also beyond the scope of this article, but I may post on it later.

Enabling auditd is easy:

# systemctl enable auditd

Installing fapolicyd is about as straightforward:

# dnf -y install fapolicyd

A little about fapolicyd: fapolicyd is an executable whitelisting service that allows you to specify which binaries may be executed in your environment. This is problematic for users new to it, so, you may want to set it to permissive mode for a little while in /etc/fapolicyd/fapolicyd.conf so you can grep system logs while building out the necessary profiles to get the benefit of this resource on your system.

Good luck!

Next Post

Previous Post

Leave a Reply

© 2024 Phanes' Canon

The Personal Blog of Chris Punches