pathsec/Apparition

GitHub: pathsec/Apparition

一个容器化的浏览器中间人平台,通过 noVNC 向目标提供隔离的 Firefox 浏览会话,支持活动管理、Token 邀请和浏览器配置文件导出。

Stars: 0 | Forks: 0

# Apparition Apparition 是一个活动驱动、容器化的中间人浏览器平台,通过链接向接收者提供临时、隔离的浏览会话。当用户访问 /join/ 时,Apparition 会启动一个专用的 Docker 容器,该容器在无头 XFCE 桌面中运行 Firefox,并通过 noVNC 进行流式传输,提供全屏的“真实浏览器”体验,而不会暴露操作主机或其他会话。Node/Express 控制服务器负责编排会话的创建和拆除,执行活动生命周期和完成规则,并在 SQLite 中记录活动/token/会话状态。 会话可以在超时、手动拆除或定义的完成条件满足后自动结束——随后容器将被销毁,用户将被重定向到配置的目的地。可选地,用户可以继续浏览,直到达到活动定义的时间限制。当满足完成条件时,可以从管理控制台下载会话的浏览器配置文件;否则,配置文件将随时可在会话视图中下载,以供审查和报告。

Architecture

Campaign Tab Campaign Creation Tab

## 重要提示! 这是通过大量“氛围编码” 创建的首个发布版本。可能存在不可预见的问题或缺陷。请仅在授权环境中使用。 ## 工作原理 1. 您创建一个**活动 (Campaign)**,设置起始 URL、生命周期和重定向 URL。 2. 您生成**邀请 Token**,并可选择通过电子邮件发送给接收者。 3. 接收者点击他们的 `/join/` 链接。 4. Apparition 启动一个 Docker 容器,通过 noVNC 在无头 XFCE 桌面中运行 Firefox。 5. 用户看到全屏浏览器。当会话结束时(超时、完成触发或手动拆除),容器将被销毁,用户将被重定向。 ## 架构 ``` ┌─────────────────────────┐ │ nginx │ (optional, recommended) │ TLS termination + │ │ WebSocket proxy │ └────────────┬────────────┘ │ :443 ┌────────────▼────────────┐ │ Apparition (Node) │ :3000 │ Express + SQLite │ │ Admin UI + API │ └────────────┬────────────┘ │ Docker socket ┌──────────────────┼──────────────────┐ │ │ │ ┌──────────▼──────┐ ┌────────▼──────┐ ┌───────▼───────┐ │ novnc-session-1 │ │novnc-session-2│ │novnc-session-3│ │ Firefox + noVNC │ │Firefox + noVNC│ │Firefox + noVNC│ │ port 6900 │ │ port 6901 │ │ port 6902 │ └─────────────────┘ └───────────────┘ └───────────────┘ ``` - **控制服务器 (Control server)** — Node.js/Express 应用程序。管理活动、Token、会话和管理仪表板。通过 Docker socket 生成和拆除兄弟容器。 - **noVNC 容器** — Docker 兄弟容器,每个容器运行 XFCE + Firefox + noVNC,绑定到唯一的主机端口(默认为 6900–6999)。每个容器通过环境变量接收会话上下文。 - **SQLite** — 存储活动、邀请 Token、会话、电子邮件历史和提交内容。 - **nginx**(生产环境推荐)— 终止 TLS,代理所有流量,包括 noVNC 的 WebSocket 升级。 ## 前置条件 - **Docker Engine** 20.10+ 和 **Docker Compose** v2+ - Linux 主机(推荐 Debian/Ubuntu 或 RHEL/Fedora) - Node.js 18+(仅在本地开发时需要 — Docker 负责生产环境) -(生产环境)用于 TLS 的 nginx + certbot ## 安装 ### 1. 克隆仓库 ``` git clone apparition cd apparition ``` ### 2. 配置环境变量 ``` cp .env.example .env ``` 打开 `.env` 并至少设置: | Variable | What to set | |---|--- | `SESSION_SECRET` | 一个长的随机字符串 — 运行 `openssl rand -hex 64` | | `JWT_SECRET` | 另一个不同的长随机字符串 — 运行 `openssl rand -hex 64` | | `CONTROL_HOST` | 此服务器的公共 URL,例如 `https://example.com` | | `CONTAINER_HOST` | 容器回调的内部 URL — `http://host.docker.internal:3000` | | `NOVNC_HOST` | noVNC 端口可访问的主机名 — 通常为 `host.docker.internal` | ### 3. 构建 Kiosk 镜像 在启动任何会话之前,必须构建自定义的 noVNC/Firefox 容器镜像: ``` docker compose build novnc-kiosk ``` 这会构建 `./novnc-container` 并将其在本地标记为 `novnc-kiosk`。只需运行一次,或者在更改 `novnc-container/` 后再次运行。 ### 4. 启动控制服务器 ``` docker compose up -d ``` 应用程序在端口 3000 上运行。使用以下命令检查日志: ``` docker compose logs -f app ``` ### 5. 创建管理员账户 ``` docker compose exec app node src/scripts/create-admin.js ``` 按照提示设置用户名和密码。这只需运行一次。 ### 6. 打开管理面板 导航到 `http://localhost:3000/admin/login`(或您的域名)。 ## 生产环境设置 (nginx + TLS) ### 安装并配置 nginx 复制包含的 nginx 配置: ``` sudo cp nginx/novnc-manager.conf /etc/nginx/sites-available/apparition ``` 在配置文件中将 `YOUR_DOMAIN` 替换为您的实际域名: ``` sudo sed -i 's/YOUR_DOMAIN/example.com/g' /etc/nginx/sites-available/apparition ``` ### 获取 TLS 证书 ``` sudo certbot --nginx -d example.com ``` ### 启用站点 ``` sudo ln -s /etc/nginx/sites-available/apparition /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx ``` ### 为生产环境更新 `.env` ``` CONTROL_HOST=https://example.com CONTAINER_HOST=http://host.docker.internal:3000 COOKIE_SECURE=true ``` 更改 `.env` 后重启应用程序: ``` docker compose up -d ``` ## 环境变量 有关完整的注释模板,请参阅 `.env.example`。 ### 必需项 | Variable | Description | |---|--- | `SESSION_SECRET` | Express 会话签名的密钥 | | `JWT_SECRET` | 容器 JWT 签名的密钥(必须与 `SESSION_SECRET` 不同)| ### 服务器 | Variable | Default | Description | |---|---|---| | `PORT` | `3000` | Node 服务器监听的端口 | | `CONTROL_HOST` | — | 公共基础 URL(用于邀请链接和电子邮件)| | `CONTAINER_HOST` | `http://host.docker.internal:3000` | 容器用于回调的内部 URL | | `NOVNC_HOST` | `host.docker.internal` | noVNC 容器端口可访问的主机/IP | | `COOKIE_SECURE` | `false` | 通过 HTTPS 提供服务时设置为 `true` | | `JOIN_PATH` | `join` | 邀请链接的 URL 段(例如 `/join/`)| | `DB_PATH` | `/data/app.db` | SQLite 数据库文件的路径 | ### Docker / 容器 | Variable | Default | Description | |---|---|---| | `NOVNC_IMAGE` | `novnc-kiosk` | 用于会话容器的 Docker 镜像 | | `NOVNC_PORT_START` | `6900` | noVNC 容器主机端口池的起始端口 | | `NOVNC_PORT_END` | `6999` | 主机端口池的结束端口 | | `CONTAINER_NETWORK` | `bridge` | 容器连接到的 Docker 网络 | | `CONTAINER_MEMORY_LIMIT` | `1073741824` | 每个容器的内存限制(字节)(默认 1 GB)| | `CONTAINER_CPU_LIMIT` | `1000000000` | 每个容器的 CPU 限制(纳秒 CPU)(默认 1 CPU)| | `CLEANUP_INTERVAL_MS` | `60000` | 清理作业运行的频率(毫秒)| ### SMTP / 电子邮件 | Variable | Default | Description | |---|---|---| | `SMTP_HOST` | — | SMTP 服务器主机名 | | `SMTP_PORT` | `587` | SMTP 端口 | | `SMTP_SECURE` | `false` | 使用 SMTPS(端口 465 时设置为 `true`)| | `SMTP_USER` | — | SMTP 用户名或 API 密钥 | | `SMTP_PASS` | — | SMTP 密码或密钥 | | `SMTP_FROM` | — | 发件人地址 | | `SMTP_FROM_NAME` | `Apparition` | 外发电子邮件的显示名称 | SMTP 设置也可以通过管理设置 UI 进行配置。环境变量优先于 UI 值。 ### 可选:直接 TLS(不带 nginx) | Variable | Description | |---|--- | `SSL_KEY` | TLS 私钥的路径 — 直接在 Node 上启用 HTTPS | | `SSL_CERT` | TLS 证书的路径 | ## 活动 (Campaigns) 活动是一组邀请 Token 继承的命名配置。每个活动定义: | Field | Description | |---|--- | **Name** | 活动的内部标签 | | **Start URL** | 会话开始时 Firefox 打开的 URL | | **Lifetime** | 会话持续时间(分钟)— 容器将在此时间后拆除 | | **Redirect URL** | 会话结束后用户被发送到的位置 | | **Slug** | 查看器的清晰 URL 前缀(例如 `/my-campaign/`)| | **Favicon URL** | 查看器中显示的标签页图标(根据用户浏览自动更新)| | **Completion URL** | 当 Firefox 访问此 URL 时,触发会话完成 | | **Completion Cookie** | 当设置此 Cookie 名称时,触发会话完成 | | **After Completion** | `redirect`(默认)拆除容器;`keep_alive` 保持其运行 | | **Show Loading Page** | 是否在容器启动时显示“Starting...”页面 | ## 邀请 Token 每个邀请 Token 映射到一个唯一的 `/join/` URL。Token 可以: - 从活动详情页面单独生成 - 批量生成用于电子邮件分发 - 通过内置电子邮件编辑器发送 当使用 Token 时: 1. 启动一个 Docker 容器(`novnc-session-`) 2. Firefox 打开活动的起始 URL 3. 加载页面轮询控制服务器,直到 noVNC 端口接受连接 4. 查看器渲染一个全屏 iframe,显示 Firefox 会话 查看器每 3 秒轮询一次服务器,以将浏览器标签页标题和图标与 Firefox 的当前页面同步。 ## 管理面板 位于 `/admin` 的管理面板提供: - **仪表板** — 实时会话计数和最近活动 - **活动** — 创建和管理活动,查看 Token 和会话日志 - **邀请链接** — 管理单个 Token,查看点击和启动统计 - **电子邮件** — 撰写和发送带有嵌入邀请链接的活动电子邮件 - **会话** — 完整的会话日志,包含提交数据和 Firefox 配置文件下载 - **设置** — 配置 SMTP 和 Cloudflare Turnstile ## 机器人防护 要在加入页面上要求 CAPTCHA 验证,请在 `.env` 中添加或通过设置 UI 进行配置: ``` TURNSTILE_SITE_KEY=your-site-key TURNSTILE_SECRET_KEY=your-secret-key ``` 配置后,加入页面会在允许会话开始之前渲染一个 Turnstile 小部件。 ## 开发 ``` npm install cp .env.example .env # edit for local config npm run dev # starts with nodemon hot-reload ``` 服务器在 `http://localhost:3000` 上运行。Docker 必须正在运行且可访问,以便进行容器管理。 ## 安全说明 - 应用程序容器挂载 Docker socket(`/var/run/docker.sock`),这授予了对主机的 root 等效访问权限。在生产环境中,考虑使用 [Tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) 来限制允许哪些 Docker API 调用。 - 会话 Cookie 是 `httpOnly`、`sameSite: lax` 的,当 `COOKIE_SECURE=true` 时为 `secure`。 - 所有容器到服务器的回调都通过短期、会话范围的 JWT 进行身份验证。 - 加入和会话端点应用了速率限制。 - `docker-compose.yml` 中的 `security_opt: label:disable` 在 Fedora/RHEL 上是必需的,以允许在 SELinux 下访问 Docker socket。它仅影响应用程序容器的标签限制。
标签:BITM, Docker, ESC8, Express, Firefox, GNU通用公共许可证, MITM代理, NIDS, Node.js, noVNC, RBIS, SQLite, XFCE, 一次性链接, 会话录制, 匿名浏览, 安全防御评估, 容器化, 攻击模拟, 浏览器中间人, 社会工程学, 网络安全, 自定义脚本, 请求拦截, 远程浏览器隔离, 隐私保护, 隔离环境, 驱动签名利用