Add platform docs; reposition as host security platform
Add docs/ (SPECIFICATION, ROADMAP, OPERATIONS, COMMAND_REFERENCE, THREAT_MODEL) describing the current v0.7 agent and the phased path from local HIDS to a host security platform. Reframe README, package metadata, and CLI/module descriptions from "intrusion-detection daemon" to "Linux host security platform", and surface the v0.7 signed-package verify (pkgdb_pkgverify*) and anti-rootkit (rootcheck_*) knobs in the sample config. Also wrap the pacman.conf read in pkgdb.siglevel_alert in a context manager to avoid a leaked file handle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
1de5e86fed
commit
6ff2087329
11 changed files with 930 additions and 26 deletions
206
docs/SPECIFICATION.md
Normal file
206
docs/SPECIFICATION.md
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
# Enodia Sentinel Specification
|
||||
|
||||
This document defines Enodia Sentinel as a host security platform, not only a
|
||||
signature IDS. The current implementation is a local Linux sensor with evidence
|
||||
capture, integrity monitoring, anti-rootkit checks, a dashboard, and alert
|
||||
delivery. The intended product is a defensive control plane for a host or small
|
||||
fleet: detect compromise, prove what changed, preserve useful evidence, guide
|
||||
response, and make sensor tampering visible.
|
||||
|
||||
## Product Definition
|
||||
|
||||
Enodia Sentinel is a zero-runtime-dependency Linux host security agent. It runs
|
||||
as a local daemon, observes high-signal host behavior, records forensic context
|
||||
when something suspicious happens, and exposes the result through local files,
|
||||
JSON, a read-only dashboard, push notifications, and command-line tools.
|
||||
|
||||
The long-term product should combine five functions:
|
||||
|
||||
| Function | Purpose |
|
||||
|---|---|
|
||||
| Detection | Find active compromise behavior: reverse shells, fileless execution, new listeners, suspicious egress, persistence edits, and privilege-escalation artifacts. |
|
||||
| Integrity | Prove whether important files, packages, baselines, and Sentinel's own footprint changed. |
|
||||
| Evidence | Capture enough context for incident response without forcing the operator to reproduce a live state after the attacker is gone. |
|
||||
| Response | Provide safe, explicit operator workflows for triage, containment, and recovery. |
|
||||
| Assurance | Make the agent itself measurable: heartbeat, dead-man's switch, tamper-evidence, and future remote attestation. |
|
||||
|
||||
## Design Principles
|
||||
|
||||
1. **High-signal first.** Prefer detections that are cheap to observe and costly
|
||||
for attackers to avoid, even if that means a smaller rule set.
|
||||
2. **Evidence over noise.** Every alert should carry enough context to answer
|
||||
"what happened, where, and what should I inspect next?"
|
||||
3. **Zero dependency core.** The base daemon must run with the Python standard
|
||||
library only. Optional layers such as bcc/eBPF may degrade cleanly.
|
||||
4. **One local trust boundary is not enough.** On-box checks are useful but
|
||||
root can tamper with them. Important anchors should move to signed package
|
||||
metadata, immutable filesystem controls, external watchers, or future
|
||||
remote attestation.
|
||||
5. **Operator control.** Sentinel should recommend response actions before it
|
||||
takes them. Destructive containment must be opt-in and auditable.
|
||||
6. **Bash prototype remains the oracle.** The original shell implementation and
|
||||
red-team harness preserve behavioral compatibility for core signatures.
|
||||
|
||||
## Current Scope: v0.7
|
||||
|
||||
### Poll Detectors
|
||||
|
||||
The daemon builds one `SystemState` per sweep and runs pure detector functions
|
||||
against cached process and socket data:
|
||||
|
||||
| Detector | Signal |
|
||||
|---|---|
|
||||
| `reverse_shell` | Interpreter with a network socket on fd 0/1/2. |
|
||||
| `ld_preload` | Non-empty `/etc/ld.so.preload` or writable-path `LD_PRELOAD`. |
|
||||
| `deleted_exe` | Process executing from a deleted file or `memfd:` image. |
|
||||
| `new_listener` | Listening socket absent from the startup baseline. |
|
||||
| `new_suid` | New SUID/SGID binary, critical in writable locations. |
|
||||
| `persistence` | Changes to cron, systemd units, SSH keys, shell rc files, and similar persistence locations. |
|
||||
| `egress` | Interpreter with an established connection to a public IP. |
|
||||
|
||||
### Event Detection
|
||||
|
||||
An optional bcc eBPF `execve` monitor feeds a declarative rule engine. This
|
||||
closes the polling gap for short-lived commands and supports custom TOML rules
|
||||
without code changes. Failure is fail-safe: if the probe cannot load, polling
|
||||
continues.
|
||||
|
||||
### Integrity and Tamper-Evidence
|
||||
|
||||
Sentinel includes several integrity layers:
|
||||
|
||||
| Layer | Current behavior |
|
||||
|---|---|
|
||||
| FIM baseline | SHA-256 baseline for critical files and Sentinel's own footprint. |
|
||||
| Package verification | Optional `pacman -Qkk` verification for package-owned files. |
|
||||
| Package DB anchor | Detects out-of-band edits to `/var/lib/pacman/local`. |
|
||||
| Signed-package anchor | Compares on-disk files to `.MTREE` hashes from cached signed packages. |
|
||||
| Heartbeat | Writes daemon liveness for local dashboard and external watchdog use. |
|
||||
| Rootcheck | Cross-view checks for hidden processes, hidden modules, hidden ports, and promiscuous interfaces. |
|
||||
|
||||
### Evidence Capture
|
||||
|
||||
When a fresh alert survives cooldown, Sentinel writes:
|
||||
|
||||
- A human-readable snapshot.
|
||||
- A JSON snapshot suitable for automation and SIEM import.
|
||||
- Relevant process tree, sockets, environment hints, file descriptors, and
|
||||
response guidance.
|
||||
- Event log entries and dashboard-visible status.
|
||||
|
||||
### Operator Interfaces
|
||||
|
||||
| Interface | Role |
|
||||
|---|---|
|
||||
| CLI | Run daemon, one-shot checks, baseline management, FIM checks, package DB checks, rootcheck, 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. |
|
||||
| Red-team harness | Safe drills for testing signatures and demos. |
|
||||
|
||||
## Target Scope: Host Security Platform
|
||||
|
||||
The next product shape should make Enodia useful before, during, and after an
|
||||
incident.
|
||||
|
||||
### Prevent
|
||||
|
||||
- Configuration posture checks for risky SSH, sudo, systemd, cron, kernel,
|
||||
package manager, firewall, and service settings.
|
||||
- Baseline drift reports for newly exposed services, new SUID files, new
|
||||
autostarts, new users/groups, and sensitive permission changes.
|
||||
- A policy mode that can fail CI or package build checks for unsafe host images.
|
||||
|
||||
### Detect
|
||||
|
||||
- More event sources: `tcp_connect`, `bind`, `accept`, file-write events for
|
||||
persistence paths, module loading, privilege transitions, and LSM hooks.
|
||||
- Correlation across signals: "web service spawned shell" + "new listener" +
|
||||
"persistence write" should become one incident, not three unrelated alerts.
|
||||
- Optional YARA-style and Sigma-like local rules if they can stay dependency
|
||||
light and operator-readable.
|
||||
|
||||
### Investigate
|
||||
|
||||
- Incident timeline files derived from event log, snapshots, FIM diffs,
|
||||
package transactions, process lineage, and network observations.
|
||||
- Stable incident IDs that group related alerts over time.
|
||||
- `enodia-sentinel incident show <id>` and `incident export <id>` workflows.
|
||||
|
||||
### Respond
|
||||
|
||||
- Safe containment actions behind explicit flags:
|
||||
stop a process, disable a systemd unit, remove a persistence entry, block an
|
||||
IP with nftables, quarantine a file, or freeze evidence.
|
||||
- Dry-run by default, with JSON plans that can be reviewed before execution.
|
||||
- Response playbooks that are code-reviewed data files, not shell snippets
|
||||
pasted into documentation.
|
||||
|
||||
### Recover
|
||||
|
||||
- Package restore guidance: identify owning package, verify cache signature,
|
||||
reinstall package, and re-run integrity checks.
|
||||
- Baseline reconciliation workflow after confirmed legitimate changes.
|
||||
- Post-incident report generation from captured evidence.
|
||||
|
||||
### Assure
|
||||
|
||||
- External anchor storage for baselines and package DB fingerprints.
|
||||
- Signed snapshots or hash-chained event logs.
|
||||
- Remote watchdog improvements and eventually fleet controller support.
|
||||
- Optional TPM/IMA integration for machines that can support measured boot.
|
||||
|
||||
## Data Model
|
||||
|
||||
The current `Alert` object is the public detection unit:
|
||||
|
||||
| Field | Meaning |
|
||||
|---|---|
|
||||
| `sid` | Stable signature ID for tuning, documentation, and downstream rules. |
|
||||
| `severity` | `MEDIUM`, `HIGH`, or `CRITICAL`. |
|
||||
| `signature` | Stable machine-readable detection name. |
|
||||
| `classtype` | Snort/Suricata-style category. |
|
||||
| `key` | Cooldown and deduplication identity. |
|
||||
| `detail` | Human-readable explanation. |
|
||||
| `pids` | Process IDs for snapshot deep dives. |
|
||||
|
||||
Future incident grouping should add an `incident_id` around one or more alerts,
|
||||
without breaking the alert JSON schema.
|
||||
|
||||
## Configuration Model
|
||||
|
||||
Configuration is a TOML file loaded at startup. Unknown keys are ignored so
|
||||
newer config templates remain tolerable on older agents, but documentation
|
||||
should clearly mark version-specific fields. Existing defaults should prefer
|
||||
detection correctness over suppression. Convenience suppression knobs should
|
||||
remain explicit and reviewable.
|
||||
|
||||
## Security Model
|
||||
|
||||
Sentinel runs as root because it must inspect root-owned files, process state,
|
||||
file descriptors, and sockets. The systemd unit should continue to keep the
|
||||
root process narrow: read-mostly, constrained writable paths, no new privileges,
|
||||
restricted namespaces, and only the capabilities needed for the enabled layers.
|
||||
|
||||
Local root can eventually defeat any purely local sensor. Sentinel's answer is
|
||||
layering: signed package metadata, immutable files, off-box watchdogs, external
|
||||
anchors, and future kernel/attestation features.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Replacing a full enterprise SIEM.
|
||||
- Silent self-hiding or rootkit-like persistence.
|
||||
- Automatic destructive remediation without explicit operator approval.
|
||||
- Shipping a broad dependency tree in the default agent.
|
||||
- Claiming complete protection against a custom kernel implant.
|
||||
|
||||
## Acceptance Criteria For New Platform Features
|
||||
|
||||
A feature is ready when it has:
|
||||
|
||||
- A stable `sid`/signature or documented command contract.
|
||||
- Unit tests for pure logic and a safe integration path where practical.
|
||||
- JSON output or a durable artifact suitable for automation.
|
||||
- Configuration documented in the sample TOML and README or relevant docs.
|
||||
- Failure behavior that does not take down the daemon.
|
||||
- Clear operator guidance for false positives, limitations, and response.
|
||||
Loading…
Add table
Add a link
Reference in a new issue