Add host posture checks (roadmap v0.8: posture check)

Add `enodia-sentinel posture check` — a config-hygiene audit that finds
the conditions making a host easy to attack, complementing the live
detectors. Checks: SSH root/password/empty-password login (Include-aware,
first-wins sshd resolution), passwordless and group/world-writable
sudoers, world-writable or non-root PATH directories, loose permissions
on sensitive files (/etc/shadow, /etc/passwd, ...), and downgraded
package-signature policy (reusing pkgdb.siglevel_alert).

Findings reuse the Alert type, so they serialize through the existing
JSON/triage pipeline (`posture check --json`). Each check is a pure
evaluator over injected content/stat facts plus a thin system reader, so
the 18 new tests need no root or live /etc. Posture is command-driven and
never runs in the daemon loop, per the v0.8 exit criterion.

SIDs 100040-100047 (classtype host-posture). Sample config and docs
(COMMAND_REFERENCE, OPERATIONS, ROADMAP, SPECIFICATION) updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-06-10 05:15:06 -07:00
parent 6ff2087329
commit 9ebc355936
9 changed files with 520 additions and 6 deletions

View file

@ -155,6 +155,31 @@ Exit code:
- `0`: sampled files match and signature policy is not downgraded.
- `1`: a signed-package mismatch or insecure signature setting was found.
### `posture check`
```bash
enodia-sentinel posture check
enodia-sentinel posture check --json
```
Audits host configuration hygiene — the conditions that make a host *easy* to
attack, as opposed to an attack in progress:
- SSH: root login, password authentication, and empty-password logins.
- sudo: passwordless (`NOPASSWD`) rules, disabled authentication, and
group/world-writable sudoers files.
- World-writable or non-root-owned `PATH` directories (binary-hijack vectors).
- Loose permissions on sensitive files (`/etc/shadow`, `/etc/passwd`, ...).
- Downgraded package-signature policy (`SigLevel`).
Findings are advisory and reuse the standard alert JSON shape (`--json`). This
command does not run inside the daemon and never blocks startup.
Exit code:
- `0`: no posture findings.
- `1`: one or more findings.
## Evidence and Operator Commands
### `web`
@ -217,7 +242,6 @@ enodia-sentinel status --json
enodia-sentinel incident list
enodia-sentinel incident show <incident-id>
enodia-sentinel incident export <incident-id>
enodia-sentinel posture check
enodia-sentinel respond plan <incident-id>
enodia-sentinel respond apply <plan-id>
```

View file

@ -51,6 +51,7 @@ enodia-sentinel fim-check
enodia-sentinel pkgdb-check
enodia-sentinel pkgdb-verify --sample 100
enodia-sentinel rootcheck
enodia-sentinel posture check
enodia-sentinel triage
```
@ -62,6 +63,9 @@ Expected healthy output:
- `pkgdb-check`: package DB consistent with anchor.
- `pkgdb-verify`: sampled files match signed cache packages.
- `rootcheck`: no hidden processes, modules, ports, or sniffers.
- `posture check`: no SSH/sudo/PATH/permission/signature hygiene findings, or
only ones you have consciously accepted (e.g. password auth on a host that
needs it).
## Alert Workflow

View file

@ -26,10 +26,11 @@ work that is bigger than single alerts.
alert time, process ancestry, sockets, persistence writes, FIM diffs, package
transactions, and rootcheck findings.
- Add `enodia-sentinel incident list/show/export`.
- Add host posture checks:
SSH password login, root SSH login, permissive sudoers entries, unexpected
enabled services, world-writable PATH components, disabled package signatures,
and unsafe systemd unit settings.
- ✅ Add host posture checks (`enodia-sentinel posture check`):
SSH root/password/empty-password login, passwordless and writable sudoers,
world-writable PATH components, loose sensitive-file permissions, and disabled
package signatures. Still to come: unexpected enabled services and unsafe
systemd unit settings.
- Add a machine-readable `status --json` command for automation.
- Update the red-team harness so every current detection has a named drill and
expected `sid`.

View file

@ -92,7 +92,7 @@ When a fresh alert survives cooldown, Sentinel writes:
| Interface | Role |
|---|---|
| CLI | Run daemon, one-shot checks, baseline management, FIM checks, package DB checks, rootcheck, triage, watchdog. |
| CLI | Run daemon, one-shot checks, baseline management, FIM checks, package DB checks, rootcheck, posture audit, triage, watchdog. |
| Logs | Durable local evidence under `/var/log/enodia-sentinel`. |
| Dashboard | Read-only web view for status, alert browsing, and snapshot inspection. |
| Push | ntfy, Pushover, and generic webhook notifications. |