dmcslab/Dwell
GitHub: dmcslab/Dwell
Dwell 是一个开源的自托管事件响应模拟训练平台,通过分支叙事让蓝队分析师在逼真的勒索软件事件中做决策并承担后果,适用于 SOC 入职培训和蓝队演练。
Stars: 1 | Forks: 0
Dwell — 事件响应培训平台
以分析师的身份体验真实的勒索软件事件。做出决策。见证后果。
专为 SOC 入职培训、蓝队演练和安全意识培训而构建。
## **在线演示:** [演示](https://playdwell.dmcslab.com)
## ⚡ 快速开始 — 无需配置
**前提条件:** [Docker Desktop](https://docs.docker.com/get-docker/)(包含所有其他必需组件)
### macOS / Linux
```
git clone https://github.com/dmcslab/Dwell.git
cd dwell
./start.sh
```
### Windows
```
git clone https://github.com/dmcslab/Dwell.git
cd dwell
start.bat
```
然后在浏览器中打开 **http://localhost:5173**。
**默认管理员凭据:**
```
Username: admin
Password: Dwell!Change123
```
首次登录后,请通过管理面板更改密码。
## 这是什么?
Dwell 让你置身于正在发生的勒索软件事件之中。你是一名分析师——不是在阅读案例研究,而是在做出实时决策:
- 你是先进行遏制,还是先收集取证证据?
- 你是从备份中恢复,还是先检查持久化?
- 你是否因为按顺序隔离而惊动了正在活动的攻击者?
错误的决策会带来**叙事性的后果**——在遏制阶段做出错误选择,下一阶段就会变成“勒索软件已到达域控制器”,而不是一次彻底的清除。这是真正的分支模拟,而不是多选题测验。
## 功能特性
| 功能 | 详情 |
|---|---|
| **43 个 IR 场景** | 3 个简单 / 17 个中等 / 23 个困难,均带有分支后果 |
| **每个场景 4 个 IR 阶段** | 准备 → 检测 → 遏制 → 根除与恢复 |
| **NIST SP 800-61r2** | 每个阶段都映射到事件响应生命周期 |
| **MITRE ATT&CK TTPs** | 技术解释参考了真实的攻击者技术 |
| **多人游戏** | 分享链接——多名分析师加入同一个实时会话 |
| **4 种分析师角色** | IR 负责人、网络、端点、单人——每种角色看到不同的上下文 |
| **旁观者模式** | 观看实时会话而不影响游戏进程 |
| **场景分支** | 错误的选择会重定向到危机阶段,而不仅仅是扣除尝试次数 |
| **总结报告** | 每次会话后的经验教训 + PDF 导出 |
| **管理面板** | 完整的场景 CRUD——无需接触 JSON 即可构建你自己的场景 |
| **深色 / 浅色模式** | 可持久化的主题切换 |
| **自托管** | 你的数据永远不会离开你的服务器 |
## 停止和重启
```
# 停止(数据保留在 Docker volumes 中)
./stop.sh # macOS/Linux
stop.bat # Windows
# 重启
./start.sh # macOS/Linux
start.bat # Windows
```
## Cloudflare Tunnel(通过互联网共享)
要在不开放防火墙端口的情况下让远程参与者访问该应用程序:
1. 安装 [cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/)
2. 创建隧道:`cloudflared tunnel create dwell`
3. 将其指向 `http://localhost:5173`
4. 启动应用:`./start.sh`
5. 启动隧道:`cloudflared tunnel run dwell`
**无需更改代码。** 应用程序会自动从请求头中检测公共 URL,并自动生成正确的分享链接。
完整设置指南:[CLOUDFLARE_TUNNEL.md](CLOUDFLARE_TUNNEL.md)
## 升级 Dwell
从仓库根目录运行升级脚本。它会检查 GitHub 上的更新,如果有可用更新,将在保留所有数据和配置的同时下载并应用它们。
**macOS / Linux**
```
./upgrade.sh
```
**Windows**
```
upgrade.bat
```
如果你已经使用的是最新版本,脚本会提示你并退出——不会更改任何内容。
### 什么会被保留
| 项目 | 安全? |
|---|---|
| 所有游戏会话和历史记录 | ✅ 始终保留 |
| 用户账户和密码 | ✅ 始终保留 |
| 在管理面板中构建的自定义场景 | ✅ 需要在 `backend/.env` 中设置 `SKIP_SEED_UPDATE=true` |
| 你的 `backend/.env` 配置 | ✅ 更新前会备份,如有更改会自动恢复 |
### 在首次升级之前 — 一次性设置
如果你通过管理面板构建了自定义场景,请将此行添加到 `backend/.env` 中以保护它们:
```
SKIP_SEED_UPDATE=true
```
没有此设置,seed 脚本会在重启时覆盖自定义场景。只需设置一次,以后就再也不用担心了。
### 脚本执行的操作
1. 从 `https://github.com/dmcslab/Dwell.git`(分支:`main`)获取最新代码,**而不在本地更改任何内容**
2. 如果未发现更新——立即退出并显示提示消息
3. 如果发现更新——显示新内容的摘要
4. 备份 `backend/.env`
5. 停止容器——你的数据库和会话数据保持不变
6. 拉取更新
7. 如果更新修改了 `.env`,则恢复你的 `.env`
8. 重新构建镜像并重启服务
9. 如果 scenario-worker 的文件发生更改,则自动重新构建其镜像
### 手动升级(如果你更喜欢这种方式)
```
# macOS / Linux
git pull origin main
docker compose up -d --build
# 仅在 scenario-worker 文件发生更改时
./build_worker.sh
```
### ⚠ 不要做什么
```
# 切勿运行此命令 — -v 标志会破坏您的数据库及所有数据
docker compose down -v
```
不带 `-v` 的 `docker compose down` 是完全安全的——卷总是会保留。
### 出了问题?
在进行任何更改之前,你的 `.env` 始终会在 `backend/.env.upgrade-backup` 处进行备份。要恢复它:
```
cp backend/.env.upgrade-backup backend/.env
docker compose restart backend
```
要回滚到以前的版本:
```
git log --oneline -10 # find the version you want
git checkout
docker compose up -d --build
```
## 安全说明
Dwell 专为**本地/私有网络部署**作为培训工具而设计。
为了易于使用,一些默认配置有意设计得较为宽松——以下是在外部暴露应用程序之前需要了解的内容。
| 设置 | 默认值 | 说明 |
|---|---|---|
| 数据库凭据 | `dwell:dwell` | 仅限内部 Docker 网络——数据库端口永远不会暴露给主机 |
| `SECRET_KEY` | 自动生成 | 每次进程启动时都会生成一个随机密钥。只有在 `backend/.env` 中设置了固定密钥时,会话才能在容器重启后继续存在(见下文) |
| 管理员密码 | `Dwell!Change123` | **首次登录后请立即更改**,通过 Admin → Users |
| `ALLOWED_ORIGINS` | `*` | 是安全的,因为唯一暴露的端口 (5173) 是 Vite 代理——后端无法被直接访问 |
| `--forwarded-allow-ips=*` | 已启用 | Cloudflare Tunnel 所需——该隧道转发来自未确定的内部 IP 的请求头 |
### 设置持久化的 SECRET\_KEY
如果你希望登录会话在容器重启后仍然有效,请在 `backend/.env` 中添加一个固定密钥:
```
# 生成密钥
python3 -c "import secrets; print(secrets.token_hex(32))"
# 将输出粘贴到 backend/.env
SECRET_KEY=
```
如果没有此设置,每次启动时都会生成一个新的随机密钥,并且所有现有的 JWT token 都将失效(用户需要在重启后重新登录)。
这对于临时培训会话来说没有问题;如果你运行持续多天的演练,请设置一个固定密钥。
## 架构
```
Browser (any URL)
│
│ HTTP / WSS :5173
▼
┌─────────────────────────┐
│ Vite Dev Server │ ← only port exposed to host
│ React + TypeScript │
│ /api/* → backend:8000 │ ← internal proxy
└──────────┬──────────────┘
│ (Docker internal network)
▼
┌─────────────────────────┐ ┌────────────┐
│ FastAPI Backend │───►│ PostgreSQL │
│ Python 3.12 │ └────────────┘
│ WebSocket game loop │ ┌────────────┐
│ │───►│ Redis │
└──────────┬──────────────┘ └────────────┘
│
▼
┌─────────────────────────┐
│ Orchestrator │ ← manages per-session worker containers
│ docker-py │
└─────────────────────────┘
```
数据库和 Redis **不会暴露**给主机——仅限内部 Docker 网络。
## 自定义
### 更改管理员密码
登录 → 点击 ⚙ Admin → Users 选项卡 → 编辑 admin 账户。
### 创建你自己的场景
登录 → ⚙ Admin → Scenarios 选项卡 → **+ New Scenario** → 按照 4 步构建器操作。
无需 JSON 或代码。
### 添加更多用户
Admin → Users → **+ Add User**
## 技术栈
| 层级 | 技术 |
|---|---|
| 前端 | React 18, TypeScript, Tailwind CSS, Vite |
| 后端 | FastAPI, Python 3.12, asyncpg, SQLAlchemy |
| 数据库 | PostgreSQL 16 |
| 缓存 / Pub-Sub | Redis 7 |
| 认证 | JWT(访问)+ Redis 中的不透明刷新令牌 |
| 容器 | Docker, Docker Compose |
| 字体 | Syne, IBM Plex Sans, IBM Plex Mono |
## 许可证
Dwell 是自由软件:你可以根据自由软件基金会发布的 **GNU General Public License v3.0** 条款重新分发和/或修改它。
完整文本请参见 [LICENSE](LICENSE)。
分发本程序是希望它会有用,但**不提供任何保证**——甚至没有适销性或特定用途适用性的暗示保证。
由 dMCSlab 构建
标签:DAST, Docker, ELK, OPA, PE 加载器, SOC入门, 决策模拟, 勒索软件, 安全仿真, 安全分析师, 安全培训平台, 安全防御评估, 库, 应急响应, 恶意软件分析, 搜索引擎查询, 数字取证, 沙箱, 测试用例, 版权保护, 网络安全, 自动化脚本, 蓝队演练, 请求拦截, 隐私保护, 靶场