cumakurt/saru
GitHub: cumakurt/saru
Saru 是一个基于 Rust 的本地 Linux 安全情报工具,通过规则引擎与快照分析实现主机威胁检测与合规评估。
Stars: 4 | Forks: 2
# Saru (猿)
[](https://github.com/cumakurt/saru/actions/workflows/ci.yml)
[](./LICENSE)
[](./Cargo.toml)
**Single-binary, local-first Linux security intelligence:** collect host context (`/proc`, `/etc`, packages, SSH, cron, containers, …), **log tails** (auth, syslog/messages, journal, audit), **running processes**, **cron**, **bash history samples**, and optional **WASM** plugins; run **75+** built-in heuristic rules plus optional **TOML** rules (including **[SigmaHQ](https://github.com/SigmaHQ/sigma) Linux rules** imported via CLI); optionally store **SQLite** snapshots for drift and trends; export **terminal**, **JSON**, **SARIF**, **STIX**, or **CSV** — plus an interactive **HTML** report.
| | |
|---|---|
| **Repository** | [github.com/cumakurt/saru](https://github.com/cumakurt/saru) |
| **Developer** | **Cuma KURT** — **LinkedIn:** [linkedin.com/in/cuma-kurt-34414917](https://www.linkedin.com/in/cuma-kurt-34414917/) |
| **User guide (mdBook)** | [`docs/book/`](./docs/book/) — run `mdbook build` in `docs/book` |
| **License** | [AGPL-3.0](./LICENSE) |
**Quality bar.** CI runs `cargo fmt`, `clippy -D warnings`, `cargo test`, and **`cargo deny`**; release builds target musl on **x86_64** and **aarch64** (binary size cap **15 MiB**). Catalog tests enforce minimum built-in rule counts (**≥20**, **≥40**, **≥75**).
## What Saru does
| Area | What you get |
|------|----------------|
| **Assessment** | Full host collection, rule engine, CVSS where applicable, **CIA-style risk score**, heuristic **attack-path** summaries embedded in scan output. |
| **Persistence** | Optional snapshots in SQLite (`state.db` by default): list, export, delete, prune, **diff** two scans, **timeline** risk trend. |
| **Threat intelligence** | **Attack** paths (graph heuristic), **simulate** what-if fixes, **explain** one rule, **MITRE** coverage and Navigator layer export, **compliance** (CIS-inspired profiles). |
| **Artifacts** | **HTML report** (fresh scan; filename gets `_.html`), **forensic** JSON, optional IOC JSON, optional **tar** bundle with manifest + optional **GPG** detach-sign. |
| **Live ops** | **Watch** paths (`inotify`), poll processes/listeners, auth log tail; optional TUI and **webhook/syslog/PagerDuty** alerts. **Container** listing with optional escape-risk heuristics. |
| **Automation** | **Daemon** loop: periodic scan + snapshot + retention. **CI**: `scan --exit-code --fail-on`. |
**Crates (for contributors):** `saru-core` (types, CVSS, config, scoring), `saru-collector`, `saru-state` (SQLite), `saru-intel` (rules, diff, attack graph, compliance, MITRE, …), `saru-cli`.
## Contents
1. [Install](#install)
2. [First commands](#first-commands)
3. [Command reference](#command-reference)
- [scan](#scan) · [fingerprint](#fingerprint) · [snapshot](#snapshot) · [diff](#diff) · [timeline](#timeline) · [daemon](#daemon)
- [attack](#attack) · [simulate](#simulate) · [explain](#explain) · [compliance](#compliance) · [mitre](#mitre)
- [report](#report) · [forensic](#forensic) · [rules](#rules)
- [watch](#watch) · [container](#container) · [completion & update](#completion--update)
4. [Global options & configuration](#global-options--configuration)
5. [Collected data highlights](#collected-data-highlights)
6. [Sigma rules (import)](#sigma-rules-import)
7. [Building & development](#building--development)
8. [Publishing on GitHub](#publishing-on-github)
Examples assume `saru` is on your **`PATH`**. From a dev build use `./target/release/saru`.
## Install
**Network installer** (clones the repo and builds with Cargo — requires [Rust](https://rustup.rs/)):
```
curl -fsSL https://raw.githubusercontent.com/cumakurt/saru/main/install.sh | sh
```
- **root:** default **`/usr/local/bin`**
- **non-root:** **`~/.local/bin`** — add `export PATH="$HOME/.local/bin:$PATH"` if needed
**From a clone:**
```
sh install.sh
PREFIX=/usr/local/bin sh install.sh
sh install.sh --tag v0.1.0
sh install.sh --release v0.1.0
```
## First commands
```
saru scan
saru fingerprint
saru scan --output json | head
```
## Command reference
### scan
Full collection + rules + risk score + attack-path summaries + optional compliance profile in JSON/embedded snapshot.
Embedded advanced rule bundle is included by default.
```
saru scan
saru scan --min-severity high
saru scan --quiet
saru scan --show-fixes
saru scan --cloud-probe
saru scan --no-cloud-probe
saru scan --tags ssh --tags network
saru scan --exclude SARU-SSH-001 --exclude 'SARU-NET*'
saru scan --plugin-dir /path/to/wasm/plugins
```
**Machine-readable output**
```
saru scan --output json
saru scan --output csv > findings.csv
saru scan --output sarif > results.sarif
saru scan --output stix > bundle.stix.json
```
**Snapshots & compliance in output**
```
saru scan --save-snapshot
saru scan --save-snapshot --retain 100
saru scan --compliance-benchmark cis-ubuntu-24
saru scan --no-compliance
```
**Remediation script (review before run)**
```
saru scan --fix-script /tmp/remediate.sh
saru scan --fix-script /tmp/run.sh --fix-script-run --yes-understand-risk
```
**CI exit code**
```
saru scan --exit-code --fail-on high
```
### fingerprint
Lightweight host summary (counts, polkit preview, attack-graph entry points, …).
```
saru fingerprint
saru fingerprint --output json
saru fingerprint --output csv
```
### snapshot
Stored scans live in SQLite (default `~/.saru/state.db` unless `--db` or config).
```
saru snapshot list
saru snapshot list --limit 50
saru snapshot list --since-days 14 --output json
saru snapshot list --output csv
saru snapshot export -f /tmp/backup.json
saru snapshot delete
saru snapshot prune 100
```
**With `scan`**
```
saru scan --save-snapshot --retain 50
```
See [Daemon](#daemon) for periodic snapshots.
### diff
Compare two stored snapshots or oldest vs newest in a time window.
```
saru diff --from --to
saru diff --between
saru diff --since-hours 24
saru diff --output json
saru diff --output csv
```
### timeline
ASCII risk trend (and optional compliance trend) from recent snapshots.
```
saru timeline
saru timeline --limit 20
saru timeline --since-days 30 --limit 20
saru timeline --since-hours 6 --limit 24
saru timeline --output json
saru timeline --output csv
```
### daemon
Periodic scan + snapshot loop (foreground; **Ctrl+C** to stop).
```
saru daemon --interval-secs 3600
saru daemon --interval-secs 3600 --retain 100
```
Example unit: [`contrib/saru-daemon.service`](./contrib/saru-daemon.service).
### attack
Heuristic attack-path summaries (listeners → privilege → `ROOT`), ranked by cost; optional MITRE and Graphviz.
```
saru attack
saru attack --mitre
saru attack --focus ssh,sudo,polkit,journal
saru attack --max-paths 12
saru attack --output json
saru attack --output csv > attack-paths.csv
saru attack --export graphviz | dot -Tpng -o attack.png
```
Supported: **terminal**, **json**, **csv** (not SARIF/STIX).
### simulate
What-if risk if fix categories are hypothetically removed.
```
saru simulate --fix ssh,sudo,polkit,filesystem
saru simulate --compare
```
### explain
Re-runs a scan and prints WHY/HOW/FIX for one rule id.
```
saru explain SARU-SSH-001
saru explain SARU-POLKIT-001
```
### compliance
CIS-inspired host checks (subset; profiles depend on OS).
```
saru compliance
saru compliance --benchmark host
saru compliance --benchmark cis-lite
saru compliance --benchmark cis-ubuntu-24
saru compliance --benchmark cis-debian-12
saru compliance --benchmark cis-rhel-9
saru compliance --dry-run-fixes
saru compliance --fix-script /tmp/cis-fix.sh
saru compliance --output csv
```
### mitre
Coverage and technique detail from the current scan; embedded Linux matrix; ATT&CK Navigator layer export.
```
saru mitre
saru mitre --coverage
saru mitre --matrix
saru mitre --tactic privilege --technique T1548
saru mitre --export-layer /tmp/navigator-layer.json
saru mitre --export-layer /tmp/layer.json --layer-name "Production host"
```
### report
Runs a **fresh scan** and writes a single **interactive HTML** report.
The written path is **timestamped**: `_YYYYMMDD_HHMMSS.html` (same directory as `-f`).
Use `---timestamp` to keep the exact file name.
Use `--open` to open the generated report in the default browser/viewer.
```
saru report -f /tmp/report.html --benchmark host
# e.g. writes /tmp/report_20260414_153045.html
saru report -f /tmp/audit.html --no-compliance
# e.g. writes /tmp/audit_20260414_153102.html
saru report -f /tmp/fixed-name.html --no-timestamp
# writes exactly /tmp/fixed-name.html
saru report -f /tmp/ops.html --open
# writes timestamped HTML and opens it automatically
saru report -f /tmp/report.html --output json
# prints machine-readable metadata (path, scan_id, risk_overall, ...)
```
### forensic
Volatile + collected host JSON, optional IOC bundle, optional signed tar archive.
```
saru forensic -f /tmp/forensic.json
saru forensic -f /tmp/full.json --with-findings
saru forensic -f /tmp/host.json -i /tmp/ioc.json
saru forensic --archive /tmp/bundle.tar -f /tmp/forensic.json
saru forensic --archive /tmp/bundle.tar -f /tmp/host.json -i /tmp/ioc.json --gpg-sign
```
### rules
Built-in catalog, optional TOML bundles, and **Sigma Linux import** (see [Sigma rules (import)](#sigma-rules-import)).
```
saru rule list
saru rule list --tags ssh
saru rule list --output json
saru rule list --output csv
# Merge extra TOML bundles from a directory (or use config `rules_path` — same merge behavior)
saru rule list --extra-rules ~/.saru/rules
saru rule test /path/to/custom-rules.toml
saru rule validate /path/to/custom-rules.toml
# Export built-in metadata as Sigma-style YAML *stubs* (for SIEM documentation — not detections)
saru rule export sigma -f /tmp/saru-sigma.yml
saru rule export sigma
```
**Import [SigmaHQ/sigma](https://github.com/SigmaHQ/sigma) `rules/linux/` into Saru TOML** (clone the Sigma repo first):
```
git clone --depth 1 https://github.com/SigmaHQ/sigma.git
saru rule import-sigma ./sigma -f ~/.saru/rules/sigma_linux.toml
saru rule validate ~/.saru/rules/sigma_linux.toml
```
Use with scans: put `*.toml` under a directory and pass **`--rules-path`** or set **`rules_path`** in config.
Custom rules use `[[rule]]` in TOML; match types include the built-ins below plus **`sigma_line_match`** and **`sigma_keyword_lines`** for imported Sigma rules.
### watch
Live filesystem (`inotify`), process/listener polling, auth log tail; optional **ratatui** TUI; alerts (**webhook**, **syslog**, **PagerDuty**).
Use **`--alert webhook:URL`**, not a bare `--webhook` flag.
### container
List Docker/Podman containers when available; optional escape-risk heuristics from inspect.
```
saru container
saru container --escape
saru container --escape --output json
```
### completion & update
```
saru completion bash > ~/.local/share/bash-completion/completions/saru
saru completion zsh > ~/.zfunc/_saru
saru completion fish > ~/.config/fish/completions/saru.fish
saru update
```
## Global options & configuration
| Option | Role |
|--------|------|
| `--output terminal\|json\|sarif\|csv\|stix` | Default output format (not every command supports every variant). |
| `--no-color` | Disable ANSI colors. |
| `--db ` | SQLite snapshot DB path (**overrides** config `db_path`). |
| `--config ` | TOML config (defaults merged with **`SARU_*`** env). |
| `--exclude ` | Skip rules (repeat; `*` suffix for prefix). |
| `--tags ` | Only run rules in these catalog categories (repeat). |
| `--cloud-probe` / `--no-cloud-probe` | Cloud metadata probe (overrides `cloud_probe` in config). |
| `--rules-path ` | Extra `*.toml` rules (**overrides** config `rules_path`). |
**Retention**
| Mechanism | Behavior |
|-----------|----------|
| `retain_snapshots` in config | After `scan --save-snapshot` or each `daemon` cycle, keep **N** newest rows. |
| `SARU_RETAIN_SNAPSHOTS` | Same as `retain_snapshots`. |
| `scan --save-snapshot --retain N` | **Overrides** config when set. |
| `daemon --retain N` | **Overrides** config when set. |
| `snapshot prune N` | One-shot prune. |
**Example `~/.saru/config.toml`**
```
db_path = "/home/you/.saru/state.db"
rules_path = "/home/you/.saru/rules"
min_severity = "medium"
fail_on = "critical"
cloud_probe = false
retain_snapshots = 100
```
**Custom rule match types** (see `crates/saru-intel/src/toml_rules.rs`): `listening_port`, `ssh_setting`, `proc_sys`, `file_exists`, `package_installed`, `user_in_group`, `user_shadow_auth_hint`, `polkit_hit`, `kernel_module_loaded`, `world_writable_etc_count` (+ **`min_count`**), **`sigma_line_match`** (Sigma AND-of-OR groups on a chosen haystack), **`sigma_keyword_lines`** (keyword lists with optional glob-like `*` / `?`), …
**Developers:** [`deny.toml`](./deny.toml) — `cargo deny check licenses bans sources`.
## Collected data highlights
High-signal collectors feed **scan**, **diff**, **fingerprint**, **IOC**, **forensic**, **HTML report**, and **STIX** notes.
| Topic | Where it matters |
|--------|------------------|
| **Polkit** (`/etc/polkit-1/rules.d`, `Result.YES`) | Rules, drift, simulate `--fix polkit`, watch, reports, STIX. |
| **Sudo NOPASSWD** | Same pattern via `sudo_nopasswd_lines`. |
| **Kernel modules** (`/proc/modules`) | Drift, fingerprint, IOC, TOML `kernel_module_loaded`. |
| **World-writable `/etc`** | Rule `SARU-FS-002`; simulate `--fix filesystem`. |
| **Auth log** (`/var/log/auth.log` or `/var/log/secure`) | Drift, IOC, built-in log rules, Sigma keyword / line matches. |
| **Syslog / messages** (`/var/log/syslog` or `/var/log/messages`) | Same; complements journal on non-journald setups. |
| **Journal** (`journalctl` short tail) | Drift, IOC, HTML “Filesystem & logs”. |
| **Audit log** (`/var/log/audit/audit.log` when readable) | Sigma auditd-derived rules (substring / pattern on raw lines). |
| **Bash history** (sampled from user `~/.bash_history`) | Sigma “suspicious command” style keyword rules. |
| **Critical file SHA-256 & MACB** | Digest drift, forensic/HTML/IOC. |
| **MITRE** | Embedded data; `saru mitre --technique Txxxx`. |
Attack-path details: [`docs/book/src/attack-paths.md`](./docs/book/src/attack-paths.md).
## Sigma rules (import)
Saru is **not** a SIEM: it evaluates patterns against **locally collected** strings (process command lines, log tails, cron lines, history samples). The CLI can **convert** the official Sigma repository’s **`rules/linux/`** tree into a **single Saru TOML bundle** of `[[rule]]` entries.
| Step | Command |
|------|---------|
| Clone Sigma | `git clone https://github.com/SigmaHQ/sigma.git` |
| Import | `saru rule import-sigma /path/to/sigma -f ~/.saru/rules/sigma_linux.toml` |
| Validate | `saru rule validate ~/.saru/rules/sigma_linux.toml` |
| Scan | `saru scan --rules-path ~/.saru/rules` |
**Scope.** Only **`rules/linux/`** is imported (Linux-focused YAML). Windows / macOS / network appliance rules in the Sigma repo are out of scope for this tool.
**Semantics.** Conversion supports common Sigma shapes: `condition: selection`, `condition: all of selection_*`, and `condition: keywords`. Rules that use negation, `1 of`, or complex parentheses are **skipped**; the command prints counts of written vs skipped rules. Imported rules are **best-effort** and may differ from a full Sigma engine — validate in your environment (`saru rule test`).
## Building & development
```
git clone https://github.com/cumakurt/saru.git && cd saru
cargo build --release -p saru-cli
./target/release/saru scan
```
| Topic | Location / command |
|--------|-------------------|
| **CI** | [`.github/workflows/ci.yml`](./.github/workflows/ci.yml) |
| **Benchmarks** (optional) | `cargo bench -p saru-core`, `cargo bench -p saru-intel` |
| **Property tests** | `proptest` in `saru-core` |
| **Smoke test** | `./scripts/selftest.sh` |
| **Static musl** | `rustup target add x86_64-unknown-linux-musl` + `musl-tools`; see [`.cargo/config.toml`](./.cargo/config.toml); `SARU_MUSL=1 sh install.sh` |
| **Documentation** | `mdbook build` in [`docs/book/`](./docs/book/) |
## Publishing on GitHub
This section is for **maintainers** tagging releases and keeping the default branch green.
| Check | Notes |
|---------------|
| **Default branch** | `main` (CI also accepts `master`). |
| **Before a release** | `cargo fmt --all`, `cargo clippy --workspace --all-targets -- -D warnings`, `cargo test --workspace`, `cargo deny check` (see [`deny.toml`](./deny.toml)). |
| **Version** | Bump `[workspace.package] version` in root [`Cargo.toml`](./Cargo.toml); tag **`v0.x.y`** to match. |
| **Binaries** | Use [`install.sh`](./install.sh) from the repo or attach musl artifacts produced by CI where applicable. |
| **License** | [AGPL-3.0](./LICENSE) — keep the full text in the repo root. |
## License
[AGPL-3.0](./LICENSE).
标签:AMSI绕过, Audit日志, Auth日志, Bash历史, Cargo测试, CIA风险评分, Clippy, Cron任务, CSV, CVSS, Heuristic规则, HTML报告, Journal日志, JSON导出, Musl, Rust, SARIF, SEO, SigmaHQ, Sigma规则, SQLite快照, SSH安全, STIX, Syslog, TOML规则, WASM插件, Web截图, 单二进制, 可视化界面, 威胁情报, 威胁检测, 安全情报, 安全扫描, 容器安全, 开发者工具, 攻击路径, 数据导出, 日志采集, 时序注入, 本地优先, 漂移检测, 目标导入, 网络流量审计, 通知系统, 邮件枚举