Expand rootkit monitoring and Claude docs

This commit is contained in:
Luna 2026-06-12 04:57:11 -07:00
parent a7129e5666
commit 3e5f8fc3f7
16 changed files with 524 additions and 32 deletions

View file

@ -101,11 +101,11 @@ enodia_sentinel/
├── config.py dataclass config (TOML + env overrides)
├── netutil.py public-IP / CIDR logic (stdlib ipaddress)
├── alert.py Alert / Severity (with Snort-style sid + classtype)
├── web.py read-only dashboard: stdlib http server + JSON API + auth
├── web.py HTTPS read-only management console + JSON API + auth
├── static/ the self-contained dashboard SPA
├── fim.py file integrity monitoring (hash baseline + pacman verify)
├── pkgdb.py package-DB integrity + signed-package verification
├── rootcheck.py anti-rootkit cross-view (hidden procs/modules/ports)
├── rootcheck.py anti-rootkit cross-view, module names, kernel/module taint
├── selfprotect.py self-integrity footprint + dead-man's-switch heartbeat
├── triage.py false-positive classification
├── provenance.py package-ownership lookups (pacman/dpkg/rpm)
@ -251,10 +251,11 @@ sudo systemctl enable --now enodia-sentinel-web
- **Bearer-token auth** (constant-time check); the token is auto-generated and
saved on first run and printed in the startup line. Open
`https://<tailscale-ip>:8787/?token=…`.
- **Read-only management**: incidents, timelines, alert inventory, event tail,
and dry-run response plans. No commands are executed from the browser. JSON
- **Read-only management**: incidents, timelines, alert inventory, posture
findings, event tail, and dry-run response plans. No commands are executed
from the browser. JSON
API at `/api/status`, `/api/incidents`, `/api/respond/plan/<id>`,
`/api/alerts`, `/api/alerts/<id>`, `/api/events`.
`/api/posture`, `/api/alerts`, `/api/alerts/<id>`, `/api/events`.
## Phone push notifications
@ -366,13 +367,21 @@ compare the answers.** A discrepancy is the hiding artifact.
| `/sys/module` (initstate=live) vs `/proc/modules` | a loaded LKM hidden from the module list | 100023 |
| `/proc/net/tcp` vs `ss` | a listening port a hooked `ss` won't report | 100024 |
| `/sys/class/net/*/flags` | an interface in promiscuous mode (a sniffer) | 100025 |
| known LKM rootkit module names | Diamorphine/Reptile/Adore-style module artifacts | 100028 |
| `/sys/module/*/taint` | out-of-tree/proprietary/unsigned loaded modules needing review | 100029 |
| `/proc/sys/kernel/tainted` | global kernel taint: forced loads/unloads, unsigned modules, warnings | 100030 |
| `/proc/net/udp` vs `ss -u` | a UDP socket a hooked `ss` won't report | 100031 |
```bash
enodia-sentinel rootcheck # one-shot cross-view scan
```
The daemon runs it on a slow background cadence (`rootcheck_interval`) and routes
any finding into the normal alert/snapshot/push pipeline. **Honest limits:** this
any finding into the normal alert/snapshot/push pipeline. If you intentionally
run tainted vendor/DKMS modules, add exact names to `rootcheck_module_allow`.
Known rootkit module names are never suppressed by that allowlist.
**Honest limits:** this
runs in user space, so it reliably catches userland (`LD_PRELOAD`) rootkits and
the common `/proc`-hiding LKMs, but a kernel rootkit that hooks *every* path
consistently can still evade it. It raises the bar and catches the common cases;
@ -488,8 +497,9 @@ v0.7 — closes the tamper-evidence loop with the **independent anchor**:
signed-package verification (compares on-disk files to the `.MTREE` in the signed
cache package, surviving a rewritten checksum DB) plus a `SigLevel`-downgrade
check, and an **anti-rootkit cross-view** layer (hidden processes, modules,
ports, and promiscuous interfaces — each caught by asking the same question two
ways and diffing the answers).
TCP/UDP ports, promiscuous interfaces, known LKM rootkit names, and
kernel/module taint — each caught by asking independent views and diffing the
answers).
v0.6 — adds **tamper-evidence**: out-of-band package-DB integrity
(catches rewritten checksums), self-integrity of Sentinel's own footprint, and a