Hardening RHEL 10 and compatible

RHEL 10 (and compatibles) hardening

As an Enterprise operating system, hardening Red Hat Enterprise Linux and compatibles for production use often involves compliance with certain standards rather than ad-hoc hack-and-slash methods.

This is a quick copypasta cheat-sheet for a modern, compliant, and future-proof setup.

First we update the system and to make sure weak dependencies won't be installed, then install OpenSCAP:

dnf groupinstall 'Minimal Install' --setopt=install_weak_deps=False
dnf update -y
dnf install openscap scap-security-guide -y

Once OpenSCAP is installed we can scan the system for configuration compliance; ideally this should be run regularly as a cron job:

oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_stig \
  --results scan-results.xml \
   --report stig-report.html \
  /usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml

Kernel

Enable validation for Secure Boot in the Shim layer:

mokutil --enable-validation

The following kernel options will be added in /etc/default/grub:

GRUB_CMDLINE_LINUX="slub_debug=FZP page_poison=1 pti=on slab_nomerge vsyscall=none randomize_kstack_offset=on lockdown=confidentiality"
  • slub_debug=FZP - Enable SLUB allocator debugging (F=Sanity-check free objects, Z=Zero objects upon allocation and free, P=Poison freed objects and padding)
  • page_poison=1 - fill freed memory pages with a poison pattern; detect use-after-free and uninitialised memory bugs.
  • pti=on - Enable Page Table isolation; mitigates Meltdown CPU vuln
  • vsyscall=none - disable legacy vsyscall interface; force vDSO use
  • randomize_kstack_offset=on - enable kernel stack offset randomisation at syscall entry. Entropy in stack locs make exploitation more difficult
  • lockdown=confidentiality - kernel lockdown mode; prevent root access to direct memory (/dev/mem, etc)

Rebuild grub2 config:

grub2-mkconfig -o /boot/grub2/grub.cfg

SELinux to enforcing mode:

setenforce 1
sed -i 's/SELINUX=.*/SELINUX=enforcing/g' /etc/selinux/config

Auditing and Logging

Enable the Linux Audit daemon which logs security events to /var/log/audit/audit.log

dnf install audit -y
systemctl enable --now auditd

auditd rules

  • log every execve (tagged with 'exec_monitor')
  • Watch for /etc/{passwd,shadow,group,sudoers,ssh/sshd_config} changes (writes and attribs)
  • Log attempts to change the hostname or domain

Logs can be searched using:

ausearch -k exec_monitor

or summarised with:

aureport

/etc/audit/rules.d/hardening.rules:

-a always,exit -F arch=b64 -S execve -k exec_monitor
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /etc/group -p wa -k group_changes
-w /etc/sudoers -p wa -k sudoers_changes
-w /etc/ssh/sshd_config -p wa -k ssh_changes
-a always,exit -F arch=b64 -S sethostname,setdomainname -k system_identity
-e 2

User and Password Policies

Password quality policy:

  • Minimum length of 16
  • 4 character classes out of lowercase, uppercase, numbers, special characters
  • no more than 2 identical characters consecutively (aaa is invalid, aab is valid)
  • no more than 2 sequential characters (abc)
  • Check against dictionary words (install dictionary!)
  • enforce rules for root

/etc/security/pwquality.conf:

minlen = 16
minclass = 4
maxrepeat = 2
maxsequence = 2
dictcheck = 1
enforce_for_root

SSH Configuration

  • Limit host key algorithms to ed25519 to prevent downgrades to RSA/DSA/ECDSA
  • Restrict key exchange to Curge25519 with SHA-256
  • Use ChaCha20-Poly1305 AEAD cipher only
  • Restrict MAC to Encrypt-then-MAC with SHA-512
  • No root login, public key auth only (no password auth)

/etc/ssh/sshd_config.d/20-hardened.conf

Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
HostKeyAlgorithms ssh-ed25519
KexAlgorithms curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com
MACs hmac-sha2-512-etm@openssh.com
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no

Disable weak algorithms entirely

Set our crypto policy to FUTURE. Although some environments require FIPS, it is dated and FUTURE will ensure a modern, secure system. This will enable us to use Quantum-resistant algorithms such as CRYSTALS-Kyber and CRYSTALS-Dilithium when available.

update-crypto-policies --set FUTURE
systemctl restart sshd
  • TLS 1.2/1.3 only
  • Only strong, modern ciphers
  • ECDH or FFDHE key exchange
  • Secure signature and hashing algorithms only
  • Affects SSH, VPNs, OpenSSL, GnuTLS, etc

Network and Firewall

systemctl enable --now firewalld
firewall-cmd --set-default-zone=drop
firewall-cmd --add-service=ssh --permanent
firewall-cmd --reload

Disable IPv6

sysctl -w net.ipv6.conf.all.disable_ipv6=1
echo "net.ipv6.conf.all.disable_ipv6=1" >> /etc/sysctl.conf

IDS

dnf install aide -y
aide --init

Make sure to run regular checks with a cron job or systemd

Integrity Measurement Architecture (IMA)

WIP. Enable kernel IMA with boot params

ima_policy=tcb ima_appraise=enforce evm=fix ima_hash=sha512

Configure policies in /etc/ima/ima-policy

Container Security

  • Always run rootless containers
  • Use SELinux/AppArmor

Automatic updates

dnf install dnf-automatic -y
systemctl enable --now dnf-automatic.timer

Written for Cryogenix by int16h