cybersecify/OpenEASD
GitHub: cybersecify/OpenEASD
OpenEASD 是一个开源自托管平台,自动化检测和分析组织外部攻击面,解决外部安全风险可视化和管理问题。
Stars: 4 | Forks: 9
# OpenEASD
[](https://github.com/cybersecify/OpenEASD/stargazers)
[](https://github.com/cybersecify/OpenEASD/actions/workflows/ci.yml)
[](https://github.com/cybersecify/OpenEASD/pkgs/container/openeasd)
**开放式外部攻击面检测** - 一个用于发现和分析您组织外部攻击面的自动化平台。
OpenEASD 扫描域名以发现子域名、解析 IP、扫描端口、检测服务,并在网络攻击面中寻找漏洞。
## 功能
- **自动化流水线** — 从域名到发现结果的 13 工具扫描工作流
- **网络攻击面扫描** — CVE、TLS/证书问题、SSH 配置、网络协议漏洞
- **动态工作流** — 创建自定义扫描配置,按工作流启用/禁用工具
- **工具自动注册** — 零核心修改添加新工具
- **实时扫描进度** — 带逐工具步骤跟踪的实时流水线状态
- **扫描停止/取消** — 工具步骤间的优雅取消
- **统一发现结果** — 所有工具写入带生命周期跟踪的单一 Finding 模型
- **持续监控** — 可配置计划(6 小时/12 小时/24 小时/48 小时/每周)的按域名重新扫描
- **子扫描** — 在现有扫描资产上重新运行特定工具,无需完全重新发现
- **报告** — CSV 和 PDF 导出
- **警报** — Slack 和 Teams webhook,带可配置严重性阈值;UI 中的测试按钮和警报历史
- **调度** — 一次性、定期和每日自动扫描
- **JWT 认证** — 无状态 Bearer 令牌认证,带刷新令牌轮换
- **强制密码更改** — 默认 `admin/admin` 密码必须在首次登录时更改
## 扫描流水线
```
Phase 1 Domain Security - DNS, email (SPF/DMARC/DKIM), RDAP checks
Phase 2 Subfinder - Passive subdomain enumeration
Phase 2 Amass - Active subdomain enumeration
Phase 3 DNSx - DNS resolution, public IP filtering
Phase 4 Naabu - TCP port scanning (top 100)
Phase 5 Service Detection - Classify ports as web/non-web via nmap -sV (auto)
Phase 7 Nmap - CVE scanning via NSE vulners (non-web ports)
Phase 7 TLS Checker - Certificate, cipher, and protocol analysis
Phase 7 SSH Checker - SSH configuration audit
Phase 7 Nuclei Network - Service-aware nuclei network templates against non-web ports
Phase 8 httpx - Web probing, URL discovery
Phase 9 Nuclei - Web vulnerability scanning (community templates)
Phase 9 Web Checker - Security headers, cookies, CORS analysis
```
## 架构
```
apps/core/ - Infrastructure (never changes)
api/ - Django Ninja API, JWT auth, error handlers
api/tokens/ - BlacklistedToken model (JWT JTI blacklist)
assets/ - Network assets: Subdomain, IPAddress, Port
web_assets/ - Web assets: URL
service_detection/ - Classifies ports as web/non-web (core, always runs)
findings/ - Unified Finding model
scans/ - ScanSession, pipeline orchestrator
workflows/ - Dynamic workflow engine + tool registry
scheduler/ - Django-Q2 scheduling, daily/weekly scans, per-domain monitoring, stuck scan watchdog
notifications/ - Slack/Teams alerts
insights/ - Scan summaries, charts
reports/ - CSV/PDF export
domains/ - Domain management
dashboard/ - UI home
apps/ - Tool apps (add/remove freely)
domain_security/ - DNS, email, RDAP checks
subfinder/ - Passive subdomain enumeration
amass/ - Active subdomain enumeration
dnsx/ - DNS resolution
naabu/ - Port scanning
nmap/ - CVE scanning (NSE vulners)
tls_checker/ - TLS/cert/cipher analysis
ssh_checker/ - SSH configuration audit
nuclei_network/ - Network protocol vuln scanning
httpx/ - Web probing
nuclei/ - Web vulnerability scanning
web_checker/ - Security headers, cookies, CORS
frontend/ - React 18 + Vite SPA
src/pages/ - Page components
src/components/ - Shared UI primitives (Badge, Spinner, Pagination, ConfirmButton)
src/components/ui/ - shadcn/ui primitives (Button, Card, Table, AlertDialog, …)
src/hooks/ - useFetch, usePolling
src/api/client.js - JWT apiFetch wrapper
src/auth.js - localStorage token helpers
```
## 快速开始
### Docker(推荐)
```
docker run -d \
-p 8000:8000 \
-v openeasd-data:/app/data \
-v openeasd-logs:/app/logs \
-e SECRET_KEY="$(openssl rand -hex 32)" \
-e ALLOWED_HOSTS="*" \
--cap-add NET_RAW \
--restart unless-stopped \
--name openeasd \
ghcr.io/cybersecify/openeasd:latest
```
打开 http://localhost:8000 — 使用 `admin` / `admin` 登录。在访问应用之前,您将被强制设置新密码。
#### 更新到最新版本
```
docker pull ghcr.io/cybersecify/openeasd:latest
docker stop openeasd && docker rm openeasd
# 重新运行上述 docker run 命令 — volumes 会保留所有数据
```
#### 环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
| `SECRET_KEY` | 不安全默认值 | Django 密钥 — **生产环境请设置此项** |
| `ALLOWED_HOSTS` | `localhost,127.0.0.1` | 逗号分隔的主机名(添加您的服务器 IP/域名) |
| `CSRF_TRUSTED_ORIGINS` | — | 如果通过域名访问则必需,例如 `https://openeasd.example.com` |
| `DEBUG` | `False` | 仅在本地开发时设置为 `True` |
| `DB_NAME` | `data/openeasd.db` | SQLite 路径,相对于 `/app` |
| `SLACK_WEBHOOK_URL` | — | 用于扫描警报的 Slack 传入 webhook(也可在通知 UI 中设置) |
| `MS_TEAMS_WEBHOOK_URL` | — | 用于扫描警报的 Teams 传入 webhook(也可在通知 UI 中设置) |
| `ALERT_SEVERITY_THRESHOLD` | `high` | 触发警报的最低严重性 — 由通知 UI 设置覆盖 |
| `SCAN_DAILY_HOUR` | `2` | 每日计划扫描的小时(24小时制,UTC) |
| `SCAN_DAILY_MINUTE` | `0` | 每日计划扫描的分钟 |
### Kubernetes
Manifests 位于 `k8s/`。需要一个带 nginx Ingress 控制器的集群。
**1. 设置您的密钥**
编辑 `k8s/secret.yaml` 并将 `REPLACE_WITH_OPENSSL_RAND_HEX_32` 替换为真实密钥:
```
openssl rand -hex 32
```
**2. 设置您的域名**
编辑 `k8s/configmap.yaml`(`ALLOWED_HOSTS`,`CSRF_TRUSTED_ORIGINS`)和 `k8s/ingress.yaml`(`host`)以匹配您的域名。
**3. 部署**
```
kubectl apply -k k8s/
```
**4. 更新到最新镜像**
```
kubectl rollout restart deployment/openeasd-web deployment/openeasd-worker -n default
```
#### 架构
单 Pod,两个容器,一个 `ReadWriteOnce` PVC:
| 容器 | 命令 | 资源 |
|---|---|---|
| `web` | `gunicorn`(2 个 worker) | 256Mi–512Mi |
| `worker` | `manage.py qcluster` | 512Mi–1Gi,`NET_RAW` 能力 |
一个 init 容器在主容器启动前运行迁移和管理员用户设置。`worker` 容器获得 `NET_RAW` 能力用于 nmap/naabu 端口扫描。
#### 健康检查
`GET /health/` 返回 `{"status": "ok"}` — 由 K8s 就绪性和活跃性探针使用(无需认证)。
### 独立(无 Docker)
在 Linux 服务器或 macOS 上无需 Docker 即可运行的最快方式:
```
git clone https://github.com/cybersecify/OpenEASD.git
cd OpenEASD
# Linux (安装所有依赖项及 systemd 服务)
sudo ./install.sh
# macOS
./install.sh
# 如果不需要活跃子域名枚举可跳过 amass (节省约10分钟)
sudo ./install.sh --skip-amass
```
该脚本安装:Python/uv, Node.js, nmap, ProjectDiscovery 工具(subfinder, dnsx, naabu, httpx, nuclei),amass,构建前端,生成带随机 `SECRET_KEY` 的 `.env`,运行迁移,创建 `admin` 用户,为 nmap/naabu 授予 `NET_RAW`,并在 Linux 上设置 `systemd` 服务。
安装后,编辑 `.env` 将您的域名添加到 `ALLOWED_HOSTS` 和 `CSRF_TRUSTED_ORIGINS`,然后重启:
```
sudo systemctl restart openeasd-web openeasd-worker
```
在 macOS 上,手动启动:
```
uv run gunicorn openeasd.wsgi:application --bind 0.0.0.0:8000 --workers 2
uv run manage.py qcluster # second terminal
```
### 开发模式
```
# 终端 1 — Django + Django-Q2 worker
uv run python main.py
# 终端 2 — Vite 开发服务器 (将 /api/ 代理到 8000 端口的 Django)
cd frontend && npm run dev
# React 应用运行于 http://localhost:5173
```
### main.py 标志
```
uv run python main.py --build # npm build then start
uv run python main.py --build-only # npm build only
uv run python main.py --port 9000 # custom port
uv run python main.py --no-worker # web server only (no worker)
```
## CI/CD
GitHub Actions 在每次推送到 `main` 和 `v*` 标签时运行:
- **pytest** — 快速测试套件(约 522 个测试,排除慢速 DNS/RDAP 测试)
- **bandit** — Python SAST 扫描
- **pip-audit** — 依赖项 CVE 扫描
- **前端构建** — `npm ci && npm run build`
- **Docker 构建** — 每次推送的 amd64 冒烟构建
- **发布到 GHCR** — 在每次 `main` 推送和版本标签时发布多架构(`amd64` + `arm64`)镜像
## API
REST API 通过 Django Ninja 在 `/api/` 提供服务,使用 JWT Bearer 认证。
- **文档:** http://localhost:8000/api/docs (OpenAPI/Swagger UI)
- **认证:** `POST /api/token/pair` → `{access, refresh}` 令牌
- **令牌刷新:** `POST /api/token/refresh`
## 添加新工具
创建一个在其 AppConfig 中带有 `tool_meta` 的工具应用 — 无需修改核心文件:
```
# apps/my_tool/apps.py
from django.apps import AppConfig
class MyToolConfig(AppConfig):
name = "apps.my_tool"
label = "my_tool"
verbose_name = "My Tool"
tool_meta = {
"label": "My Tool",
"runner": "apps.my_tool.scanner.run_my_tool",
"phase": 6,
"requires": ["naabu"],
"produces_findings": True,
}
```
然后将 `"apps.my_tool"` 添加到 `openeasd/settings.py` 的 `INSTALLED_APPS` 中。该工具会自动注册到工作流系统中。
### 工具应用结构
```
apps/my_tool/
apps.py - AppConfig with tool_meta
models.py - Empty (uses core Finding/asset models)
scanner.py - Orchestrator: collect -> analyze -> save
collector.py - Runs binary or probes, returns raw data
analyzer.py - Parses data, builds Finding/asset objects
```
## 运行测试
```
# 快速测试 (排除缓慢的 DNS 测试,约629个测试)
uv run pytest tests/ --ignore=tests/unit/test_domain_security.py
# 全部测试 (总计约670个)
uv run pytest tests/
```
## 技术栈
**后端:**
- **Django 5** — Web 框架
- **Django Ninja** — 带 OpenAPI 文档的 REST API
- **Django-Q2** — 后台任务队列和调度器(ORM 代理,替代 APScheduler)
- **croniter** — 用于 Django-Q2 CRON 调度的 Cron 表达式解析
- **WhiteNoise** — 在生产环境(Docker)中提供带 gzip 压缩的静态文件
- **SQLite** — 数据库(开发),可通过 `DB_NAME` 配置
- **paramiko** — SSH 协议检查
- **cryptography** — X.509 证书分析
- **xhtml2pdf** — PDF 报告生成
- **django-ninja-jwt** — 用于 Ninja API 的 JWT 认证(包装 `djangorestframework-simplejwt`);访问 + 刷新令牌,登出时黑名单
**前端:**
- **React 18 + Vite** — 带热模块替换的 SPA
- **Tailwind CSS 3 + shadcn/ui** — 带 Radix UI 组件原语的实用程序优先样式
- **sonner** — Toast 通知
- 原生 popstate 路由器(无 react-router)
## 许可证
MIT 许可证 - 详见 [LICENSE](LICENSE)
## 作者
[Rathnakara G N](https://cybersecify.com) / [CyberSecify](https://cybersecify.com)
标签:Claude, CVE检测, DInvoke, GPT, TLS检测, Web漏洞扫描, 动态工作流, 动态插桩, 占用监测, 反取证, 安全评估, 报告导出, 持续监控, 攻击面检测, 数据统计, 漏洞管理, 端口扫描, 网络安全, 自动化安全扫描, 自托管, 警报通知, 请求拦截, 调度任务, 资产管理, 运行时操纵, 逆向工具, 隐私保护