SirGCMHatoRey/UniSOC-Sentinel

GitHub: SirGCMHatoRey/UniSOC-Sentinel

专为 UniFi 网络构建的生产级容器化 SIEM 平台,提供日志采集、解析、威胁检测、告警与可视化等全链路安全监控能力。

Stars: 0 | Forks: 0

# UniSOC Sentinel — 企业级 UniFi SIEM 平台 一个专为 UniFi 网络构建的生产级安全信息和事件管理 (SIEM) 平台。UniSOC Sentinel 从 UniFi 硬件采集 syslog 数据,对事件进行标准化和丰富,通过可配置的告警规则检测威胁,并通过统一的仪表板展示所有信息。 ## 目录 1. [概述](#overview) 2. [架构](#architecture) 3. [前置条件](#prerequisites) 4. [快速开始](#quick-start) 5. [UniFi 配置](#unifi-configuration) 6. [配置参考](#configuration-reference) 7. [TLS 选项](#tls-options) 8. [备份与恢复](#backup-and-restore) 9. [监控](#monitoring) 10. [故障排除](#troubleshooting) 11. [安全说明](#security-notes) ## 概述 UniSOC Sentinel 是一个自托管的、容器化的 SIEM 技术栈,由专门构建的微服务组成。每个服务具有单一职责,并通过定义好的 Redis streams 和 REST API 进行通信。整个技术栈通过 Docker Compose 运行,旨在部署在单台主机上(最低要求 4 GB RAM,2 vCPUs),并支持可选的多节点扩展。 **核心功能:** - 通过 UDP 514 端口实时从 UniFi 控制器和设备采集 syslog - 采用 ECS 标准化的日志解析,支持 GeoIP 丰富化与威胁情报查询 - 基于规则的告警,支持去重、限流和邮件推送 - 由 OpenSearch 支持的全文日志搜索 - 用于仪表板集成的 REST API 和实时 WebSocket 数据流 - 用于操作可视化的 Prometheus 指标和 Grafana 仪表板 - 基于 JWT 认证的多角色用户管理(admin / analyst / viewer) ## 架构 ``` ┌─────────────────────────────────────────────────────────────────────┐ │ UniFi Network │ │ Controller / APs / Switches / Gateways │ └───────────────────────────┬─────────────────────────────────────────┘ │ UDP 514 (syslog) ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ syslog-ingestion │ │ Receives raw syslog frames → publishes to Redis stream │ │ Stream: siem:raw_logs │ └───────────────────────────┬─────────────────────────────────────────┘ │ Redis XADD ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ parser-pipeline │ │ Reads siem:raw_logs (consumer group: siem-parsers) │ │ Normalises → ECS fields │ │ Enriches → GeoIP, threat-intel feeds │ │ Indexes → OpenSearch (siem-logs-YYYY.MM.DD) │ │ Publishes → siem:parsed_logs │ └──────────────┬────────────────────────────┬────────────────────────┘ │ Redis XADD │ HTTP bulk index ▼ ▼ ┌──────────────────────────┐ ┌──────────────────────────────────────┐ │ alerting-engine │ │ OpenSearch │ │ Reads siem:parsed_logs │ │ Indices: siem-logs-*, siem-alerts │ │ (group: siem-alerting) │ │ Full-text search + aggregations │ │ Evaluates alert rules │ └──────────────────┬───────────────────┘ │ Deduplicates via Redis │ │ REST /api/v1/ │ Stores → PostgreSQL │ │ │ Publishes alert events │ │ │ → siem:alert_notific. │ │ └────────┬─────────────────┘ │ │ Redis PUBLISH │ ▼ │ ┌──────────────────────────┐ │ │ email-notifier │ │ │ Subscribes to │ │ │ siem:alert_notifications│ │ │ Sends SMTP emails │ │ └──────────────────────────┘ │ │ ┌─────────────────────────────────────────────────▼───────────────────┐ │ siem-core (FastAPI) │ │ REST API prefix: /api/v1/ │ │ WebSocket: /ws/live (pub: siem:live_stream) │ │ Auth: JWT + API keys DB: PostgreSQL │ └───────────────────────────┬─────────────────────────────────────────┘ │ HTTP upstream ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ reverse-proxy (nginx) │ │ /api/ → siem-core:8000 /ws/ → siem-core:8000 │ │ /grafana/ → grafana:3000 / → dashboard-ui:3000 │ │ TLS termination (self-signed or Let's Encrypt) │ └──────────┬───────────────────────────────────────────────────────┬──┘ │ TCP 80 / 443 │ ▼ ▼ Browser (Dashboard) Grafana UI ``` ### 数据存储 | 存储 | 用途 | 默认端口 | |-------------|------------------------------------------|:------------:| | Redis | 日志流,发布/订阅,去重缓存 | 6379 | | PostgreSQL | 用户、会话、API 密钥、告警、审计 | 5432 | | OpenSearch | 日志索引 (siem-logs-*),告警索引 | 9200 | ### 监控技术栈 | 服务 | 角色 | 默认端口 | |------------|-----------------------------------|:------------:| | Prometheus | 从所有服务抓取 /metrics | 9090 | | Grafana | 通过 /grafana/ 提供仪表板 | 3000 (内部) | ## 前置条件 | 要求 | 最低配置 | 备注 | |---|---|---| | Docker Engine | 24.0+ | `docker --version` | | Docker Compose Plugin | v2.20+ | `docker compose version` | | RAM | 4 GB | 生产环境建议 8 GB | | CPU | 2 vCPUs | 建议 4+ | | 磁盘 | 20 GB | 用于日志、指标和备份 | | OS | Linux (amd64) | 建议 Ubuntu 22.04 LTS 或 Debian 12 | | `openssl` | 任意版本 | 生成密钥所需 | | `curl` / `bash` | 任意版本 | 运行脚本所需 | ## 快速开始 ### 1. 克隆代码库 ``` git clone https://github.com/your-org/unisoc-sentinel.git cd unisoc-sentinel ``` ### 2. 生成密钥 ``` bash scripts/generate-secrets.sh # 或 make generate-secrets ``` 这会创建 `./secrets/` 目录,其中包含: - `postgres_password` — PostgreSQL siem 用户密码 - `redis_password` — Redis 认证密码 - `opensearch_password` — OpenSearch admin 密码 - `smtp_password` — SMTP 认证(占位符,需手动修改) - `jwt_secret` — 64 字节 JWT 签名密钥 ### 3. 配置环境 ``` # .env 已由 generate-secrets.sh 从 .env.example 复制 # 编辑与你的部署相关的值: nano .env ``` 至少需要检查并调整以下内容: | 变量 | 需要执行的操作 | |---|---| | `DOMAIN` | 设置为服务器的 FQDN 或 IP | | `TLS_MODE` | `self-signed`(测试环境)或 `letsencrypt`(生产环境) | | `LETSENCRYPT_EMAIL` | 当 `TLS_MODE=letsencrypt` 时必填 | | `OPENSEARCH_INITIAL_ADMIN_PASSWORD` | 修改默认值 | | `SMTP_HOST`, `SMTP_USER`, `SMTP_PORT` | 用于邮件发送的设置 | | `ALERT_RECIPIENTS` | 以逗号分隔的通知接收者 | | `GRAFANA_ADMIN_PASSWORD` | 修改默认值 | ### 4. 构建并启动技术栈 ``` # 构建自定义镜像并启动所有服务: make build make up # 查看启动进度: make logs ``` 首次启动时,OpenSearch 最多可能需要 2 分钟才能变为健康状态。 ### 5. 验证技术栈 ``` make ps ``` 所有服务应显示为 `healthy` 或 `running`。然后打开: - 仪表板:`https:///` - Grafana:`https:///grafana/` - API 健康状态:`https:///api/v1/health` 默认管理员凭据:`admin` / `ChangeMe123!` **请立即通过仪表板或 API 修改此密码。** ## UniFi 配置 将你的 UniFi 设备指向运行 UniSOC Sentinel 的主机以发送 syslog。 ### UniFi Network Application (Controller) 1. 登录到 UniFi Network Application。 2. 导航至 **Settings → System → Advanced**。 3. 启用 **Remote Syslog Server**。 4. 将 **Server IP** 设置为 UniSOC Sentinel 主机的 IP 地址。 5. 将 **Port** 设置为 `514`。 6. 将 **Protocol** 设置为 `UDP`。 7. 点击 **Apply Changes**。 ### 旧版 UniFi Security Gateway (USG) 通过 SSH 登录 USG 并运行: ``` configure set system syslog host facility all level info commit save exit ``` ### UniFi Dream Machine (UDM / UDM-Pro / UDM-SE) 在 UniFi OS 设置中: 1. 导航至 **Console Settings → Notifications → Remote Syslog**。 2. 输入主机 IP 和端口 `514`。 ### 防火墙注意事项 确保 UniFi 设备与主机之间的 UDP 514 端口已开放: ``` # Linux 示例 (ufw): sudo ufw allow 514/udp comment "UniSOC Sentinel syslog" ``` ## 配置参考 所有配置均通过 `.env` 文件完成。有关每个变量的完整文档,请参阅 `.env.example`。 ### 关键变量 | 变量 | 默认值 | 描述 | |---|---|---| | `DOMAIN` | `localhost` | 用于 TLS 证书和 nginx 虚拟主机的公共 FQDN | | `TLS_MODE` | `self-signed` | 证书模式:`self-signed` 或 `letsencrypt` | | `OPENSEARCH_INITIAL_ADMIN_PASSWORD` | `ChangeMe_1234!` | OpenSearch admin 密码 | | `LOG_LEVEL` | `INFO` | Python 服务的全局日志详细级别 | | `CORS_ORIGINS` | `http://localhost,...` | API 允许的 CORS 源 | ### 扩展变量 | 变量 | 默认值 | 描述 | |---|---|---| | `SYSLOG_WORKERS` | `4` | syslog 采集服务中的异步 worker | | `SYSLOG_BUFFER_SIZE` | `10000` | 传入数据帧的内存队列深度 | | `PARSER_WORKERS` | `2` | 并发解析器协程 | | `PARSER_BATCH_SIZE` | `100` | Redis XREADGROUP 批量大小 | | `SIEM_CORE_WORKERS` | `4` | Uvicorn worker 进程 | ### 告警规则 告警规则定义在 `config/alert-rules/alert-rules.yml` 中。该文件以只读方式挂载到 `alerting-engine` 容器中。修改后,请重启告警引擎: ``` make restart SERVICE=alerting-engine ``` 有关完整的规则 schema,请参阅 `config/alert-rules/alert-rules.yml`。 ### 威胁情报源 订阅源配置位于 `config/threat-intel/feeds.yml`。解析器流水线会根据 `update_interval_hours` 自动刷新订阅源。 ## TLS 选项 ### 自签名(开发 / 实验) 在 `.env` 中设置 `TLS_MODE=self-signed`。`tls-manager` 服务会在首次启动时生成自签名证书,并将其存储在 `tls-certs` 卷中。浏览器会显示安全警告 —— 添加例外或信任该 CA。 ### Let's Encrypt(生产) 要求: - `DOMAIN` 必须公开解析为主机的 IP - 端口 `80` 必须可从互联网访问(用于 ACME HTTP-01 验证) - 在 `LETSENCRYPT_EMAIL` 中填写有效的电子邮箱地址 在 `.env` 中设置 `TLS_MODE=letsencrypt` 并启动技术栈。`tls-manager` 服务将自动获取并缓存证书。 证书续期由 `tls-manager` 服务在每次重启时处理。要手动触发续期: ``` docker compose restart tls-manager docker compose restart reverse-proxy ``` ## 备份与恢复 ### 创建备份 ``` make backup ``` 备份内容: - PostgreSQL 数据库(pg_dump,已压缩) - OpenSearch 数据卷 - Redis RDB 快照 备份文件将写入 `./backups/YYYY-MM-DD_HH-MM-SS/` 目录,并保留最近七次的备份(更早的备份将被自动删除)。 ### 计划自动备份 ``` # 每天 02:00 运行备份 0 2 * * * cd /opt/unisoc-sentinel && bash scripts/backup.sh >> /var/log/sentinel-backup.log 2>&1 ``` ### 从备份恢复 ``` bash scripts/restore.sh ./backups/2026-05-21_02-00-00 ``` 在覆盖任何数据之前,系统会提示您进行确认。 ## 监控 ### Prometheus Prometheus 配置为从每个服务抓取 `/metrics`。 配置文件:`services/monitoring/prometheus/prometheus.yml` 直接访问 Prometheus(仅限内部访问,不公开暴露): ``` docker compose exec prometheus wget -qO- http://localhost:9090/api/v1/targets ``` ### Grafana 通过 `https:///grafana/` 访问 Grafana。 默认凭据:通过 `GRAFANA_ADMIN_USER` / `GRAFANA_ADMIN_PASSWORD` 配置。 预构建的仪表板从 `services/monitoring/grafana/dashboards/` 加载。 数据源从 `services/monitoring/grafana/provisioning/` 配置。 ## 故障排除 ### 容器未启动 / 不健康 ``` # 查看特定服务的日志: make logs SERVICE=opensearch # 检查最后 100 行: docker compose logs --tail=100 opensearch ``` ### OpenSearch 变为健康状态的时间过长 首次启动时,OpenSearch 生成 TLS 证书并初始化集群可能需要 60–90 秒。在诊断之前,请等待 `start_period` 结束。检查日志: ``` make logs SERVICE=opensearch ``` 如果 `bootstrap.memory_lock` 失败,请增加主机的 `vm.max_map_count`: ``` sudo sysctl -w vm.max_map_count=262144 echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf ``` ### OpenSearch 中没有出现日志 1. 确认你的 UniFi 设备正在通过 UDP 514 向主机 IP 发送 syslog。 2. 验证 `syslog-ingestion` 是否健康:`make ps`。 3. 检查 Redis 连接情况:`make logs SERVICE=syslog-ingestion`。 4. 验证 `parser-pipeline` 是否正在消费:`make logs SERVICE=parser-pipeline`。 ### 告警未发送 1. 检查 `alerting-engine` 日志:`make logs SERVICE=alerting-engine`。 2. 检查 `email-notifier` 日志:`make logs SERVICE=email-notifier`。 3. 验证 SMTP 凭据:`cat secrets/smtp_password`。 4. 测试 SMTP 连接: ``` docker compose exec email-notifier python -c \ "import smtplib; s = smtplib.SMTP('$SMTP_HOST', $SMTP_PORT); print(s.ehlo())" ``` ### 重置一切并重新开始 ``` make reset # WARNING: destroys all data make generate-secrets make build make up ``` ## 安全说明 1. **密钥** — 所有密码和密钥都存储在 `./secrets/` 文件中,绝不会存储在环境变量或 docker-compose.yml 中。`secrets/` 目录已通过 `.gitignore` 排除在 git 之外。权限设置为 `600`。 2. **非 root 容器** — 所有自定义服务均以 UID 1000(或相应的服务 UID)运行。通过 `no-new-privileges:true` 阻止权限提升。 3. **只读文件系统** — 在可行的情况下,容器以 `read_only: true` 运行,并将可写的 `/tmp` 挂载为 tmpfs。 4. **丢弃 Capabilities** — 自定义服务会丢弃所有的 Linux capabilities,仅重新添加严格需要的权限(例如 syslog 监听 514 端口所需的 `NET_BIND_SERVICE`)。 5. **网络隔离** — 所有服务均在内部的 `siem-internal` Docker 网络上通信。只有 `reverse-proxy` 和 `grafana` 连接到面向公网的 `siem-public` 网络。 6. **默认密码** — 在连接到生产网络之前,请修改 `OPENSEARCH_INITIAL_ADMIN_PASSWORD`、`GRAFANA_ADMIN_PASSWORD` 以及默认的 `admin` 数据库用户密码 (`ChangeMe123!`)。 7. **TLS** — 在生产环境中使用 `TLS_MODE=letsencrypt`。自签名模式仅适用于内部实验环境。 8. **审计日志** — 所有的 API 操作都会连同用户身份、IP 地址和时间戳写入 PostgreSQL 的 `audit_log` 表中。
标签:Docker Compose, UniFi, 安全运营, 扫描框架, 搜索引擎查询, 测试用例, 版权保护, 网络安全, 网络测绘, 自定义请求头, 逆向工具, 隐私保护