devpedrois/crabwalk

GitHub: devpedrois/crabwalk

Crabwalk 是一款基于 Rust 和 BLAKE3 并行哈希的文件系统快照与差异对比 CLI 工具,用于检测目录中文件内容及元数据的未授权变更。

Stars: 0 | Forks: 0

# Crabwalk [![构建](https://img.shields.io/badge/build-passing-brightgreen)](#) [![许可证: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![Rust 版本](https://img.shields.io/badge/rust-1.75%2B-orange)](https://www.rust-lang.org) [![安全审计](https://img.shields.io/badge/security-defense--in--depth-red)](#security) **用于安全审计和部署验证的文件系统快照差异对比工具。** Crabwalk 会对目录进行时间点快照(包含 BLAKE3 哈希、权限、时间戳、所有权),并通过对比来精确展示发生了哪些变化。专为基础设施安全团队、系统管理员和合规工作流而构建。 ``` crabwalk snap /etc --output baseline.json # ... 部署、事故或时间流逝 ... crabwalk snap /etc --output current.json crabwalk diff baseline.json current.json --format table ``` ``` Crabwalk Diff Report Summary: Added: 1 | Removed: 1 | Modified: 2 | Metadata: 3 | Total: 7 ┌──────────────────┬─────────────────────────┬────────────────────────────────┐ │ Status │ Path │ Details │ ├──────────────────┼─────────────────────────┼────────────────────────────────┤ │ ADDED │ etc/cron.d/backdoor │ │ │ REMOVED │ etc/app.conf │ │ │ MODIFIED │ bin/sshd │ hash: a1b2c3... → f4e5d6... │ │ META │ etc/sudoers │ permissions: 0440 → 0777 │ └──────────────────┴─────────────────────────┴────────────────────────────────┘ ``` ## 目录 - [用例](#use-cases) - [环境要求](#requirements) - [安装](#installation) - [快速开始](#quick-start) - [命令](#commands) - [忽略模式](#ignore-patterns) - [输出格式](#output-formats) - [架构](#architecture) - [安全](#security) - [性能](#performance) - [贡献](#contributing) - [许可证](#license) ## 用例 - **部署验证** - 对比发布前后的文件系统状态 - **安全审计** - 检测二进制文件、配置或权限的未授权更改 - **配置漂移检测** - 发现不同环境之间或随时间推移的配置漂移 - **合规证据** - 将确定性的、可复现的审计快照持久化作为交付物 - **事件响应** - 准确查明事件发生期间发生了什么变化以及发生时间 ## 环境要求 - Rust 1.75 或更新版本 - Cargo(随 Rust 一起安装) 通过 [rustup](https://rustup.rs) 安装 Rust: ``` curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` ## 安装 ### 从源码安装 ``` git clone https://github.com/devpedrois/crabwalk cd crabwalk cargo build --release ``` 编译生成的二进制文件位于 `target/release/crabwalk`。将其复制到您需要的任何位置: ``` cp target/release/crabwalk /usr/local/bin/crabwalk ``` ### 免安装运行 ``` cargo run -- snap /etc --output baseline.json cargo run -- diff baseline.json current.json ``` ## 快速开始 **1. 对目录进行快照:** ``` crabwalk snap /etc --output baseline.json ``` **2. 进行更改,再次快照:** ``` crabwalk snap /etc --output current.json ``` **3. 对比两个快照的差异:** ``` crabwalk diff baseline.json current.json --format table ``` **4. 导出为 HTML 报告:** ``` crabwalk diff baseline.json current.json --format html --output report.html ``` ## 命令 ### `crabwalk snap ` 递归遍历目录并生成一个 JSON 快照,其中包含每个条目的 BLAKE3 哈希、权限、时间戳和所有权。 ``` crabwalk snap [OPTIONS] OPTIONS: -o, --output Write snapshot to file (default: stdout) --max-size Skip files larger than SIZE (e.g. 100MB, 1GB) --no-ignore Do not load .crabwalkignore files --follow-symlinks Follow symlinks [default: off, see Security] --threads Rayon worker threads (default: number of CPU cores) ``` 示例: ``` # 对 /etc 建立快照,跳过大于 10MB 的文件 crabwalk snap /etc --max-size 10MB --output etc-snap.json # 使用 4 个线程 crabwalk snap /var/www --threads 4 --output www-snap.json # 建立快照且忽略 .crabwalkignore crabwalk snap /app --no-ignore --output app-snap.json ``` ### `crabwalk diff ` 对比两个快照文件并报告发生的更改。将每项更改分类为 `Added`(新增)、`Removed`(移除)、`Modified`(内容修改)或 `MetadataChanged`(元数据修改:权限、所有权、mtime)。 ``` crabwalk diff [OPTIONS] OPTIONS: -f, --format Output format: table, json, html (default: table) -o, --output Write output to file (default: stdout, required for html) --ignore-mtime Ignore mtime-only differences --ignore-metadata Suppress metadata-only changes, show content changes only --only Filter change types: added,removed,modified,metadata ``` 退出代码: | 代码 | 含义 | |------|---------| | `0` | 未检测到更改 | | `1` | 检测到更改 | | `2` | 执行或输入错误 | 示例: ``` # 终端中以人类可读的表格显示 crabwalk diff before.json after.json # 输出 JSON 到文件 crabwalk diff before.json after.json --format json --output diff.json # 仅显示内容更改,忽略权限/mtime 漂移 crabwalk diff before.json after.json --ignore-metadata # 仅显示新增和删除的文件 crabwalk diff before.json after.json --only added,removed # HTML 报告 crabwalk diff before.json after.json --format html --output report.html ``` ## 忽略模式 在要进行快照的目录中创建一个 `.crabwalkignore` 文件。使用与 `.gitignore` 相同的语法,由 ripgrep 使用的同一个 `ignore` crate 提供支持。 ``` # .crabwalkignore # 忽略构建产物 target/ *.log # 忽略版本控制元数据 .git/ # 取反:始终包含此特定日志 !important.log # 忽略缓存目录 **/__pycache__/ **/node_modules/ ``` 传入 `--no-ignore` 可完全禁用此行为。 ## 输出格式 ### 表格(默认) 带颜色的终端输出。最适合交互式使用和快速审查。 - 绿色:`ADDED` - 红色:`REMOVED` - 黄色:`MODIFIED` - 青色:`META` ``` crabwalk diff old.json new.json ``` ### JSON 机器可读的结构化输出。适用于通过管道传递给其他工具、作为交付物存储或构建仪表板。 ``` crabwalk diff old.json new.json --format json ``` 输出结构: ``` { "old_snapshot": "baseline.json", "new_snapshot": "current.json", "timestamp": "2026-05-20T12:00:00Z", "summary": { "added": 1, "removed": 1, "modified": 2, "metadata_changed": 3, "total": 7 }, "entries": [ { "path": "etc/sudoers", "change_type": "MetadataChanged", "details": ["permissions: 0440 -> 0777"] } ] } ``` ### HTML 包含摘要卡片和交互式过滤器的独立 HTML 报告。需要指定 `--output`。 ``` crabwalk diff old.json new.json --format html --output report.html open report.html ``` ## 架构 ``` crabwalk/ ├── Cargo.toml # Dependencies and package metadata ├── .crabwalkignore.example # Example ignore pattern file │ ├── src/ │ ├── main.rs # Entry point: CLI parse -> dispatch to snap/diff │ ├── cli.rs # Clap structs: SnapArgs, DiffArgs, OutputFormat │ │ │ ├── walker.rs # Recursive directory traversal via walkdir │ │ # Applies filters before hashing │ │ # Never follows symlinks outside root │ │ │ ├── hasher.rs # BLAKE3 streaming hash in 64KB chunks via BufReader │ │ # Never loads entire file into memory │ │ # Send + Sync for rayon parallelism │ │ │ ├── snapshot.rs # Snapshot + FileEntry structs with serde │ │ # Entries always sorted by path (determinism) │ │ │ ├── diff.rs # Diff engine: HashMap-indexed comparison │ │ # Categorizes: Added, Removed, Modified, MetadataChanged │ │ │ ├── filter.rs # .crabwalkignore via `ignore` crate │ │ # --max-size enforcement before hashing │ │ # Special file detection and skip │ │ │ ├── output/ │ │ ├── mod.rs # OutputFormatter trait + format dispatch │ │ ├── table.rs # comfy-table + colored terminal output │ │ ├── json.rs # serde_json pretty output to stdout or file │ │ └── html.rs # Askama compiled template -> HTML report │ │ │ └── error.rs # CrabwalkError enum via thiserror │ # Io, Walk, Hash, Snapshot, Diff, Filter, Output │ ├── templates/ │ └── report.html # Askama HTML diff report template │ ├── tests/ │ ├── snap_test.rs # Snapshot determinism, metadata, errors │ ├── diff_test.rs # All change categories │ ├── filter_test.rs # Ignore patterns and max-size │ ├── security_test.rs # Symlinks, special files, path traversal │ └── integration_test.rs # End-to-end: snap -> modify -> snap -> diff │ └── benches/ └── walker_bench.rs # Criterion: sequential vs parallel, various sizes ``` ### 数据流 ``` PATH | v [walker.rs] -- recursive walk, metadata collection | v [filter.rs] -- .crabwalkignore, --max-size, skip special files | v [hasher.rs] -- rayon par_iter: BLAKE3 streaming hash per file | v [snapshot.rs] -- sort by path, serialize to JSON | v (two snapshots) [diff.rs] -- HashMap comparison, categorize changes | v [output/] -- table | json | html ``` ### 主要依赖 | Crate | 版本 | 用途 | |-------|---------|---------| | `clap` | 4 | 带有 derive 宏的 CLI 解析 | | `walkdir` | 2 | 递归目录遍历 | | `blake3` | 1 | 流式加密哈希(比 SHA-256 更快) | | `rayon` | 1.10 | 通过 `par_iter()` 实现数据并行 | | `serde` + `serde_json` | 1 | 快照序列化 | | `ignore` | 0.4 | `.gitignore` 风格的模式匹配(与 ripgrep 相同) | | `comfy-table` + `colored` | 7 / 2 | 带颜色的终端表格输出 | | `askama` | 0.12 | 编译时类型安全的 HTML 模板 | | `thiserror` | 2 | 符合人体工程学的错误类型派生 | | `chrono` | 0.4 | ISO 8601 时间戳 | ## 安全 Crabwalk 是一款安全审计工具。它默认将文件系统视为具有潜在威胁的环境。 ### 纵深防御 | 层级 | 威胁 | 缓解措施 | |-------|--------|-----------| | 1. 软链接安全 | 软链接逃逸至 `/etc/shadow` | 默认不跟随软链接。`--follow-symlinks` 为可选启用项,且会限制在根目录内 | | 2. 路径标准化 | 通过精心构造的路径进行目录遍历 | 所有快照路径均相对于根目录,绝不使用绝对路径 | | 3. 流式哈希 | 大文件导致 OOM | 通过 64KB 的 `BufReader` 数据块计算 BLAKE3。任意文件大小均保持恒定内存占用 | | 4. 特殊文件保护 | 无限读取 `/dev/zero`,管道阻塞 | 跳过字符设备、块设备、FIFO 和套接字并进行报告 | | 5. 错误报告 | 隐藏篡改行为的静默失败 | 每个 I/O 错误都会记录在 `FileEntry.error` 中。快照元数据中包含 `total_errors` | | 6. TOCTOU 感知 | 文件在遍历与哈希计算期间发生更改 | 扫描中途消失的文件会产生错误条目,绝不会引发 panic | | 7. 快照完整性 | 被篡改的快照文件 | 确定性的 JSON 排序。用于兼容性检查的 Schema 版本字段 | | 8. 输入验证 | 格式错误的路径或选项 | 所有 CLI 输入在处理前均经过验证。严格的 serde 反序列化 | ### Crabwalk 不会做的事 - 不验证其自身二进制文件的完整性(请使用您的包管理器或 TPM 来实现此目的) - 快照未进行加密签名(如有需要,请自行进行 GPG 签名) - 不进行实时操作(它是一个时间点工具,不是 daemon) ## 性能 Crabwalk 使用 Rayon 跨所有可用的 CPU 核心并行计算文件哈希。无论文件大小如何,内存占用始终保持不变。 ### 基准测试结果 2026-05-20 的参考运行结果(`cargo bench --bench walker_bench`): | 基准测试 | 时间 | |-----------|------| | `snapshot_small / sequential` | ~9.91 ms | | `snapshot_small / parallel` | ~4.46 ms | | `snapshot_medium / sequential` | ~107.06 ms | | `snapshot_medium / parallel` | ~41.21 ms | | `hash_single_file / 1KB` | ~43.36 µs | | `hash_single_file / 100KB` | ~76.67 µs | | `hash_single_file / 1MB` | ~316.56 µs | | `hash_single_file / 10MB` | ~4.13 ms | | `diff_engine / 100 entries` | ~35.75 µs | | `diff_engine / 1000 entries` | ~404.13 µs | | `diff_engine / 10000 entries` | ~6.83 ms | 并行模式在中等工作负载下可带来约 2.5 倍的加速。diff 引擎随条目数量呈线性扩展。 ### 运行基准测试 ``` cargo bench --bench walker_bench ``` 使用 Hyperfine 对比串行与并行: ``` hyperfine \ "crabwalk snap ./target --threads 1 --output /tmp/seq.json" \ "crabwalk snap ./target --threads 8 --output /tmp/par.json" ``` ## 许可证 MIT。详见 [LICENSE](./LICENSE)。
标签:Rust, 可视化界面, 文件系统, 网络流量审计, 运维工具, 通知系统