Sagneo/sagneo-secops-workbench
GitHub: Sagneo/sagneo-secops-workbench
一个隔离的双 VM 安全运营实验室,用于在合成遥测环境中演练从告警检测、案例处理到受控取证和完整性验证的完整防御工作流。
Stars: 1 | Forks: 0
# Sagneo SecOps Workbench
[](https://github.com/Sagneo/sagneo-secops-workbench/actions/workflows/ci.yml)
[](https://github.com/Sagneo/sagneo-secops-workbench/releases/latest)
[](LICENSE)
[](LIMITATIONS.md)
一个可复现的 SecOps 实验室,用于追踪合成遥测数据,从受限的数据接入,到告警分析、案例处理、受控取证以及完整性验证。
这是一个隔离的双 VM 实验室——而非生产级 SIEM、企业级事件响应平台、商业 SOC,也非声称的专业监督。运行时数据和证据保持私密;受版本控制的测试固定数据和证据报告均为合成的或经过脱敏处理的。
## 学习背景与实践重点
我构建这个项目,作为我持续进行的网络安全教育和独立家庭实验室实践的一部分。目标是超越孤立的练习,实现一个完整且可审查的防御工作流:接入遥测数据、解释告警、管理调查、收集有边界的证据、验证完整性,并证明结果是可复现的。
这项工作强调了我希望带入安全运营中的习惯:
范围纪律、最小权限、可解释的决策、失败历史的保留、可衡量的验证,以及便于其他分析师跟进的文档。
下文的每一项声明都有提交的测试固定数据、测试、运行手册或脱敏证据作为支撑。
| 实践的能力 | 在此处的应用方式 | 可验证的项目证据 |
|---|---|---|
| 安全架构 | 隔离的双 VM 家庭实验室、仅主机网络、回环应用暴露、仅限密钥管理 | [架构](#architecture), [安全](SECURITY.md) |
| 遥测工程 | 受限的 Linux 身份验证和 Suricata 接入、UTC 标准化、来源溯源、解析器错误隔离、重放去重 | [遥测流水线](docs/TELEMETRY_PIPELINE.md) |
| 检测工程 | 五个版本化 YAML 规则、稳定身份标识、确定性评估、告警-事件关联 | [检测与分诊](docs/DETECTION_AND_TRIAGE.md) |
| SOC 分析与分诊 | 告警过滤、严重性/置信度理由、误报上下文、处置、建议措施、仅追加历史 | [告警分诊报告](docs/evidence/reports/02_ALERT_TRIAGE.md) |
| 事件工作流 | 分析师与模拟审查员职责分离、案例状态流转、不可变的收集请求、记录在案的升级与关闭 | [事件报告](docs/INCIDENT_REPORT.md) |
| 证据处理 | 固定配置收集、严格的路径/链接/大小控制、规范化清单、SHA-256 验证、防篡改测试 | [收集与完整性](docs/evidence/reports/04_COLLECTION_AND_INTEGRITY.md) |
| 安全工程 | Argon2、不透明会话、CSRF、服务端授权、CSP、受限执行、强化的容器设置 | [安全](SECURITY.md), [局限性](LIMITATIONS.md) |
| 验证与改进 | 自动化测试、静态分析、依赖审计、恢复检查,以及经过测量的 `666 → 1` 身份查询优化 | [过程改进](docs/PROCESS_IMPROVEMENT_CASE_STUDY.md), [测试与恢复](docs/TESTING_AND_RECOVERY.md) |
该项目还提供了动手实践机会,包括诊断失败的收集过程、在不抹除失败记录的情况下纠正狭窄的根本原因、验证从一次性副本中的恢复,以及将展示出的实验室能力与生产环境声明区分开来。
## 五分钟审查
- [学习背景与实践重点](#learning-context-and-practical-focus)
- [架构](#architecture) 和 [从事件到证据的工作流](#event-to-evidence-workflow)
- [合成界面图库](#synthetic-interface-gallery)
- [已验证的结果](#verified-results)
- [五分钟审查员导览](#five-minute-reviewer-tour)
- [确定性本地演示](#deterministic-local-demo)
- [安全与隔离](#security-and-isolation)
- [功能与刻意排除项](#capabilities-and-deliberate-exclusions)
- [开发概述](docs/DEVELOPMENT_OVERVIEW.md)
- [局限性与状态](#limitations-and-status)
## 架构
```
flowchart LR
subgraph Host["Operator workstation"]
Browser["Analyst / Reviewer browser"]
SSH["Key-only SSH local forward"]
end
subgraph Lab["VMnet2 host-only network — 192.168.90.0/24"]
Core["secops-core
FastAPI + rules + case workflow"] DB[("Private SQLite
Alembic 0004")] Endpoint["linux-endpoint-01
bounded collection target"] end Browser --> SSH -->|"127.0.0.1:8080 → guest loopback:8000"| Core Core --> DB Endpoint -.->|"fixed-profile run
access revoked in final state"| Core ``` 最终的实验室状态为:每个 VM 拥有一个自定义的 `VMnet2` 适配器,没有桥接或 NAT 适配器,没有客户机默认路由,也没有公共应用监听器。上面显示的收集路径代表一次受限的固定配置运行;在最终状态下,其专用账户、密钥、包装器和 sudo 条目均已被撤销。 ## 从事件到证据的工作流 [](docs/assets/event-to-evidence-workflow.svg) 打开图表以查看完整尺寸。蓝色 = 接入,紫色 = 检测和审查控制,琥珀色 = 分析师工作流,绿色 = 收集和证据。 每个支持的转换都通过应用程序行为进行记录。保留的时间线包括原始的技术收集失败和更正后的替换请求;它不会重写失败历史。 ## 合成界面图库 这些视图是基于一次性测试固定数据库渲染的。此处显示的账户、事件、地址、标识符、日期和决策均为合成实验室数据; 不包含任何 VM 运行时、留存的证据、凭据或操作员信息。 选择图片以全尺寸查看。
## 已验证的结果
| 领域 | 接受的结果 | 边界 |
|---|---:|---|
| 遥测 | 来自 2 种源类型的 1,201 个标准化事件;2 个隔离的解析器错误 | 确定性测试固定数据 |
| 检测规则 | 5 个不可变版本 | 4 条遥测规则 + 1 条证据完整性规则 |
| 干净测试固定数据评估 | 665 个告警;重放创建 0 个并报告 665 个重复项 | 一次性 SQLite 演示 |
| 事件-告警关联 | 1,555 个链接 | 精确追踪的清单 |
| 规则分布 | `404 / 41 / 100 / 120`; `EVID-001 = 0` | 干净克隆没有私有验证失败 |
| 接受的收集 | 8 个工件,61,910 字节,验证通过 | 一个固定的实验室目标/配置;模拟审查 |
| 过程改进 | SQL 身份查询 `666 → 1`(减少 99.85%) | 一个合成 SQLite 工作负载 |
| 最终质量门禁 | 收集 108 个,通过 107 个,1 个已知的 Windows 符号链接跳过,0 个失败/错误 | 干净的本地门禁;88% 的应用代码行覆盖率 |
| 最终运行时 | 在客户机 `127.0.0.1:8000` 上健康运行,通过 SSH 隧道访问 | 私有仅限 VMnet2 实验室 |
经过验证的运行时包含 666 个告警,因为其保留的验证记录触发了 `EVID-001`。干净的测试固定数据演示正确地生成了 665 个。
## 功能与刻意排除项
已实现:
- Argon2 身份验证、不透明服务端会话、CSRF 验证以及服务端的分析师/审查员授权;
- SQLite 以及通过 `0004` 进行的 Alembic 迁移;
- 受限的 Linux 身份验证/sudo 以及 Suricata EVE 解析器;
- UTC 标准化、稳定的 SHA-256 身份标识、批量来源溯源、重放去重、解析器错误隔离以及数据源健康度;
- 透明的 YAML 检测规则、告警过滤/分页、仅追加的分诊历史以及案例时间线;
- 一个由审查员控制的 `linux-ir-lite-v1` 收集合约;
- 受限的流式收集和规范化清单验证,具备严格的路径/链接/大小处理;
- 确定性的离线测试固定数据和一次性恢复程序。
刻意排除:
- 生产环境实时传感器、任意上传、原始 PCAP 发布或常规远程命令执行;
- SSO、注册、密码重置、多租户管理或企业级数据库引擎;
- 任意取证配置、法律上的证据保管链声明、自动化响应或生产环境 SLA 声明;
- 公共运行时、桥接网络、最终状态下的 NAT 以及公共端口发布。
## 五分钟审查员导览
1. 阅读 [数据源健康报告](docs/evidence/reports/01_SOURCE_HEALTH.md)
以了解接入边界、解析器隔离和时效性语义。
2. 跟随 [告警分诊](docs/evidence/reports/02_ALERT_TRIAGE.md) 进入
[案例时间线](docs/evidence/reports/03_CASE_TIMELINE.md)。
3. 检查 [收集与完整性](docs/evidence/reports/04_COLLECTION_AND_INTEGRITY.md)
以了解批准边界、保留的失败、接受的替换以及 SHA-256 的局限性。
4. 对比测量过的 [过程改进](docs/evidence/reports/05_PROCESS_IMPROVEMENT.md)。
5. 使用 [证据索引](docs/evidence/EVIDENCE_INDEX.md),然后
审查三个操作运行手册:
[监控与分诊](docs/runbooks/01_SOURCE_MONITORING_AND_TRIAGE.md),
[案例与证据](docs/runbooks/02_INCIDENT_CASE_AND_EVIDENCE.md),以及
[演示与恢复](docs/runbooks/03_RECOVERY_DEMO_AND_ESCALATION.md)。
6. 审查脱敏的 [事件报告](docs/INCIDENT_REPORT.md)、[CHANGELOG](CHANGELOG.md) 中的精简发布检查单,以及
[发布完整性响应程序](docs/RELEASE_INTEGRITY_RESPONSE.md)。
## 确定性本地演示
前置条件:Git、Python 3.12 以及锁定的依赖项。冷依赖安装需要网络访问或准备好的 wheel 缓存;依赖项存在后,测试固定数据演示本身是离线的。
```
python -m venv .venv
python -m pip install --require-hashes -r requirements-dev.txt
python -c "from pathlib import Path; Path('data/disposable').mkdir(parents=True, exist_ok=True)"
```
在启动 Python 之前设置一个新的一次性数据库:
```
$env:APP_DATABASE_URL = 'sqlite:///./data/disposable/reviewer-demo.db'
```
```
export APP_DATABASE_URL='sqlite:///./data/disposable/reviewer-demo.db'
```
然后运行:
```
alembic upgrade head
python -m app.telemetry seed-assets
python -m app.telemetry import --source LINUX_AUTH --path fixtures/linux/auth.log
python -m app.telemetry import --source SURICATA_EVE --path fixtures/suricata/eve.jsonl
python -m app.telemetry import --source LINUX_AUTH --path fixtures/linux/auth-malformed.log
python -m app.telemetry summary
python -m app.detections evaluate
python -m app.detections evaluate
python -m app.detections summary
```
预期结果是上表中的干净测试固定数据值。完整的命令、
失败处理、一次性 SQLite 恢复以及私有证据验证位于 [测试、离线演示和恢复](docs/TESTING_AND_RECOVERY.md) 中;记录在案的
确定性验证位于 [确定性测试固定数据演示记录](docs/DETERMINISTIC_DEMO_RECORD.md) 中。
账户引导是交互式的:
```
python -m app.bootstrap
```
它仅创建一个分析师和一个审查员,并拒绝覆盖现有的
用户集。切勿将密码、会话值、私钥、接受的数据库或原始证据放入命令、日志、截图、Issue 或提交中。
## 安全与隔离
- 应用程序端口 `8000` 仅在客户机回环地址上发布,并通过主机回环 SSH 隧道进行审查。
- 实验室管理采用仅限密钥的 SSH;禁用了 root、密码和键盘交互 SSH。
- UFW 拒绝未经请求的/横向访问;主机管理仅限于
`192.168.90.1`。
- 最终配置移除了两个开发 NAT 适配器、自动化 sudo 条目以及收集器密钥/账户访问权限、包装器和 sudo 条目。
- 容器以非 root 用户身份运行,具有只读文件系统、无新增权限,并丢弃了所有 capabilities。
- 原始证据、密钥、运行时数据库、VM 文件、安装介质、私有报告、缓存和特定于操作员的路径均保留在受追踪的源代码树之外。
请参阅 [安全](SECURITY.md) 和 [局限性](LIMITATIONS.md)。
## 技术栈
Python 3.12、FastAPI、Jinja2、SQLAlchemy、Alembic、SQLite、PyYAML、Argon2、
Docker Compose、pytest、Ruff、严格的 mypy、Bandit、Git、Ubuntu Server、VMware
Workstation、Linux 身份验证/journal 数据以及 Suricata EVE 测试固定数据。
## 局限性与状态
- 审查员批准是一项模拟的实验室控制,而非外部的专业监督。
- 遥测、用户、资产和工作负载均为合成的,且为实验室规模。
- 特意将 SQLite 限制在单实例实验室中。
- SHA-256 证明与受信任清单的字节一致性,而非散列之前的原始真实性、
完整性或合法保管权。
- 性能结果不适用于并发、分布式或
企业级工作负载。
- 恰好存在六份证据报告;[报告 6](docs/evidence/reports/06_REPRODUCIBILITY_CONTROLS.md)
记录了可复现的 CI 和合并验证。
- 源码分发仅包含代码和脱敏证据;它不包含
也不运行私有运行时。
基于 [Apache License 2.0](LICENSE) 授权;请参阅 [NOTICE](NOTICE)。
FastAPI + rules + case workflow"] DB[("Private SQLite
Alembic 0004")] Endpoint["linux-endpoint-01
bounded collection target"] end Browser --> SSH -->|"127.0.0.1:8080 → guest loopback:8000"| Core Core --> DB Endpoint -.->|"fixed-profile run
access revoked in final state"| Core ``` 最终的实验室状态为:每个 VM 拥有一个自定义的 `VMnet2` 适配器,没有桥接或 NAT 适配器,没有客户机默认路由,也没有公共应用监听器。上面显示的收集路径代表一次受限的固定配置运行;在最终状态下,其专用账户、密钥、包装器和 sudo 条目均已被撤销。 ## 从事件到证据的工作流 [](docs/assets/event-to-evidence-workflow.svg) 打开图表以查看完整尺寸。蓝色 = 接入,紫色 = 检测和审查控制,琥珀色 = 分析师工作流,绿色 = 收集和证据。 每个支持的转换都通过应用程序行为进行记录。保留的时间线包括原始的技术收集失败和更正后的替换请求;它不会重写失败历史。 ## 合成界面图库 这些视图是基于一次性测试固定数据库渲染的。此处显示的账户、事件、地址、标识符、日期和决策均为合成实验室数据; 不包含任何 VM 运行时、留存的证据、凭据或操作员信息。 选择图片以全尺寸查看。
分析师分诊详情及仅追加历史
[](docs/assets/ui-alert-triage.jpg)标签:Metaprompt, 取证, 安全实验室, 安全运营, 扫描框架, 生成式AI安全, 虚拟机, 逆向工具

