内容
安全仪表盘
[](https:///MadDogWarner/actions/workflows/docker-publish.yml)
一个自托管 Compose 堆栈,连接到本地 Ubiquiti UniFiDream Machine Pro、UDR 或等效设备),仪表盘和 MCP 服务器为 Claude Code / Code集成提供防火墙策略健康状况、威胁情报和配置漏洞信息。
---
## 截图
| | |
|---|  |  |
| — 摘要卡片和策略动作分布* |墙 — 基于区域的策略矩阵,允许/阻止|  |
| *评估 — 评分安全检查和补救指导* 警报 — 设备库存和固件暴露视图|  |  *威胁源 — 源、MISP 批规则审批* | *VLAN — 网络区域分配* |
|器](screenshots/sc) |  |
扫描器 — RFC191口扫描用于防火墙验证* | *设置 — UniFi 连接、CVE 监控源控制* |
---
## 功能
- **防火可视化** —的策略矩阵,显示所有区域对之间的允许/阻止/拒绝姿态,每个策略次数与 syslog 匹配
- **实时防火墙事件 syslog 接收 UniFi 内核阻止/允许/拒绝事件,并将其与触发的规则进行交叉引用IDS/IPS — 检测入侵启用,是否处于仅检测或预防模式,并标记配置漏洞
- **策略冲突和漂移检测** —阴影规则、重复策略,并通过 SHA-256 快照哈希跟踪策略集中的任何更改
- **评分安全 — 10 项自动检查(启用 IDS、默认拒绝 WAN 姿态、访客隔离、日志记录覆盖、允许任何规则等)并提供补救建议
- **端口扫描验证** — 仅针对 RFC1918 目标触发 nmap,将开放端口与预期区域策略进行交叉引用以显示执行漏洞
- **CVE 监控** *(可选)* — 拉取 NVD 修改后的源和 Ubiquiti 安全公告,针对 HIGH 和 CRITICAL CVE,与连接设备的固件版本进行交叉引用,并显示升级警报
- **威胁** *(可选,实验性)* — 拉取公共 IP 阻止列表(FireHOL、Spam 或自定义源将其推送到 Uni地址组和防火墙规则;还支持 MISP(恶意软件信息共享平台认证威胁情报源;支持手动模式(每次审批)或自动推送模式
- **MCP 15 个工具用于 Claude Code / Codex 查询实时数据
---
## 架构
```text
nginx (:443 HTTPS, :80 -> 重定向)
├── /api/* → api:8000 FastAPI + SQLAlchemy,每 60 秒轮询 UniFi API
└── → 前端 React SPA 由 nginx 提供(从 Vite 构建)
api:8000 还运行一个 UDP syslog 接收器在 :514
mcp:8001 MCP 服务器,通过内部 Docker 网络调用 api:8000
scanner:8002 nmap 微服务,仅限 仅限 RFC1918 目标
postgres: PostgreSQL 16,持久卷 pgdata
```
镜像发布到 GitHub 容器注册表:
镜像 | 用途 |
| ----- | ------- |
ghcr.io/maddogwarner/unifi-dashboard | FastAPI 后端 |
ghcr.io/maddogwarner/unifi-dashboard/frontend` | React SPA `ghcr.io/maddogwarner/unifi-dashboard/mcp` | MCP 服务器 |
| `ghcr.ioogwarner/unifi-dashboard/scanner` | n器 |
---
## 先决条件
- **Docker 24+** 带有 Compose 插件(`docker compose version`)
- **UniFi Dream Machine Pro、UD控制台** 运行Fi Network 9.x (基于区域的防火墙策略 API 需要 9.x)
- **UniFi API 密钥** — 在 UniFi Network → 设置 → 控制 集成 → 创建 API 密钥处生成
- 运行堆栈的机器必须可以通过网络被 UniFi 控制台访问(syslog 需要)
> **SSL 注意:**Fi 控制台自签名证书。在` 中设置 `UN_SSL=false` 以而不验证证书。如果您的信任的证书 `true` 部署
### 选项 A — 从 GH预构建镜像(推荐)
无需构建步骤。Docker Compose 将拉取最新的发布镜像。
```bash
# 1. 获取 Compose 文件和环境模板
curl -O https://raw.githubusercontent.com/MadDogWarner/unifi-dashboard/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/MadDogWarner/unifi-dashboard/main/.env.example
# 创建环境文件
cp .env.example .env
# 3. 编辑 .env — 必需值
# UNIFI_HOST 例如 https://192.168.1.1
# UNIFI_API_KEY 来自 UniFi
# UNIFI_SITE 通常为 "default POSTGRES_PASSWORD 从示例值更改
env
# 4. 拉取并启动
docker compose pull
docker compose up -d
# 检查所有服务是否健康 compose ps
```
仪表盘将在 `https://<>` 上可用。HTTP 请求到端口 80定向到 HTTPS。
选项 B — 从源代码构建
```bash
://github.comDogWarner/unifi-dashboard.git
cd unifi .env.examplenano .env IFI_HOST、UN_KEY、UNPOSTGRES_PASSWORD
docker compose up --build -```
仪表盘将在<主机-ip可用。HTTP 请求到端口 80 会重定向。
---
## TLS仪表盘默认443 端口运行 HTTPS。80 端口的 HTTP重定向到 HTTPS 自签名证书(首次启动时,nginx 会自动生成一个自签名 RSA 2048 证书,有效期为 10 年,并将其写入 `certs/server.crt` 和 `.key`。会警告您证书不受信任。这是自托管 LAN 仪表盘的预期结果;永久的浏览器### 自定义证书
从您的私有 CA、pfSense/OPNsense `openssl` 格式的证书和私钥。
2. 将为 `server.crt`链)和 ``(私钥)。
启动堆栈这两个文件放在项目根 `certs/` 目录中。
4. 启动或重启 nginx:`docker nginx`
入口点两个文件均缺失时生成自签名证书。完整证书对永远覆盖。
### Let'scertbot)
Certbot live 目录符号链接certs/`:
```bash
lnetc/lets/yourdomain/full certs/server.crt
ln -sf /etc/letsencryptourdomainkey.pem certs/server.key
```
添加一个 certbot 部署钩子,在每次续期后运行 `docker compose restart nginx`。
### 停止和升级
```bash
# 停止
docker compose down
# 升级到最新镜像(选项 A)
docker compose pull
docker compose up -d
# 清除数据库并重新开始(破坏性)
docker compose downdocker composed
```
配置
复制 `.` 到 `.env`以下值。
| 变量 | 必需 | 默认值 | 描述 |
| -------- | -------- | ------- || `UNIFI | 是 | —地 UniFi 控制台 URL,例如 `https://192.1.1` |
| `UNIFI` | 是 | — | 来自 UniFi Network → 控制平面 → 集成的 API 密钥 `UNIFI_SITE 是 | `default` 站点名称。在设置 → 系统 → 站点找到 |
| `UNIFI_VERIFY_SSL` | `false`仅在控制台证书时设置为 ` |
| `POSTGRES_PASSWORD` | 是 | — — 在从示例值更改 |
| `POSTGRES_DB 否 | `unifi_dashboard` | 数据库名称 |
| `POSTGRES_USER 否 | `dashboard 数据库用户 |
| `AUTH_SECRET` | 是 | — | 用于签署仪表 的长随机密钥 rand -hex 32` 生成 |
|_TOKEN_LIFETIME_SECONDS` | `86400` | 仪表盘牌寿命( |
| `SYSLOG_PORT` | 否 | ` syslog 接收器监听的 UDP 端口 `POLL_INTERVAL_SECONDS` | 否 | `60 轮询 UniFi API 的频率。10 |
| `LOG_RETENTION_DAYS` `30`保留日志记录(过期) |
| `MCP_AUTH_TOKEN` 需要 | — | MCP 服务器所需的长随机承载| `M` | 开发false` | 仅在隔离的本地 MCP 开发中设置为 `true` |
| `MCP_URL` | 否://localhost:800 | 保护资源中使用的公共 MCP| `VITE_API_URL` | 开发 `http://localhost:8000` | 前代理目标。Docker堆栈中未使用## 仪表验证
仪表盘 支持的页面登录。在新数据库上,首次浏览器访问会到 `/setup`便您可以创建初始。第一个注册帐户会自动提升为超级用户,之后关闭开放注册。
在启动 API 之前生成并设置 `AUTH_SECRET`:
```bash
openssl rand -hex 32
```
```env
AUTH_SECRET=<在此处粘贴生成的密钥>
AUTH_TOKEN_LIFETIME_SECONDS=86400
```
除健康检查、登录、设置状态和首次注册外,所有仪表盘 API 路由都需要 `Authorization: Bearer <token>`。其他帐户可以通过 `POST /api/v1/users/` 由超级用户创建。
---
## Syslog 设置
仪表盘通过将 syslog 中的规则名称与策略将防火墙阻止/允许事件与其策略引用。如果未配置仪表盘仍将 API 的策略元数据,但命中次数将。
**在 控制台上配置远程 syslog:**
1. Network → 设置 → 系统 → 高级 → 远程日志记录
2.Syslog 主机** 设置为运行此堆机器的 IP 地址. 将 ** 端口** 设置514`(或 `.env` 中的 `SYSLOG_PORT` 值)
4. 启用 **防火墙** 日志类别
5. 点击 **应用更改**
Docker Compose 在 API 容器中发布 UDP `${SYSLOG_PORT:-514}` 到主机。在启动后确认映射:
```bash
docker compose port api 514/```
**预期日志 (内核防火墙事件):
```text
kernelWAN_LOCAL]IN=eth= SRC=1.3.4192.168.1 LEN=60 PROTO=TCP SPT=54321 DPT
```
动作在后缀中编码: = 丢`A` = 接受,`R` = 拒绝。
> **防火墙:** 运行此堆栈的主机必须 UniFi 控制台的 UDP 端口 514 的入站流量。如果使用 `ufw`:`fw allow fromifi-ip> to514 proto udp`
---
## MCP 服务器
服务器在 8001运行,并公开 可以调用的工具,以查询您的实时 UniFi。它默认需要 bearer-token 身份验证,其绑定到 `127.0.0.1:8001`,因此仅可在运行此堆栈的主机上访问。
在启动 MCP 服务之前生成一个长随机令牌并设置在 `.env` 中:
```bash
openssl rand -hex
```
```env
MCP_AUTH_TOKEN=<在此处粘贴生成的令牌>
```
**添加到您的 Claude Code 设置** (`~/.claude/settings.json` 或项目 `.claude/settings.json`):
```json
{
"mcpServers": {
"unifi": {
"type": "http",
": ":8001 "headers": "Authorization":MCP_AUTH_TOKEN}"
}
}
}
}
```
如果 Claude Code 在不同的主机上运行,请有意更改 Compose 端口绑定,例如 `192.1.150:8001:800,并将访问权限限制在受信任的管理主机或 VPN 上。不要在 LAN 或互联网上广泛公开 MCP 端口;它可以读取实时仪表盘数据并触发 RFC1918 端口扫描。
仅在隔离的本地开发中,`MCP_AUTH_DISABLED=true` 启动 MCP 服务器而不进行 bearer-token 检查。
**可用工具:**
| 工具 | 描述 |
| ---- | ----------- |
| `get_firewall_policies` | 列出所有具有命中次数的基于区域的策略 |
| `get_firewall_logs` | 查询防火墙事件 — 按源 IP、规则名称或限制进行筛选 |
| `reats` |最近的 IDS/IPS事件 |
get_ids_status`/IPS 启用模式和配置| `get_vlans` | 具有和策略计 |
| `get_assessment` | 运行完整的安全评估 |
| `_conflicts` |检测到的影子策略和重复策略冲突 |
| `get_drift_report` | 最新策略漂移事件和更改内容 |
| `run_port_scan` | 触发对 RFC1918 目标的 nmap 扫描 |
| `get_scan_results` | 检索扫描结果 |
| `get_cve_alerts` | 列出未确认的高/严重 CVE 及受影响设备 |
| `get_cve_devices` | 设备库存与匹配的 CVE 计数和固件版本 |
| `get_threatfeed_status` | 威胁源启用状态、最后更新、总阻止 IP |
| `get_threatfeed_entries` | 查询阻止 IP/CIDR 列表 — 支持 CIDR 搜索和限制 |
| `get_threatfeed_pending_rules` | 列出待批威胁源规则更改 |
**示例 Claude Code 会话:**
```text
> get_assessment
得分:72/100 — 5 pass, 2 warn, 3 fail
FAIL IDS/IPS 处于仅检测模式 — 预防未激活
FAIL WAN→LAN 默认动作未显式设置为 BLOCK
FAIL 访客区域有一个 ALLOW 策略到内部
WARN 3 个策略未启用 syslog 日志记录
WARN 2 个策略名称与默认 "Policy N" 模式匹配
PASS 管理 VLAN 存在且在网关区域
...
```
---
## 端口扫描器
扫描器服务使用 nmap 验证防火墙策略是否实际执行。评估结果包括最新的开放主机/端口证据,并将这些端口与 UniFi 公开的数据关联起来,如果有的话,将这些端口与 WAN 端口转发或 WAN 允许规则关联起来,以便直接识别暴露的服务。
**安全约束:** 扫描器硬拒绝任何在 RFC1918 范围之外的目标 (`10.0.0.0/8`, `172.0.0/12`, `192.168.0.0/16`)。此检查在调用 nmap 之前在 `services/scanner/scanner.py` 中强制执行,无法通过 API 绕过。
扫描器容器需要 `NET_RAW` 和 `NET_ADMIN` 能力才能使用 SYN 扫描模式。如果需要降低这些能力,TCP 连接扫描将在没有提升权限的情况下工作。
---
## 可选以下两个功能默认禁用。在仪表盘的 **设置** 页面中启用并配置它们。所有设置都存储在数据库中,并在下一次轮询周期内生效,无需重启容器。
可选的 HTTP 代理 URL 可以在设置中配置,如果运行堆栈的主机没有直接互联网访问权限。代理适用于来自两个收集器的所有出站 HTTP 调用。
### CVE 监控
启用后,CVE 收集器会以可配置的间隔(默认为 24 小时)拉取两个源:
1. **NVD 修改后的源** (`nvdcve-0-modified.json.gz`) — 官方国家漏洞数据库批量源,过滤iquiti (`ui`) CPE 条目,CVSS 基准分数为 7.0 或高/严重. **Ub 社区安全 — 公告索引在 `community.ui.com/releases` 被爬取以获取安全咨询帖子和 CVE ID,并提取并与 记录进行交叉从 UniFi API (`stat/device`) 拉取设备固件版本,并的 CVE CPE 标准进行比较。受影响在 **CVE 警报** 页面上显示,并带有升级提示。
仅存储高(CVSS ≥ 7.0)和严重(CVSS ≥ 9.0)CVE。可以单独确认设备修复后可以忽略警报。
### 威胁源集成
> **⚠ 实验性功能 — 请在启用前阅读**
启用后,威胁源收集器将轮询配置的 IP 阻止列表,并通过旧版防火墙 API 将条目推送到 UniFi 控制台,生成地址组和防火墙规则。此功能 **修改 UniFi 控制台的实时防火墙配置**。
**风险和限制:**
- **实验状态** — 该功能尚未针对所有固件版本进行验证。使用的防火墙规则操作值(`drop`)被认为是正确的,但行为可能会因固件版本而异。在首次启用该功能后,请在 UniFi 仪表盘中检查创建的规则,并确认它们已正确应用。
- **防火墙混乱** — 每个启用的规则集都会生成一个地址组(或多个,如果组合阻止列表超过 500 个条目)和一个相应的拒绝规则。这些规则的命名格式为 `ThreatFeed-{RULESET}-{N}` 和 `Block-ThreatFeed-{RULESET}-{N}`。禁用该功能会尝试自动删除它们;如果清理失败,请手动从 UniFi 网络 → 防火墙 → 地址组/规则中删除任何剩余的 `ThreatFeed-*` 组和规则。
- **连接影响** — 阻止大型公共威胁源范围可能会有少量误报的风险。开始时先启用单个规则集(例如 `WAN_IN`),而不是一次性启用所有区域。
- **手动模式为默认值** — 规则更改会排队等待批准,而不是立即推送。在 **威胁源** 页面上查看并批准每个更改,然后再将其应用于 UniFi。只有在您熟悉该功能在您的硬件上的行为后,才切换到自动推送模式。
**支持的源类型:**
- **URL 源** — 普通的 HTTP/HTTPS 源,格式为 netset、JSON 或 JSONL(FireHOL、Spamhaus DROP 或任何兼容的阻止列表)。URL 会被验证,并且必须可以公开访问。
- **MISP 服务器** — 通过 API 密钥向 MISP 实例进行身份验证,并向 `/attributes/restSearch` 发送 POST 请求以检索 IP 类型的指标(`ip-src`、`ip-dst`、`cidr` 和端口变体)。仅收集标记为 `to_ids: true` 并通过 MISP 警告列表的属性。分页会自动处理。MISP 源可以针对托管在 RFC1918 上的服务器(自托管 MISP 很常见);环回、元数据端点和其他保留范围仍然被阻止。API 密钥按源存储,并且永远不会在 API 响应中返回。为自签名 MISP 证书提供了一个可选的“验证 SSL”切换开关。
**最小轮询间隔为 1 小时**。默认源(FireHOL Level 1 和 Spamhaus DROP)在首次启动时被播种,但被禁用 — 您必须从威胁源页面明确启用每个源。
---
## API
所有端点都在 `/api/v1/` 下,并且通过 nginx 代理。
| 端点 | 方法 | 描述 |
| -------- | ------ | ----------- |
| `/api/v1/health` | GET | 服务健康状况,数据库状态,UniFi API 可达性 |
| `/api/v1/firewall/policies` | GET | 基于区域的策略,包含命中次数 |
| `/api/v1/firewall/rules` | GET | 旧版防火墙规则,包含命中次数 |
| `/api/v1/firewall/logs` | GET | 分页的 syslog 防火墙事件(筛选:源 IP,规则名称) |
| `/api/v1/firewall/zones` | GET | 具有指定网络的区域 |
| `/api/v1/threats/events` | GET | IDS/IPS 威胁事件 |
| `/api/v1/threats/ids-status` | GET | IDS/IPS 配置 + 差距分析 |
| `/api/v1/networks/` | GET | 具有区域和策略元数据的 VLAN |
| `/api/v1/assessment/` | GET | 评分安全评估 |
| `/api/v1/assessment/conflicts` | GET | 检测到的策略冲突 |
| `/api/v1/drift/snapshots` | GET | 策略快照历史 |
| `/api/v1/drift/diff/{a}/{b}` | GET | 两个快照之间的 JSON 差异 |
| `/api/v1/drift/latest-change` | GET | 最近的漂移事件 |
| `/api/v1/scan/` | POST | 触发 nmap 扫描 `{target, ports, scan_type}` |
| `/api/v1/scan/{id}` | GET | 轮询扫描结果 |
| `/api/v1/settings` | GET | 读取所有运行时设置 |
| `/api/v1/settings` | PUT | 更新运行时设置(功能开关,间隔,代理 URL) |
| `/api/v1/cve/alerts` | GET | 分页的 CVE 警报 — 按严重性和确认状态筛选 |
| `/api/v1/cve/alerts/{id}/acknowledge` | POST | 将 CVE 警报标记为已确认 |
| `/api/v1/cve/devices` | GET | 设备库存,包含每个设备匹配的 CVE ID |
| `/api/v1/cve/refresh` | POST | 触发立即的 CVE 轮询周期 |
| `/api/v1/threatfeed/feeds` | GET / POST | 列出或添加配置的源 |
| `/api/v1/threatfeed/feeds/{id}` | PUT / DELETE | 更新或删除源 |
| `/api/v1/threatfeed/status` | GET | 启用状态,最新更新,总条目,待处理计数 |
| `/api/v1/threatfeed/entries` | GET | 分页的阻止 IP/CIDR 条目 — 支持 CIDR 搜索 |
| `/api/v1/threatfeed/pending-rules` | GET | 列出待处理规则更改,等待批准 |
| `/api/v1/threatfeed/pending-rules/{id}/approve` | POST | 批准并将待处理规则更改应用于 UniFi |
| `/api/v1/threatfeed/pending-rules/{id}/reject` | POST | 拒绝待处理规则更改 |
| `/api/v1/threatfeed/refresh` | POST | 触发立即的威胁源轮询周期 |
---
## 验证
启动堆栈后:
```bash
# 所有服务都应显示“healthy”或“running”
docker compose ps
# 健康检查(-k 接受自签名证书)— 无需身份验证
curl -k https://localhost/api/v1/health
# HTTP 重定向检查 — 应返回 301,带有 Location: https://
curl -I http://localhost/
# 获取 Bearer token(用您的帐户替换凭证)
TOKEN=$(curl -k -s -X POST https://localhost/api/v1/auth/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin@example.com&password=yourpassword" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
# 返回策略列表(直到 UniFi 凭证配置并运行第一个轮询)
curl -k -H "Authorization: Bearer $TOKEN" https://localhost/api/v1/firewall/policies
# 测试扫描器 RFC1918 防护 — 应返回 HTTP 400
curl -k -X POST https://localhost/api/v1/scan/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"target":"8.8.8.8","ports":"80"}'
# 触发有效扫描
curl -k -X POST https://localhost/api/v1/scan/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"target":"192.168.1.1","ports":"22,80,443"}'
```
---
## 开发设置
### 在本地运行服务,无需 Docker
**API:**
```bash
cd services/api
pip install -e ".[dev]"
# 需要运行 PostgreSQL 实例 — 更新 .env 中的 POSTGRES_HOST
uvicorn app.main:app --reload --port 8000
```
**前端:**
```bash
cd services/frontend
npm install
# 设置 VITE_API_URL=http://localhost:8000 如果 API 在本地运行
npm run dev # http://localhost:5173
```
**MCP 服务器:**
```bash
cd services/mcp
pip install "mcp[cli]>=1.0" httpx
# 设置 API_BASE_URL=http://localhost:8000
python server.py
```
### 在 Docker 中仅运行数据服务
```bash
# 启动只有 postgres 和 API 的服务,以便前端开发服务器可以代理到它
docker compose up postgres api -d
cd services/frontend && VITE_API_URL=http://localhost/api npm run dev
```
### 代码质量
```bash
# Python linting 和格式化
cd services/api && ruff check . && ruff format --check .
# TypeScript 类型检查
cd services/frontend && npm run build # tsc 在 Vite 构建过程中运行
```
---
## 贡献
欢迎贡献。请在提交拉取请求之前打开问题以讨论重大更改。
### 贡献者
- [MadDogWarner](https://github.com/MadDogWarner) — 项目作者
- [Claude](https://claude.ai) (Anthropic) — 架构、代码审查和实施指导
- [Codex](https://openai.com/codex) (OpenAI) — 主要代码生成
### 指南
- 遵循现有的代码风格(Python 使用 Black/Ruff,TypeScript 使用严格模式)
- 提交中不包含机密或凭证
- 扫描器 RFC1918 防护不得削弱或删除
- 为任何用户可见的更改添加或更新 `changelog.md` 条目
---
## 许可证
MIT — 参见 [LICENSE](LICENSE) 以获取详细信息。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器