refactor: move tree under homelab/, add alma10 hardening and kickstart docs

- 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]>
This commit is contained in:
andersenandClaude Fable 5 committed 2026-07-06 22:35:07 -04:00
1 parent c44e450fb4
commit 6d398b826a
1703 files changed
+713908 -90

No files matched your search

+302
View File
@@ -0,0 +1,302 @@
# 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.