From fc9d63026334f0f4b6f656b5152acc5e91b7fc8c Mon Sep 17 00:00:00 2001 From: PTah Date: Sat, 20 Jun 2026 19:02:58 +1000 Subject: [PATCH] docs: refresh README; allow monitor JWT for RDG qwinsta/logoff (0.20.6) Update platform docs for current features; Seaca and web operators with monitor role can trigger WinRM actions via SAC API. --- README.md | 87 +++++++---------------- README_en.md | 87 +++++++---------------- backend/app/api/v1/events.py | 10 +-- backend/app/services/rdg_winrm_actions.py | 16 +++-- backend/app/version.py | 2 +- docs/agent-control-plane.md | 37 +++++----- frontend/src/version.ts | 2 +- 7 files changed, 83 insertions(+), 158 deletions(-) diff --git a/README.md b/README.md index 1ad4a15..8d57ff0 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,50 @@ # Security Alert Center (SAC) -Центральная платформа сбора, хранения и отображения событий безопасности с Linux- и Windows-хостов. +Центральная платформа: приём событий от агентов, корреляция, UI, оповещения, управление хостами. **English:** [README_en.md](README_en.md) -## Агенты (отдельные репозитории) +## Репозитории | Репозиторий | Назначение | |-------------|------------| -| [ssh-monitor](https://git.kalinamall.ru/PapaTramp/ssh-monitor) | Linux: SSH, sudo, logind, брутфорс, баны IP | -| [RDP-login-monitor](https://git.kalinamall.ru/PapaTramp/RDP-login-monitor) | Windows: RDP/RDS, RD Gateway, WinRM, admin share C$/ADMIN$ | -| **security-alert-center** (этот репозиторий) | Ubuntu 24.04: API, БД, UI, оповещения | -| [seaca](https://git.kalinamall.ru/PapaTramp/seaca) | Android: мобильный клиент SAC, push (FCM) | +| [ssh-monitor](https://git.kalinamall.ru/PapaTramp/ssh-monitor) | Linux-агент | +| [RDP-login-monitor](https://git.kalinamall.ru/PapaTramp/RDP-login-monitor) | Windows-агент | +| **security-alert-center** | Сервер SAC (Ubuntu 24.04) | +| [seaca](https://git.kalinamall.ru/PapaTramp/seaca) | Android-клиент | -## Статус +**Версия:** `0.20.6` · **Деплой:** `sudo /opt/sac-deploy.sh` -**Версия:** `0.10.0` -**Стек:** FastAPI, PostgreSQL, Vue 3, JWT, SSE -**Деплой:** `sudo /opt/sac-deploy.sh` (см. `deploy/sac-deploy.sh`) +## Возможности -## Скриншоты UI - -| Обзор | События | Проблемы | -|-------|---------|----------| -| ![Обзор SAC](docs/screenshots/ui-overview.png) | ![События SAC](docs/screenshots/ui-events.png) | ![Проблемы SAC](docs/screenshots/ui-problems.png) | - -## Что мониторится - -События приходят от агентов по [контракту ingest](docs/agent-integration.md) (`type`, `severity`, `details`): - -- **Linux — [ssh-monitor](https://git.kalinamall.ru/PapaTramp/ssh-monitor):** SSH (успех/неудача), **sudo**, **systemd-logind**, брутфорс и баны IP (ipset), пороги без бана, ежедневный отчёт, heartbeat. -- **Windows — [RDP-login-monitor](https://git.kalinamall.ru/PapaTramp/RDP-login-monitor):** - - **RDP/RDS** (4624/4625); - - **RD Gateway** (302/303), **WinRM / PowerShell Remoting** (Enter-PSSession, ID 91); - - **админ-шары `C$` / `ADMIN$`** (Security **5140**, `smb.admin_share.access`); - - **RDS Shadow Control** (RCM 20506/20507/20510), блокировка учётки **4740**, ежедневный отчёт, heartbeat, **инвентаризация железа** (`agent.inventory`). -- **В SAC:** problems (корреляция), Telegram/email/webhook, лимит входа в UI, SSE-дашборд и live-обновление хостов, статус агентов по heartbeat, карточка хоста с железом. - -**Примеры типов:** `ssh.login.*`, `privilege.sudo.command`, `rdp.login.*`, `winrm.session.started`, `smb.admin_share.access`, `agent.heartbeat`, `agent.inventory`, `report.daily.*` — [полная таблица](docs/agent-integration.md#3-маппинг-уведомлений--типы-событий). - -## Возможности платформы - -- Роли `admin` / `monitor`, управление пользователями в UI, JWT с проверкой активности в БД -- События, хосты, problems, dashboard, отчёты, live SSE -- Оповещения: Telegram, email, webhook; правила problems и cooldown -- Защита SPA, `DELETE /hosts` только для admin, login rate limit, DOMPurify для `report_html` -- Страницы ошибок `401` / `403` / `404` / `429` -- Статистика системы в sidebar (CPU, RAM, диск, latency БД) +- **Ingest** событий от агентов ([контракт](docs/agent-integration.md)): SSH/sudo/logind, RDP/RDG/WinRM/SMB, heartbeat, отчёты, inventory +- **Problems** — автокорреляция (в т.ч. RDG 302→303 flap за 1–10 с) +- **Оповещения** — Telegram, email, webhook, FCM (Seaca); severity + cooldown +- **UI** — события, хосты, problems, отчёты, обзор (SSE live), настройки (admin) +- **RDG flap** — бейдж на событиях 302/303, **qwinsta/logoff** по WinRM на клиентский ПК (нужен domain admin в настройках) +- **Хосты** — статус агента, inventory, обновление ssh-monitor/RDP (SSH/WinRM), тест Git/SSH/WinRM +- **Мобильные** — enrollment, устройства, push; Seaca: ack/resolve, qwinsta/logoff через API SAC +- **Роли** — `admin` / `monitor`; JWT, rate limit входа ## Документация | Документ | Описание | |----------|----------| -| [docs/TZ.md](docs/TZ.md) | Техническое задание | -| [docs/architecture.md](docs/architecture.md) | Архитектура | -| [docs/agent-integration.md](docs/agent-integration.md) | Интеграция агентов, режим `UseSAC` | -| [docs/event-schema-v1.json](docs/event-schema-v1.json) | JSON Schema событий v1 | -| [docs/install-ubuntu-24.04-native.md](docs/install-ubuntu-24.04-native.md) | **Ubuntu 24.04 — native (основной)** | -| [docs/install-ubuntu-24.04-docker.md](docs/install-ubuntu-24.04-docker.md) | Ubuntu 24.04 — Docker | -| [docs/deployment.md](docs/deployment.md) | Развёртывание и эксплуатация | -| [docs/ssl-certificate.md](docs/ssl-certificate.md) | TLS-сертификат | -| [docs/runbook-ops.md](docs/runbook-ops.md) | Runbook эксплуатации | +| [docs/agent-integration.md](docs/agent-integration.md) | Агенты, `UseSAC`, типы событий | +| [docs/agent-control-plane.md](docs/agent-control-plane.md) | RDG flap, qwinsta, обновления агентов | +| [docs/install-ubuntu-24.04-native.md](docs/install-ubuntu-24.04-native.md) | Установка (native) | +| [docs/deployment.md](docs/deployment.md) | Эксплуатация | +| [docs/seaca-mobile.md](docs/seaca-mobile.md) | Мобильные устройства | -## Быстрый старт (native) +## Быстрый старт ```bash git clone https://git.kalinamall.ru/PapaTramp/security-alert-center.git /opt/security-alert-center -# deploy/env.native.example -> config/sac-api.env -cd /opt/security-alert-center/backend -python3 -m venv .venv && .venv/bin/pip install -r requirements.txt -.venv/bin/alembic upgrade head +# deploy/env.native.example → config/sac-api.env +cd /opt/security-alert-center/backend && python3 -m venv .venv +.venv/bin/pip install -r requirements.txt && .venv/bin/alembic upgrade head ``` -Полная инструкция: [docs/install-ubuntu-24.04-native.md](docs/install-ubuntu-24.04-native.md) - -## Целевая платформа - -- **Сервер SAC:** Ubuntu 24.04 LTS -- **Агенты:** ssh-monitor (Linux), RDP-login-monitor (Windows) - ## Лицензия -MIT — см. [LICENSE](LICENSE). -Copyright (c) 2026 Andrey «PapaTramp» Lutsenko. +MIT — [LICENSE](LICENSE). diff --git a/README_en.md b/README_en.md index 430646b..2dc5a42 100644 --- a/README_en.md +++ b/README_en.md @@ -1,88 +1,49 @@ # Security Alert Center (SAC) -Self-hosted hub for collecting, storing, and displaying security events from Linux and Windows hosts. +Self-hosted hub for security events from Linux and Windows agents: ingest, correlation, UI, notifications, host management. **Русский:** [README.md](README.md) -## Agents (separate repositories) +## Repositories | Repository | Role | |------------|------| -| [ssh-monitor](https://git.kalinamall.ru/PapaTramp/ssh-monitor) | Linux: SSH, sudo, logind, brute-force, IP ban | -| [RDP-login-monitor](https://git.kalinamall.ru/PapaTramp/RDP-login-monitor) | Windows: RDP/RDS, RD Gateway, WinRM, admin share C$/ADMIN$ | -| **security-alert-center** (this repo) | Ubuntu 24.04: API, database, UI, notifications | +| [ssh-monitor](https://git.kalinamall.ru/PapaTramp/ssh-monitor) | Linux agent | +| [RDP-login-monitor](https://git.kalinamall.ru/PapaTramp/RDP-login-monitor) | Windows agent | +| **security-alert-center** | SAC server (Ubuntu 24.04) | +| [seaca](https://git.kalinamall.ru/PapaTramp/seaca) | Android client | -## Status +**Version:** `0.20.6` · **Deploy:** `sudo /opt/sac-deploy.sh` -**Version:** `0.10.0` -**Stack:** FastAPI, PostgreSQL, Vue 3, JWT, SSE -**Deploy:** `sudo /opt/sac-deploy.sh` (see `deploy/sac-deploy.sh`) +## Features -## UI screenshots - -| Overview | Events | Problems | -|----------|--------|----------| -| ![SAC dashboard](docs/screenshots/ui-overview.png) | ![SAC events](docs/screenshots/ui-events.png) | ![SAC problems](docs/screenshots/ui-problems.png) | - -## What is monitored - -Agents send events via the [ingest contract](docs/agent-integration.md) (`type`, `severity`, `details`): - -- **Linux — [ssh-monitor](https://git.kalinamall.ru/PapaTramp/ssh-monitor):** SSH success/failure, **sudo**, **systemd-logind**, brute-force and IP ban (ipset), thresholds without ban, daily report, heartbeat. -- **Windows — [RDP-login-monitor](https://git.kalinamall.ru/PapaTramp/RDP-login-monitor):** - - **RDP/RDS** (4624/4625); - - **RD Gateway** (302/303), **WinRM / PowerShell Remoting** (Enter-PSSession, event ID 91); - - **admin shares `C$` / `ADMIN$`** (Security **5140**, `smb.admin_share.access`); - - **RDS Shadow Control** (RCM 20506/20507/20510), account lockout **4740**, daily report, heartbeat, **hardware inventory** (`agent.inventory`). -- **SAC platform:** problems (correlation), Telegram/email/webhook, UI login rate limit, SSE dashboard and live host updates, agent online/stale by heartbeat, host detail with hardware snapshot. - -**Event type examples:** `ssh.login.*`, `privilege.sudo.command`, `rdp.login.*`, `winrm.session.started`, `smb.admin_share.access`, `agent.heartbeat`, `agent.inventory`, `report.daily.*` — [full mapping](docs/agent-integration.md#3-маппинг-уведомлений--типы-событий). - -## Platform features - -- Roles `admin` / `monitor`, user management in UI, JWT validated against DB -- Events, hosts, problems, dashboard, reports, live SSE -- Notifications: Telegram, email, webhook; problem rules and cooldowns -- SPA hardening, admin-only `DELETE /hosts`, login rate limit, DOMPurify for `report_html` -- Custom error pages: `401` / `403` / `404` / `429` -- Sidebar system stats (CPU, RAM, disk, DB latency) +- **Ingest** from agents ([contract](docs/agent-integration.md)): SSH/sudo/logind, RDP/RDG/WinRM/SMB, heartbeat, reports, inventory +- **Problems** — auto-correlation (incl. RDG 302→303 flap within 1–10 s) +- **Notifications** — Telegram, email, webhook, FCM (Seaca) +- **Web UI** — events, hosts, problems, reports, dashboard (SSE), settings (admin) +- **RDG flap** — badge on 302/303 events, **qwinsta/logoff** via WinRM to client PC (domain admin required) +- **Hosts** — agent status, inventory, agent updates (SSH/WinRM), connectivity tests +- **Mobile** — enrollment, devices, push; Seaca: ack/resolve, qwinsta/logoff via SAC API +- **Roles** — `admin` / `monitor` ## Documentation | Document | Description | |----------|-------------| -| [docs/TZ.md](docs/TZ.md) | Technical specification (Russian) | -| [docs/architecture.md](docs/architecture.md) | Architecture | -| [docs/agent-integration.md](docs/agent-integration.md) | Agent integration (`UseSAC` modes) | -| [docs/event-schema-v1.json](docs/event-schema-v1.json) | Event JSON Schema v1 | -| [docs/install-ubuntu-24.04-native.md](docs/install-ubuntu-24.04-native.md) | **Ubuntu 24.04 native install** | -| [docs/install-ubuntu-24.04-docker.md](docs/install-ubuntu-24.04-docker.md) | Docker alternative | -| [docs/deployment.md](docs/deployment.md) | Deployment and operations | -| [docs/ssl-certificate.md](docs/ssl-certificate.md) | TLS certificate setup | -| [docs/runbook-ops.md](docs/runbook-ops.md) | Operations runbook | +| [docs/agent-integration.md](docs/agent-integration.md) | Agents, `UseSAC`, event types | +| [docs/agent-control-plane.md](docs/agent-control-plane.md) | RDG flap, qwinsta, agent updates | +| [docs/install-ubuntu-24.04-native.md](docs/install-ubuntu-24.04-native.md) | Native install | +| [docs/deployment.md](docs/deployment.md) | Operations | -## Quick start (native) +## Quick start ```bash git clone https://git.kalinamall.ru/PapaTramp/security-alert-center.git /opt/security-alert-center # deploy/env.native.example -> config/sac-api.env -cd /opt/security-alert-center/backend -python3 -m venv .venv && .venv/bin/pip install -r requirements.txt -.venv/bin/alembic upgrade head +cd /opt/security-alert-center/backend && python3 -m venv .venv +.venv/bin/pip install -r requirements.txt && .venv/bin/alembic upgrade head ``` -Full guide: [docs/install-ubuntu-24.04-native.md](docs/install-ubuntu-24.04-native.md) - -## Target platform - -- **SAC server:** Ubuntu 24.04 LTS -- **Agents:** ssh-monitor (Linux), RDP-login-monitor (Windows) - -## GitHub topics - -`security-monitoring`, `siem`, `incident-response`, `fastapi`, `vue`, `postgresql`, `telegram-bot`, `webhook`, `jwt`, `rbac`, `self-hosted` - ## License -MIT — see [LICENSE](LICENSE). -Copyright (c) 2026 Andrey "PapaTramp" Lutsenko. +MIT — [LICENSE](LICENSE). diff --git a/backend/app/api/v1/events.py b/backend/app/api/v1/events.py index 6119025..00b74a3 100644 --- a/backend/app/api/v1/events.py +++ b/backend/app/api/v1/events.py @@ -9,7 +9,7 @@ from sqlalchemy import func, select from sqlalchemy.orm import Session, joinedload from app.auth.api_key import get_api_key_auth -from app.auth.jwt_auth import get_current_user, require_admin +from app.auth.jwt_auth import get_current_user, CurrentUser from app.config import get_settings from app.database import get_db from app.models import Event, Host @@ -212,12 +212,12 @@ class LogoffActionBody(BaseModel): def post_event_qwinsta( event_db_id: int, db: Session = Depends(get_db), - user=Depends(require_admin), + user: CurrentUser = Depends(get_current_user), ) -> AgentCommandResponse: event = db.get(Event, event_db_id) if event is None: raise HTTPException(status_code=404, detail="Event not found") - cmd = execute_qwinsta_via_winrm(db, event, requested_by=str(user)) + cmd = execute_qwinsta_via_winrm(db, event, requested_by=user.username) db.commit() return _agent_command_response(cmd) @@ -227,7 +227,7 @@ def post_event_logoff( event_db_id: int, body: LogoffActionBody, db: Session = Depends(get_db), - user=Depends(require_admin), + user: CurrentUser = Depends(get_current_user), ) -> AgentCommandResponse: event = db.get(Event, event_db_id) if event is None: @@ -236,7 +236,7 @@ def post_event_logoff( db, event, session_id=body.session_id, - requested_by=str(user), + requested_by=user.username, ) db.commit() return _agent_command_response(cmd) diff --git a/backend/app/services/rdg_winrm_actions.py b/backend/app/services/rdg_winrm_actions.py index e76f11e..44ef254 100644 --- a/backend/app/services/rdg_winrm_actions.py +++ b/backend/app/services/rdg_winrm_actions.py @@ -10,7 +10,7 @@ from sqlalchemy.orm import Session from app.models import AgentCommand, Event, Host from app.services.rdg_client_host import ClientWorkstationNotFoundError, resolve_client_workstation -from app.services.rdg_session_flap import event_has_rdg_flap, event_internal_ip +from app.services.rdg_session_flap import event_has_rdg_flap, event_internal_ip, resolve_rdg_flap_summary from app.services.win_admin_settings import get_effective_win_admin_config from app.services.winrm_connect import ( WinRmCmdResult, @@ -30,9 +30,13 @@ def _require_win_admin(db: Session): return cfg -def _require_rdg_flap(event: Event) -> None: - if not event_has_rdg_flap(event): - raise HTTPException(status_code=400, detail="Event is not flagged as RDG session flap") +def _require_rdg_flap(db: Session, event: Event) -> None: + flap, _, qwinsta_id = resolve_rdg_flap_summary(db, event) + if flap and qwinsta_id == event.id: + return + if event_has_rdg_flap(event): + return + raise HTTPException(status_code=400, detail="Event is not flagged as RDG session flap") def _resolve_client(db: Session, event: Event) -> Host: @@ -87,7 +91,7 @@ def _persist_command( def execute_qwinsta_via_winrm(db: Session, event: Event, *, requested_by: str) -> AgentCommand: - _require_rdg_flap(event) + _require_rdg_flap(db, event) cfg = _require_win_admin(db) client_host = _resolve_client(db, event) @@ -130,7 +134,7 @@ def execute_logoff_via_winrm( session_id: int, requested_by: str, ) -> AgentCommand: - _require_rdg_flap(event) + _require_rdg_flap(db, event) cfg = _require_win_admin(db) client_host = _resolve_client(db, event) diff --git a/backend/app/version.py b/backend/app/version.py index 8512034..2b4e730 100644 --- a/backend/app/version.py +++ b/backend/app/version.py @@ -1,5 +1,5 @@ """Единый источник версии SAC (API, health, логи, OpenAPI).""" APP_NAME = "Security Alert Center" -APP_VERSION = "0.20.5" +APP_VERSION = "0.20.6" APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}" diff --git a/docs/agent-control-plane.md b/docs/agent-control-plane.md index 1bf8d8e..f286897 100644 --- a/docs/agent-control-plane.md +++ b/docs/agent-control-plane.md @@ -100,25 +100,20 @@ THEN: **Маршрутизация команды qwinsta:** команда уходит на хост, где **установлен агент** и куда привязано событие (`host_id`). Если session host ≠ gateway, в перспективе — таблица «gateway → session hosts» или агент на session host; MVP — агент на том же сервере, что шлёт события RDG. -### 3.3. UI — «Обзор» → «Последние события» +### 3.3. UI — веб и Seaca -В таблице [DashboardView](../frontend/src/views/DashboardView.vue) для строки события с `rdg_flap = true` (обычно **303**, второе в паре): +Бейдж **RDG flap** и кнопка **qwinsta** на событиях **302 и 303** (пара вычисляется при чтении): -| … | Title | **Действия** | -|---|-------|--------------| -| … | RD Gateway event 303 | **[qwinsta]** | +- Веб: **Обзор**, **События**, карточка события +- **Seaca:** список событий + карточка → `POST .../actions/qwinsta` / `logoff` **Поток:** 1. Оператор нажимает **qwinsta**. -2. `POST /api/v1/events/{id}/actions/qwinsta` → SAC ставит команду в очередь хоста. -3. Агент на poll выполняет `qwinsta` под **доменным admin** (см. §5). -4. Результат → модальное окно: таблица SESSIONNAME, USERNAME, ID, STATE. -5. **logoff:** - - по умолчанию — кнопка только у строк с **matching user** из события; - - дополнительно — возможность **выбрать любую строку** (на серверах бывает нестандартный вывод qwinsta). -6. `POST .../actions/logoff { session_id }` → подтверждение → команда агенту → `logoff {id} /v`. -7. Результат в модалке; Problem можно auto-resolve или оставить оператору. +2. `POST /api/v1/events/{id}/actions/qwinsta` → SAC выполняет **WinRM qwinsta** на **клиентский ПК** (`internal_ip` из события). +3. Результат — модалка: SESSION, USER, ID, STATE. +4. **logoff:** `POST .../actions/logoff { session_id }` → WinRM `logoff` → повторный qwinsta. +5. Нужен **Windows domain admin** в настройках SAC (`SAC_WIN_ADMIN_*` или UI). ```mermaid sequenceDiagram @@ -257,13 +252,13 @@ Authorization: Bearer sac_xxx } ``` -### 7.2. UI actions (JWT admin) +### 7.2. UI actions (JWT: admin / monitor / mobile) | Метод | Путь | Назначение | |-------|------|------------| -| POST | `/api/v1/events/{id}/actions/qwinsta` | Запрос qwinsta | +| POST | `/api/v1/events/{id}/actions/qwinsta` | qwinsta (WinRM на клиентский ПК) | | POST | `/api/v1/events/{id}/actions/logoff` | logoff `{ "session_id": 5 }` | -| GET | `/api/v1/events/{id}/actions/{cmd_id}` | Статус / результат команды | +| GET | `/api/v1/events/{id}/actions/{cmd_id}` | Статус / результат | | PATCH | `/api/v1/hosts/{id}/config` | Desired config | | PATCH | `/api/v1/hosts/{id}/access` | Bootstrap / WinRM creds | | GET/PATCH | `/api/v1/settings/agent-updates` | Режим A/B, версии, источники | @@ -285,10 +280,10 @@ Authorization: Bearer sac_xxx | Фаза | Содержание | Статус | |------|------------|--------| | **1** | `rule:rdg_session_flap`, Problem, notify, флаг `rdg_flap` | ✅ SAC | -| **2** | Кнопка **qwinsta** на «Обзоре» | ✅ SAC UI | -| **3** | Poll API, `agent_commands`, env admin | ✅ SAC; ✅ RDP ≥ 2.1.0-SAC | -| **4** | logoff в модалке | ✅ SAC UI | -| **5** | Settings «Обновления агентов» | ⏳ | +| **2** | **qwinsta** / **logoff** — веб + Seaca | ✅ | +| **3** | Poll API, `agent_commands` (агент) | ✅ RDP ≥ 2.1.0-SAC | +| **4** | WinRM qwinsta с сервера SAC | ✅ | +| **5** | Settings «Обновления агентов», SSH bootstrap | частично ✅ | | **6** | Self-update B1 | ⏳ | | **7** | SSH bootstrap + WinRM fallback | ⏳ | | **8** | Desired config per host | ⏳ | @@ -299,7 +294,7 @@ Authorization: Bearer sac_xxx ## 9. Безопасность -- Команды qwinsta/logoff — только **JWT admin**; audit log. +- Команды qwinsta/logoff — JWT (веб и Seaca); `requested_by` в `agent_commands`. - Rate limit на actions per host. - logoff — confirm dialog; по умолчанию только matching user. - Password bootstrap Linux — удаляется после успеха; re-bootstrap явной кнопкой. diff --git a/frontend/src/version.ts b/frontend/src/version.ts index 65cd5cb..0f62e59 100644 --- a/frontend/src/version.ts +++ b/frontend/src/version.ts @@ -1,4 +1,4 @@ /** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */ export const APP_NAME = "Security Alert Center"; -export const APP_VERSION = "0.20.5"; +export const APP_VERSION = "0.20.6"; export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;