LLawliet188/aegis-scanner-api
GitHub: LLawliet188/aegis-scanner-api
一个基于 FastAPI 构建的模块化网络漏洞扫描器后端,通过 WebSocket 提供实时的 Nmap 扫描流式传输和结构化报告。
Stars: 0 | Forks: 0
# Aegis Scanner API
适用于网络安全 SaaS 作品集仪表板的 Production 风格 FastAPI 后端。该 API 接受授权的扫描请求,运行有边界的 Nmap 扫描,通过 WebSocket 流式传输实时的终端风格事件,并为 React 前端返回结构化的主机、服务和漏洞数据。
## 功能特性
- 版本化的 FastAPI REST API,包含 `/v1/health`、`/v1/health/detailed`、`/v1/scan` 和 `/v1/scan/{scan_id}`
- `/health`、`/scan` 和 `/scan/{scan_id}` 的向后兼容旧版 REST 路由
- 位于 `/v1/ws/scan/{scan_id}` 的 WebSocket 流,用于传输实时日志、进度、发现结果和完成事件
- 通过安全的子进程边界实现真正的 Nmap 集成,并支持 `python-nmap` XML 解析
- 针对主机名、IP 地址和小型 CIDR 范围的目标验证
- 默认的私有网络扫描策略,以降低滥用风险
- 结构化的 Pydantic 响应模型,用于处理主机、端口、漏洞和扫描摘要
- CVE 丰富服务边界已准备好,后续可接入 NVD、OSV 或商业数据源
- Docker Compose 技术栈,包含后端、由 nginx 提供服务的前端、专用反向代理、Nmap、健康检查和桥接网络
- 测试套件覆盖 API 生命周期、WebSocket 事件、目标策略、命令安全性和 XML 解析
## 架构
```
app/
main.py FastAPI app factory, CORS, app state wiring
api/routes.py Root endpoint
api/v1/routes.py Versioned REST endpoints
websocket/routes.py WebSocket scan event stream
core/config.py Environment-driven settings
core/targeting.py Target and port validation
models/ Pydantic API models
services/
scan_manager.py Scan orchestration
scan_store.py In-memory scan records
event_bus.py Per-scan WebSocket event fanout
nmap_runner.py Safe Nmap process execution
mock_scanner.py Local/test scanner
cve_service.py Future enrichment boundary
utils/nmap_resolver.py Portable Nmap executable detection
utils/nmap_parser.py Nmap XML to structured findings
tests/ API, WebSocket, safety, parser tests
```
当前的存储在产品设计上特意采用内存存储,以用于作品集/本地开发。在生产环境中,请将 `ScanStore` 替换为 Redis、Postgres 或其他由持久化队列支持的存储,这无需更改 API 契约。
## API
### `GET /`
返回包含指向 `/v1/health` 和 `/docs` 链接的小型服务索引。
### `GET /v1/health`
返回 API 状态、版本、就绪状态、环境、活跃的扫描引擎、Nmap 可用性和目标策略。
### `GET /v1/health/detailed`
返回就绪状态以及环境验证、依赖项检查、运行时间和基本系统诊断信息。
### `POST /v1/scan`
启动异步扫描。
```
{
"target": "127.0.0.1",
"options": {
"top_ports": 100,
"service_detection": true,
"os_detection": false,
"vuln_scripts": false,
"intensity": "standard"
}
}
```
响应:
```
{
"scan_id": "example",
"status": "queued",
"target": "127.0.0.1",
"websocket_url": "/v1/ws/scan/example",
"message": "Scan accepted and queued."
}
```
### `GET /v1/scan/{scan_id}`
返回当前扫描记录,并在扫描完成后返回结构化结果。
### `WS /v1/ws/scan/{scan_id}`
流式传输 JSON 事件:
```
{
"type": "progress",
"scan_id": "example",
"timestamp": "2026-05-09T12:00:00Z",
"message": "Parsing Nmap XML results",
"progress": 95,
"data": null
}
```
事件类型包括 `queued`、`log`、`progress`、`finding`、`completed` 和 `error`。
## 环境变量
将 `.env.example` 复制到 `.env` 以用于本地开发。
| Variable | Default | Purpose |
| --- | --- | --- |
| `ENV_MODE` | `development` | 运行时模式,例如 `development`、`docker` 或 `production`。旧版的 `AEGIS_ENVIRONMENT` 仍然有效。 |
| `LOG_LEVEL` | `INFO` | Python 日志级别。旧版的 `AEGIS_LOG_LEVEL` 仍然有效。 |
| `AEGIS_SCAN_ENGINE` | `nmap` | 使用 `nmap` 进行真实扫描,或使用 `mock` 在没有 Nmap 的情况下进行本地 UI/测试演示。 |
| `AEGIS_ALLOWED_TARGET_MODE` | `private` | `private` 仅允许 localhost/私有 IP;`any` 仅应在授权的网络中使用。 |
| `AEGIS_MAX_SCAN_HOSTS` | `16` | API 接受的最大 CIDR 范围大小。 |
| `AEGIS_NMAP_PATH` | 空 | 可选的显式指向 `nmap.exe` 的路径。如果在 Windows 上未设置,API 将依次检查 `C:\Program Files (x86)\Nmap\nmap.exe`、`C:\Program Files\Nmap\nmap.exe` 以及系统 PATH。 |
| `AEGIS_ENABLE_OS_DETECTION` | `false` | 启用 `-O`;通常需要提升的权限或容器 capabilities。 |
| `AEGIS_ENABLE_VULN_SCRIPTS` | `false` | 启用已配置的 Nmap 漏洞脚本。保持为选择性启用。 |
| `AEGIS_NMAP_VULN_SCRIPT_SELECTOR` | `vuln` | 启用漏洞脚本时使用的脚本选择器。 |
| `ALLOWED_ORIGINS` | localhost 前端/代理 URL | 允许调用 API 的以逗号分隔的浏览器源(origin)。生产环境中必需。出于向后兼容性考虑,仍接受 `AEGIS_CORS_ORIGINS`。 |
| `AEGIS_LOCAL_HOSTNAMES` | `localhost,host.docker.internal` | 私有目标策略下允许的主机名。 |
| `VITE_API_URL` | 在 Docker 中为 `/v1`,Vite 开发时为本地后端 URL | 前端 API 基础 URL。WebSocket URL 将根据此相同的值推导生成。 |
| `APP_PORT` | `8000` | Docker Compose 使用的公共 nginx 反向代理端口。 |
## 本地开发
请先安装 Python 3.12+ 和 Nmap。在 Windows 上,辅助脚本使用
`python -m uvicorn` 和 `npm.cmd`,因此即使 PowerShell 阻止了激活脚本或 `npm.ps1`,应用程序也能正常运行。
后端:
```
powershell -ExecutionPolicy Bypass -File .\run_backend.ps1
```
前端:
```
powershell -ExecutionPolicy Bypass -File .\run_frontend.ps1
```
一键启动 Windows:
```
powershell -ExecutionPolicy Bypass -File .\run_project.ps1
```
这将在单独的 PowerShell 窗口中打开后端和前端。
手动后端命令:
```
py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
Copy-Item .env.example .env
.\.venv\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
```
手动前端命令:
```
npm.cmd --prefix frontend install
npm.cmd --prefix frontend run dev
```
如果本地未安装 Nmap,请在进行前端集成工作时使用 `AEGIS_SCAN_ENGINE=mock`。真实的扫描请求会自动使用 `AEGIS_NMAP_PATH`、常见的 Windows 安装路径或系统 PATH。如果找不到 Nmap,扫描请求将明确失败并提示:`Nmap not installed. Install Nmap or set AEGIS_NMAP_PATH.`
运行测试:
```
pytest -q
```
## Docker
构建并运行:
```
docker compose up
```
在更改了 Dockerfile 或需要强制重新构建镜像的源代码后,请使用 `docker compose up --build`。
完整技术栈可通过以下地址访问:
```
Frontend: http://localhost:8000
Backend: http://localhost:8000/v1
WebSocket: ws://localhost:8000/v1/ws/scan/{scan_id}
```
Compose 文件使用标准的桥接网络,并启动三个服务:
- `backend`:FastAPI + Nmap,带有运行 `nmap --version` 的启动验证。
- `frontend`:由 nginx 提供服务的静态 Vite 构建产物。
- `nginx`:公共入口,将 `/` 路由到前端,将 `/v1/*` 和 `/v1/ws/*` 路由到后端。
浏览器在容器化部署中使用同源 `/v1` API 路径,因此默认的本地 Docker 技术栈无需为了前端而进行特定于主机的重新构建。
后端镜像包含了 Nmap。容器设置了 `AEGIS_NMAP_PATH=/usr/bin/nmap`,如果 `nmap --version` 失败,它将拒绝静默启动。
使用环境变量或本地 `.env` 文件来覆盖端口、CORS 源、目标策略和前端 API URL。
## CI
GitHub Actions 会在每次推送和拉取请求时运行。该工作流会安装后端依赖项,验证 Python 导入,运行后端测试套件,安装前端依赖项,对前端进行 lint 检查,构建 Vite 应用程序,构建 Docker Compose 技术栈,启动该技术栈,通过 nginx 检查 `http://localhost:8000/v1/health`,并通过同一个代理建立基本的 WebSocket 连接。
默认情况下,请勿在此项目中使用 `network_mode: host`。它在 Linux、macOS 和 Windows 上的行为各不相同,可能会使作品集难以复现。
### 从 Docker 扫描主机
在容器内部,`127.0.0.1` 指的是 API 容器本身。要扫描运行在宿主机上的服务,请使用:
```
host.docker.internal
```
Compose 文件包含:
```
extra_hosts:
- "host.docker.internal:host-gateway"
```
这使得 Linux Docker 的行为与 Docker Desktop 的行为保持一致。
## Nmap、防火墙和权限
当端口处于打开状态且操作系统防火墙允许环回连接时,本地主机测试应能与服务检测正常配合使用。对于局域网目标,目标主机防火墙必须允许向被扫描端口发送入站探测请求,并且必须允许扫描仪主机发送出站流量。
操作系统检测(`-O`)可能需要原始套接字权限。在 Docker 中,这通常意味着添加诸如 `NET_RAW` 以及有时需要 `NET_ADMIN` 等能力。这些在默认情况下是故意不启用的。仅应在受控实验室环境中开启它们。
根据脚本的不同,Nmap 漏洞脚本可能会产生大量流量或具有侵入性。此后端通过 `AEGIS_ENABLE_VULN_SCRIPTS=true` 以及请求选项 `vuln_scripts=true` 使其保持为选择性启用。
## 云部署注意事项
许多云平台限制或禁止从托管服务进行端口扫描。无服务器平台、PaaS 容器和免费层应用托管服务通常不是运行 Nmap 扫描的合适场所。
对于生产风格的部署:
- 使用 VPS 或自托管的扫描仪节点,且该服务提供商允许进行扫描。
- 仅扫描您拥有或有书面授权进行测试的资产。
- 保持 `AEGIS_ALLOWED_TARGET_MODE=private`,除非扫描仪部署在经过授权的环境中。
- 在公开暴露 API 之前,添加身份验证、授权机制、配额和速率限制。
- 将 API 置于 HTTPS 和反向代理之后。
- 将扫描记录存储在持久化后端(例如 Postgres)中,如果增加了多个 worker,则通过 Redis 流式传输事件。
- 如果扫描变成长时间运行或多租户模式,请将控制平面与扫描仪 worker 分离。
云服务提供商的示例会随时间而变化,因此在从 AWS、Azure、GCP、Render、Fly.io、Railway 或类似平台发起扫描之前,请务必查阅当前的可接受使用策略。
## 前端连接
React 仪表板位于 `frontend/` 目录中。在项目根目录下,运行
`powershell -ExecutionPolicy Bypass -File .\run_frontend.ps1`,或者直接使用
`npm.cmd --prefix frontend run dev`。使用
`.\.venv\Scripts\python.exe -m uvicorn app.main:app --reload` 单独运行后端。
React 前端使用以下环境变量:
```
VITE_API_URL=http://127.0.0.1:8000/v1
```
预期的前端流程:
1. 携带目标和选项发起 `POST ${VITE_API_URL}/scan`。
2. 从响应中读取 `scan_id`。
3. 打开由 `VITE_API_URL` 推导出的 WebSocket URL。
4. 将 `log` 事件渲染为终端输出。
5. 在进度 UI 中渲染 `progress` 事件。
6. 立即渲染 `finding` 事件。
7. 在收到 `completed` 事件时,使用包含的结果负载或调用 `GET ${VITE_API_URL}/scan/${scan_id}` 以获取权威记录。
CORS 必须包含前端开发源(origin),对于 Vite 通常为 `http://localhost:5173`。
## 安全路线图
这个作品集后端包含了用于后续生产步骤的占位符和边界:
- Auth 中间件和用户作用域的扫描记录
- 每用户的速率限制和扫描并发限制
- API 密钥或 OAuth/JWT 集成
- 带有 worker 隔离的持久化扫描队列
- CVE 丰富缓存
- 审计日志
- 租户级别的目标允许列表
这些目前是刻意没有过度设计的;当前的代码侧重于提供一个整洁、稳定且可读的基础。
标签:AV绕过, CTI, CVE, Docker, Docker Compose, FastAPI, Nginx, Nmap, Pydantic, Python, React, RESTful API, SaaS, Syscalls, WebSocket, 云存储安全, 依赖分析, 反取证, 反向代理, 后端开发, 子进程管理, 安全测试, 安全评估, 安全防御评估, 实时通信, 微服务架构, 批量查询, 提示词优化, 插件系统, 攻击性安全, 数字签名, 数据展示, 数据统计, 数据验证, 无后门, 端口扫描, 红队, 网络安全, 网络扫描, 网络资产测绘, 虚拟驱动器, 请求拦截, 资产探测, 逆向工具, 隐私保护