mirror of
https://git.valherun.com/valherun/pxe_boot_alma.git
synced 2026-10-15 20:32:03 -04:00
- 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]>
303 lines
11 KiB
Markdown
303 lines
11 KiB
Markdown
# 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`
|
||
|
||
```ini
|
||
# 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)
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
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`
|
||
|
||
```ini
|
||
# 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`
|
||
|
||
```ini
|
||
# 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:
|
||
|
||
```bash
|
||
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:
|
||
|
||
1. No application code writes large temporary files to `/tmp` that would exhaust a size-limited tmpfs
|
||
2. `/var/tmp` exec requirements are understood — CIS also recommends `noexec` on `/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:
|
||
```bash
|
||
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:** `audit2allow` outputs 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-enables `ip_forward` at startup. Confirm no conflict with the sysctl set above.
|