- restructure boot/kickstarts/scripts/docs into homelab/ - docs: alma9->10 breaking changes, CIS hardening, kickstart changes - add find_cron_entries.sh helper and codex running memory notes Co-Authored-By: Claude Fable 5 <[email protected]>
11 KiB
AlmaLinux 10 — CIS Level 1 Hardening Decisions
Created: 2026-03-27 Updated: 2026-03-28
Reference: CIS AlmaLinux OS 10 Benchmark (tracks RHEL 10)
Script: work/KickStart/cfg/AlmaLinux-10.1-x86_64/ks.d/S940A-cis-hardening
Summary of Decisions
| CIS Control | Description | Decision |
|---|---|---|
| 1.1.1 | Disable unused filesystem modules | Applied |
| 1.1.2 | /tmp as separate partition or tmpfs | Deferred — pending dev review |
| 1.6 | Disable core dumps | Applied |
| 3.3.1 | Disable IP forwarding | Applied (probes/servers are not routers) |
| 3.3.2 | Disable packet redirect sending | Applied |
| 3.3.3 | Refuse source-routed packets | Applied |
| 3.3.4 | Refuse ICMP redirects | Applied |
| 3.3.5 | Refuse secure ICMP redirects | Applied |
| 3.3.6 | Log martian packets | Applied |
| 3.3.7 | Ignore broadcast ICMP echo requests | Applied |
| 3.3.8 | Ignore bogus ICMP error responses | Applied |
| 3.3.9 | Enable TCP SYN cookies | Applied |
| 3.3.10 | Disable IPv6 router advertisements | Applied |
| 4.1.2 | auditd enabled at boot | Applied |
| 4.1.3 | Audit processes prior to auditd start | Applied (audit=1 audit_backlog_limit=8192 kernel args) |
| 4.1.4 | Date/time change events | Applied |
| 4.1.5 | User/group identity changes | Applied |
| 4.1.6 | Network environment changes | Applied |
| 4.1.7 | MAC policy changes (SELinux) | Applied |
| 4.1.8 | Login/logout events | Applied |
| 4.1.9 | Session initiation | Applied |
| 4.1.10 | Permission modification events | Applied |
| 4.1.11 | Unauthorized file access attempts | Applied |
| 4.1.12 | Privileged command usage | Applied (generated dynamically via find) |
| 4.1.13 | File system mounts | Applied |
| 4.1.14 | File deletion by users | Applied |
| 4.1.15 | sudoers scope changes | Applied |
| 4.1.16 | sudo log monitoring | Applied |
| 4.1.17 | Kernel module load/unload | Applied |
| 4.1.18 | Audit rules immutable (-e 2) |
Applied |
| 5.3.2 | sudo: require pty | Applied |
| 5.3.3 | sudo: log all usage | Applied |
| 5.4.1 | Password quality (pwquality) | Applied |
| 5.4.2 | Password aging | Excluded — no expiration policy in this environment |
| 5.4.3 | Account lockout (pam_faillock) | Applied (pre-configured; active after authselect enable-feature with-faillock post-IPA) |
| squashfs module blacklist | CIS recommends disabling | Excluded — containers (Docker/Podman) require squashfs |
| udf module blacklist | CIS recommends disabling | Excluded — not prohibited in this environment |
| AIDE cron | CIS recommends local AIDE cron | Excluded — managed centrally, not locally |
| authselect profile change | Required to activate faillock in PAM | Excluded from kickstart — IPA owns the authselect profile |
Applied Controls
1.1.1 — Disable Unused Filesystem Modules
File: /etc/modprobe.d/cis-fs-blacklist.conf
install cramfs /bin/true
install freevxfs /bin/true
install hfs /bin/true
install hfsplus /bin/true
install jffs2 /bin/true
blacklist cramfs
blacklist freevxfs
blacklist hfs
blacklist hfsplus
blacklist jffs2
Both install (prevents modprobe load) and blacklist (prevents udev autoload) directives are used for belt-and-suspenders.
Excluded from this list:
squashfs— Docker/Podman containers require it. Re-evaluate if container usage changes.udf— Not prohibited in this environment. Re-evaluate if needed.
1.6 — Core Dump Restrictions
Three layers applied:
/etc/security/limits.d/cis-coredump.conf (PAM limits):
* hard core 0
/etc/sysctl.d/20-cis-coredump.conf (kernel — disables setuid core dumps):
fs.suid_dumpable = 0
/etc/systemd/coredump.conf.d/cis.conf (systemd coredump handler):
[Coredump]
Storage=none
ProcessSizeMax=0
3.3 — Network Sysctl Hardening
File: /etc/sysctl.d/30-cis-network.conf
# 3.3.1 — disable IP forwarding
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
# 3.3.2 — disable packet redirect sending
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# 3.3.3 — refuse source-routed packets
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0
# 3.3.4 — refuse ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# 3.3.5 — refuse secure ICMP redirects
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# 3.3.6 — log martian packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# 3.3.7 — ignore broadcast ICMP echo requests
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 3.3.8 — ignore bogus ICMP error responses
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 3.3.9 — enable TCP SYN cookies
net.ipv4.tcp_syncookies = 1
# 3.3.10 — disable IPv6 router advertisements
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
# Kernel ASLR
kernel.randomize_va_space = 2
Note on net.ipv4.ip_forward: The default is already 0 on RHEL 10 for non-router systems. This is explicitly set for audit compliance. If Docker/Podman networking requires it, Docker daemon config ("ip-forward": true) re-enables it automatically — but explicitly setting 0 here means Docker/Podman will need to override it at startup. Verify if container networking is affected.
4.x — Auditd Configuration
Added 2026-03-28.
Kernel boot flag (4.1.3)
grubby --update-kernel=ALL --args="audit=1 audit_backlog_limit=8192"
Ensures processes that start before auditd is running are still audited. audit_backlog_limit=8192 prevents kernel audit buffer overflow during boot.
Rules file: /etc/audit/rules.d/cis.rules
Controls 4.1.4–4.1.17 are written as a static heredoc, with 4.1.12 (privileged commands) appended dynamically:
find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null \
| awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged"}' \
>> /etc/audit/rules.d/cis.rules
-e 2 (immutable flag, 4.1.18) is appended last so it takes effect after all rules including the dynamic privileged-command list.
Network environment path note (4.1.6)
CIS references /etc/sysconfig/network-scripts/ which does not exist in RHEL 10. Replaced with /etc/NetworkManager/ which is the canonical location for NM keyfiles.
auditd service
systemctl enable auditd
audit package is a dependency of audit-libs which is pulled in transitively. No explicit KS_Packages.cfg entry required.
5.3 — sudo Hardening
File: /etc/sudoers.d/cis-sudo (mode 0440)
# 5.3.2 — require pty (prevents background sudo abuse)
Defaults use_pty
# 5.3.3 — log all sudo usage
Defaults logfile=/var/log/sudo.log
# credential caching limit
Defaults timestamp_timeout=5
5.4.1 — Password Quality (pwquality)
File: /etc/security/pwquality.conf.d/cis.conf
# CIS 5.4.1 — password complexity requirements
minlen = 14
minclass = 4
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
maxrepeat = 3
maxsequence = 3
Applies to all interactive password changes. Does not affect pre-hashed passwords set in kickstart.
5.4.3 — Account Lockout (pam_faillock)
File: /etc/security/faillock.conf
# 5.4.3 — lock after 5 failures in a 15-minute window
deny = 5
fail_interval = 900
unlock_time = 900
even_deny_root
root_unlock_time = 60
Important: This configuration is pre-staged but not active until PAM is wired to use it. ipa-client-install owns the authselect profile. After IPA enrolment, enable faillock:
authselect enable-feature with-faillock
Do not run this in kickstart — IPA resets the authselect profile during enrolment.
Deferred Controls
1.1.2 — /tmp as Separate Partition or tmpfs
Status: Deferred pending dev review.
Reason: /var/tmp may need exec permissions for some application stack components. Current kickstart uses autopart --type=lvm which places /tmp on the root LVM volume. Mounting /tmp as tmpfs or a separate partition requires validating that:
- No application code writes large temporary files to
/tmpthat would exhaust a size-limited tmpfs /var/tmpexec requirements are understood — CIS also recommendsnoexecon/var/tmp, which may conflict with application use
Action: Revisit with dev team. If approved, add to kickstart:
%pre
# ... partition layout
%end
or post-install:
echo "tmpfs /tmp tmpfs defaults,nodev,nosuid,noexec,size=2G 0 0" >> /etc/fstab
Excluded Controls
5.4.2 — Password Aging
No password expiration policy for any accounts in this environment. PASS_MAX_DAYS, PASS_MIN_DAYS, PASS_WARN_AGE are left at system defaults. Service accounts and probe accounts do not rotate passwords on a schedule.
squashfs Module Blacklist
CIS recommends blacklisting squashfs. Excluded because Docker and Podman use squashfs for container image layers. If container usage is removed from these hosts, re-evaluate.
udf Module Blacklist
CIS recommends blacklisting udf (Universal Disk Format). Not prohibited in this environment and excluded from scope.
AIDE Cron
AIDE is installed (aide package in KS_Packages.cfg) but cron-based integrity scanning is managed centrally by a dedicated machine — not configured locally on each probe/server. Local AIDE cron is not added.
authselect Profile Change
ipa-client-install owns and resets the authselect profile. Any pre-kickstart authselect change would be overwritten during IPA enrolment. faillock.conf is pre-staged; authselect enable-feature with-faillock is a manual post-enrolment step.
Kernel ASLR Note
kernel.randomize_va_space = 2 (full ASLR) is set in 30-cis-network.conf. This is the RHEL 10 default but is explicitly set for audit compliance. No known application compatibility issues with this value.
Future Review Items
- SELinux verification:
audit2allowoutputs CIL format by default in RHEL 10 (changed from.te). Any local SELinux policy management scripts need to be updated. Verify in test VM. - Docker/container network compatibility with
ip_forward=0: If containers use bridged networking, Docker daemon re-enablesip_forwardat startup. Confirm no conflict with the sysctl set above.