From 6bff0731086e692494fbc18e5238ffef183e6a5c Mon Sep 17 00:00:00 2001 From: PTah Date: Tue, 16 Jun 2026 11:41:07 +1000 Subject: [PATCH 1/3] chore(docs): sync repository URLs for kalinamall mirror --- README.md | 12 ++++++------ README_en.md | 10 +++++----- deploy/systemd/sac-api.service | 2 +- docs/event-schema-v1.json | 2 +- docs/install-ubuntu-24.04-docker.md | 2 +- docs/install-ubuntu-24.04-native.md | 2 +- docs/install-ubuntu-24.04.md | 2 +- docs/operations-prod-status.md | 2 +- docs/roadmap.md | 6 +++--- docs/seaca-mobile.md | 4 ++-- docs/workspace-three-repos.md | 14 +++++++------- schemas/event-schema-v1.json | 2 +- scripts/Rewrite-GitHostUrls.ps1 | 12 ++++++------ scripts/rewrite-git-host-urls.sh | 12 ++++++------ 14 files changed, 42 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index ebe1c92..9a7f46e 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ | Репозиторий | Назначение | |-------------|------------| -| [ssh-monitor](https://github.com/PTah/ssh-monitor) | Linux: SSH, sudo, logind, брутфорс, баны IP | -| [RDP-login-monitor](https://github.com/PTah/RDP-login-monitor) | Windows: RDP/RDS, RD Gateway, WinRM, admin share C$/ADMIN$ | +| [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://github.com/PTah/seaca) | Android: мобильный клиент SAC, push (FCM) | +| [seaca](https://git.kalinamall.ru/PapaTramp/seaca) | Android: мобильный клиент SAC, push (FCM) | ## Статус @@ -29,8 +29,8 @@ События приходят от агентов по [контракту ingest](docs/agent-integration.md) (`type`, `severity`, `details`): -- **Linux — [ssh-monitor](https://github.com/PTah/ssh-monitor):** SSH (успех/неудача), **sudo**, **systemd-logind**, брутфорс и баны IP (ipset), пороги без бана, ежедневный отчёт, heartbeat. -- **Windows — [RDP-login-monitor](https://github.com/PTah/RDP-login-monitor):** +- **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`); @@ -65,7 +65,7 @@ ## Быстрый старт (native) ```bash -git clone https://github.com/PTah/security-alert-center.git /opt/security-alert-center +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 diff --git a/README_en.md b/README_en.md index b3b0a4b..735fe20 100644 --- a/README_en.md +++ b/README_en.md @@ -8,8 +8,8 @@ Self-hosted hub for collecting, storing, and displaying security events from Lin | Repository | Role | |------------|------| -| [ssh-monitor](https://github.com/PTah/ssh-monitor) | Linux: SSH, sudo, logind, brute-force, IP ban | -| [RDP-login-monitor](https://github.com/PTah/RDP-login-monitor) | Windows: RDP/RDS, RD Gateway, WinRM, admin share C$/ADMIN$ | +| [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 | ## Status @@ -28,8 +28,8 @@ Self-hosted hub for collecting, storing, and displaying security events from Lin Agents send events via the [ingest contract](docs/agent-integration.md) (`type`, `severity`, `details`): -- **Linux — [ssh-monitor](https://github.com/PTah/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://github.com/PTah/RDP-login-monitor):** +- **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`); @@ -64,7 +64,7 @@ Agents send events via the [ingest contract](docs/agent-integration.md) (`type`, ## Quick start (native) ```bash -git clone https://github.com/PTah/security-alert-center.git /opt/security-alert-center +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 diff --git a/deploy/systemd/sac-api.service b/deploy/systemd/sac-api.service index 1aeddb3..6920d4c 100644 --- a/deploy/systemd/sac-api.service +++ b/deploy/systemd/sac-api.service @@ -1,6 +1,6 @@ [Unit] Description=Security Alert Center API (FastAPI) -Documentation=https://github.com/PTah/security-alert-center +Documentation=https://git.kalinamall.ru/PapaTramp/security-alert-center After=network-online.target postgresql.service Wants=network-online.target Requires=postgresql.service diff --git a/docs/event-schema-v1.json b/docs/event-schema-v1.json index 4b28de8..c867a07 100644 --- a/docs/event-schema-v1.json +++ b/docs/event-schema-v1.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/PTah/security-alert-center/schemas/event-v1.json", + "$id": "https://git.kalinamall.ru/PapaTramp/security-alert-center/schemas/event-v1.json", "title": "Security Alert Center Event v1", "description": "Каноническое событие от ssh-monitor или RDP-login-monitor", "type": "object", diff --git a/docs/install-ubuntu-24.04-docker.md b/docs/install-ubuntu-24.04-docker.md index 63bc24b..c2900d2 100644 --- a/docs/install-ubuntu-24.04-docker.md +++ b/docs/install-ubuntu-24.04-docker.md @@ -24,7 +24,7 @@ Docker удобен для локальной отладки или изолир ```bash sudo apt install -y git -sudo git clone https://github.com/PTah/security-alert-center.git /opt/security-alert-center +sudo git clone https://git.kalinamall.ru/PapaTramp/security-alert-center.git /opt/security-alert-center sudo chown -R "$USER:$USER" /opt/security-alert-center ``` diff --git a/docs/install-ubuntu-24.04-native.md b/docs/install-ubuntu-24.04-native.md index 3509917..a757816 100644 --- a/docs/install-ubuntu-24.04-native.md +++ b/docs/install-ubuntu-24.04-native.md @@ -71,7 +71,7 @@ nginx -v ```bash sudo mkdir -p /opt -sudo git clone https://github.com/PTah/security-alert-center.git /opt/security-alert-center +sudo git clone https://git.kalinamall.ru/PapaTramp/security-alert-center.git /opt/security-alert-center ``` --- diff --git a/docs/install-ubuntu-24.04.md b/docs/install-ubuntu-24.04.md index 6dcb39e..23a7bcb 100644 --- a/docs/install-ubuntu-24.04.md +++ b/docs/install-ubuntu-24.04.md @@ -14,7 +14,7 @@ ```bash # см. полный чеклист в native-руководстве sudo apt update && sudo apt install -y git postgresql nginx python3.12 python3.12-venv -sudo git clone https://github.com/PTah/security-alert-center.git /opt/security-alert-center +sudo git clone https://git.kalinamall.ru/PapaTramp/security-alert-center.git /opt/security-alert-center # … PostgreSQL, venv, config/sac-api.env, systemd, nginx ``` diff --git a/docs/operations-prod-status.md b/docs/operations-prod-status.md index 592ebe2..35b2893 100644 --- a/docs/operations-prod-status.md +++ b/docs/operations-prod-status.md @@ -39,7 +39,7 @@ sudo /opt/sac-deploy.sh | Параметр | Значение | |----------|----------| | Хост | `ubabuba` / `10.10.36.9` | -| Репозиторий | `github.com/PTah/ssh-monitor` (`main`, есть `sac-client.sh`) | +| Репозиторий | `git.kalinamall.ru/PapaTramp/ssh-monitor` (`main`, есть `sac-client.sh`) | | `UseSAC` | пилот **exclusive** — см. [pilot-2.1-exclusive.md](pilot-2.1-exclusive.md) | | Сервис | `ssh-monitor.service` — **active** | | `--check-sac` | OK (health + ingest `agent.test` 202) | diff --git a/docs/roadmap.md b/docs/roadmap.md index 9b68067..9a9b047 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -66,7 +66,7 @@ **Цель:** нативный Android-клиент и push по тем же правилам оповещений, что Telegram/email/webhook. -Репозиторий клиента: [seaca](https://github.com/PTah/seaca) (Kotlin, Jetpack Compose, FCM). +Репозиторий клиента: [seaca](https://git.kalinamall.ru/PapaTramp/seaca) (Kotlin, Jetpack Compose, FCM). **Сервер SAC:** @@ -77,7 +77,7 @@ **Не в мобильном клиенте:** пользователи SAC, каналы Telegram/SMTP/webhook, админ-настройки. -Подробный план клиента — [seaca/docs/ROADMAP.md](https://github.com/PTah/seaca/blob/main/docs/ROADMAP.md). +Подробный план клиента — [seaca/docs/ROADMAP.md](https://git.kalinamall.ru/PapaTramp/seaca/src/branch/main/docs/ROADMAP.md). --- @@ -95,7 +95,7 @@ | v0.1 | — (не требуется) | — | | v0.2 | TBD (тег с UseSAC) | TBD | | v0.3+ | совместимость schema 1.0 | совместимость schema 1.0 | -| v0.6 | — | — (мобильный клиент [seaca](https://github.com/PTah/seaca), не агент) | +| v0.6 | — | — (мобильный клиент [seaca](https://git.kalinamall.ru/PapaTramp/seaca), не агент) | При breaking change схемы — `schema_version: 1.1` с поддержкой 1.0 на ingest. diff --git a/docs/seaca-mobile.md b/docs/seaca-mobile.md index 3020a46..33bbc6c 100644 --- a/docs/seaca-mobile.md +++ b/docs/seaca-mobile.md @@ -1,6 +1,6 @@ # Seaca — мобильный клиент SAC -Репозиторий приложения: [seaca](https://github.com/PTah/seaca). +Репозиторий приложения: [seaca](https://git.kalinamall.ru/PapaTramp/seaca). Требуется SAC **≥ 0.9.0** с применённой миграцией `014`. --- @@ -84,7 +84,7 @@ SAC_FCM_SERVICE_ACCOUNT_JSON=/etc/security-alert-center/fcm-service-account.json | `sac.kalinamall.ru` | Web UI | yes (`git-sac-allowed`) | | `sac-api.kalinamall.ru` | Seaca, `/api/v1/mobile/*` | no (enroll + JWT) | -Both resolve to the same SAC server (**192.168.160.145**). nginx must accept both names in `server_name`. See [reverse-proxy/docs/sac-access.md](https://github.com/PTah/reverse-proxy/blob/main/docs/sac-access.md). +Both resolve to the same SAC server (**192.168.160.145**). nginx must accept both names in `server_name`. See [reverse-proxy/docs/sac-access.md](https://git.kalinamall.ru/PapaTramp/reverse-proxy/src/branch/main/docs/sac-access.md). --- diff --git a/docs/workspace-three-repos.md b/docs/workspace-three-repos.md index c4f2ad6..bfe252b 100644 --- a/docs/workspace-three-repos.md +++ b/docs/workspace-three-repos.md @@ -8,9 +8,9 @@ | Имя в workspace | Путь (пример Windows) | Публичный remote | |-----------------|----------------------|------------------| -| `ssh-monitor` | `D:\Soft\Git\ssh-monitor` | github.com/PTah/ssh-monitor | -| `rdp-monitor` | `D:\Soft\Git\RDP-login-monitor` | github.com/PTah/RDP-login-monitor | -| `security-alert-center` | `D:\Soft\Git\security-alert-center` | github.com/PTah/security-alert-center | +| `ssh-monitor` | `D:\Soft\Git\ssh-monitor` | git.kalinamall.ru/PapaTramp/ssh-monitor | +| `rdp-monitor` | `D:\Soft\Git\RDP-login-monitor` | git.kalinamall.ru/PapaTramp/RDP-login-monitor | +| `security-alert-center` | `D:\Soft\Git\security-alert-center` | git.kalinamall.ru/PapaTramp/security-alert-center | Пути подставьте свои. Закрытый инстанс **git.kalinamall.ru** — зеркало с теми же репозиториями; ссылки в документации на каждом хосте должны вести **на этот же хост** (см. ниже). @@ -55,7 +55,7 @@ ### 4.1. Git: зеркала и ссылки в документации -В **main** ссылки между репозиториями указывают на **GitHub** (`https://github.com/PTah/...`). +В **main** ссылки между репозиториями указывают на **GitHub** (`https://git.kalinamall.ru/PapaTramp/...`). Перед push на другой хост (kalinamall, papatramp) используйте скрипт зеркалирования — он подменяет URL в docs, пушит и **не оставляет** чужие ссылки в локальной ветке: @@ -82,9 +82,9 @@ git push github main | Проект | URL | |--------|-----| -| security-alert-center | `https://github.com/PTah/security-alert-center.git` | -| ssh-monitor | `https://github.com/PTah/ssh-monitor.git` | -| RDP-login-monitor | `https://github.com/PTah/RDP-login-monitor.git` | +| security-alert-center | `https://git.kalinamall.ru/PapaTramp/security-alert-center.git` | +| ssh-monitor | `https://git.kalinamall.ru/PapaTramp/ssh-monitor.git` | +| RDP-login-monitor | `https://git.kalinamall.ru/PapaTramp/RDP-login-monitor.git` | --- diff --git a/schemas/event-schema-v1.json b/schemas/event-schema-v1.json index f22278c..d2b779d 100644 --- a/schemas/event-schema-v1.json +++ b/schemas/event-schema-v1.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/PTah/security-alert-center/schemas/event-v1.json", + "$id": "https://git.kalinamall.ru/PapaTramp/security-alert-center/schemas/event-v1.json", "title": "Security Alert Center Event v1", "description": "Каноническое событие от ssh-monitor или RDP-login-monitor", "type": "object", diff --git a/scripts/Rewrite-GitHostUrls.ps1 b/scripts/Rewrite-GitHostUrls.ps1 index 87a40f5..bbd8952 100644 --- a/scripts/Rewrite-GitHostUrls.ps1 +++ b/scripts/Rewrite-GitHostUrls.ps1 @@ -28,15 +28,15 @@ switch ($Target) { $BaseHost = $Base -replace '^https://', '' $patterns = @( - @{ From = 'https://github.com/PTah/([^)/''"\s]+)/blob/main/'; To = "$Base/`$1$BlobSuffix/" } + @{ From = 'https://git.kalinamall.ru/PapaTramp/([^)/''"\s]+)/blob/main/'; To = "$Base/`$1$BlobSuffix/" } + @{ From = 'https://git.kalinamall.ru/PapaTramp/([^)/''"\s]+)/src/branch/main/'; To = "$Base/`$1$BlobSuffix/" } @{ From = 'https://git.kalinamall.ru/PapaTramp/([^)/''"\s]+)/src/branch/main/'; To = "$Base/`$1$BlobSuffix/" } - @{ From = 'https://git.papatramp.ru/PTah/([^)/''"\s]+)/src/branch/main/'; To = "$Base/`$1$BlobSuffix/" } - @{ From = 'https://github.com/PTah/'; To = "$Base/" } @{ From = 'https://git.kalinamall.ru/PapaTramp/'; To = "$Base/" } - @{ From = 'https://git.papatramp.ru/PTah/'; To = "$Base/" } - @{ From = 'github.com/PTah/'; To = "$BaseHost/" } + @{ From = 'https://git.kalinamall.ru/PapaTramp/'; To = "$Base/" } + @{ From = 'https://git.kalinamall.ru/PapaTramp/'; To = "$Base/" } + @{ From = 'git.kalinamall.ru/PapaTramp/'; To = "$BaseHost/" } + @{ From = 'git.kalinamall.ru/PapaTramp/'; To = "$BaseHost/" } @{ From = 'git.kalinamall.ru/PapaTramp/'; To = "$BaseHost/" } - @{ From = 'git.papatramp.ru/PTah/'; To = "$BaseHost/" } ) $extensions = @('*.md', '*.json', '*.service', '*.example', '*.sh', '*.ps1', '*.yml', '*.yaml') diff --git a/scripts/rewrite-git-host-urls.sh b/scripts/rewrite-git-host-urls.sh index 38c4dfe..a0b76a0 100644 --- a/scripts/rewrite-git-host-urls.sh +++ b/scripts/rewrite-git-host-urls.sh @@ -28,15 +28,15 @@ esac # Order matters: longer patterns first. PATTERNS=( - 's|https://github.com/PTah/\([^)/"'"'"' ]*\)/blob/main/|'"${BASE}"'/\1'"${BLOB_SUFFIX}"'/|g' + 's|https://git.kalinamall.ru/PapaTramp/\([^)/"'"'"' ]*\)/blob/main/|'"${BASE}"'/\1'"${BLOB_SUFFIX}"'/|g' + 's|https://git.kalinamall.ru/PapaTramp/\([^)/"'"'"' ]*\)/src/branch/main/|'"${BASE}"'/\1'"${BLOB_SUFFIX}"'/|g' 's|https://git.kalinamall.ru/PapaTramp/\([^)/"'"'"' ]*\)/src/branch/main/|'"${BASE}"'/\1'"${BLOB_SUFFIX}"'/|g' - 's|https://git.papatramp.ru/PTah/\([^)/"'"'"' ]*\)/src/branch/main/|'"${BASE}"'/\1'"${BLOB_SUFFIX}"'/|g' - 's|https://github.com/PTah/|'"${BASE}"'/|g' 's|https://git.kalinamall.ru/PapaTramp/|'"${BASE}"'/|g' - 's|https://git.papatramp.ru/PTah/|'"${BASE}"'/|g' - 's|github.com/PTah/|'"${BASE#https://}"'/|g' + 's|https://git.kalinamall.ru/PapaTramp/|'"${BASE}"'/|g' + 's|https://git.kalinamall.ru/PapaTramp/|'"${BASE}"'/|g' + 's|git.kalinamall.ru/PapaTramp/|'"${BASE#https://}"'/|g' + 's|git.kalinamall.ru/PapaTramp/|'"${BASE#https://}"'/|g' 's|git.kalinamall.ru/PapaTramp/|'"${BASE#https://}"'/|g' - 's|git.papatramp.ru/PTah/|'"${BASE#https://}"'/|g' ) FILES=() From 2069e57f14a6e6b02eb23a4c1ced590bb43bdf68 Mon Sep 17 00:00:00 2001 From: PTah Date: Wed, 17 Jun 2026 11:07:12 +1000 Subject: [PATCH 2/3] docs: backlog for agent version compliance and remote updates Add agent-update-backlog.md and roadmap v0.7 outline for SAC-driven agent version tracking and remote update initiation. Co-authored-by: Cursor --- docs/INDEX.md | 1 + docs/agent-update-backlog.md | 58 ++++++++++++++++++++++++++++++++++++ docs/roadmap.md | 14 +++++++++ docs/todo-2026-05-29.md | 1 + 4 files changed, 74 insertions(+) create mode 100644 docs/agent-update-backlog.md diff --git a/docs/INDEX.md b/docs/INDEX.md index 3a8576c..d5ebee2 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -18,6 +18,7 @@ | [seaca-mobile.md](seaca-mobile.md) | **Seaca**: коды, устройства, сессия, API | | [seaca-fcm.md](seaca-fcm.md) | **Seaca push**: Firebase и `SAC_FCM_*` | | [workspace-three-repos.md](workspace-three-repos.md) | Multi-root workspace (три репо) | +| [agent-update-backlog.md](agent-update-backlog.md) | **ToDo:** версии агентов, удалённое обновление | ## Порядок чтения diff --git a/docs/agent-update-backlog.md b/docs/agent-update-backlog.md new file mode 100644 index 0000000..cb202c6 --- /dev/null +++ b/docs/agent-update-backlog.md @@ -0,0 +1,58 @@ +# ToDo — управление версиями агентов и удалённое обновление + +**Статус:** идея, требует проработки архитектуры. +**Связано:** [roadmap.md](roadmap.md) (v0.7), [agent-integration.md](agent-integration.md), UI «Хосты». + +--- + +## Цель + +SAC должен: + +1. **Отслеживать соответствие версий** агентов (`ssh-monitor`, `RDP-login-monitor`) ожидаемым/минимальным для текущей версии SAC. +2. **Инициировать обновление удалённо** с компьютеров/серверов из UI SAC (или по политике), без ручного захода на каждый хост. + +Сейчас версии видны по `host.product_version` и heartbeat; обновление — вручную (`update_ssh_monitor.sh`, `Deploy-LoginMonitor.ps1` / NETLOGON, GPO). + +--- + +## Вопросы для проработки + +| # | Тема | Варианты / заметки | +|---|------|-------------------| +| 1 | **Источник истины версии** | Матрица в SAC (min/recommended per `product`); теги в репо; отдельный manifest API | +| 2 | **Сигнал «устарел»** | Problem `agent.version.stale`; severity на карточке хоста; дашборд «не на версии» | +| 3 | **Канал команд** | Pull-only (агент сам тянет по расписанию) vs push-команда от SAC (нужен обратный канал) | +| 4 | **Linux** | Вызов `update_ssh_monitor.sh` по systemd timer + флаг «pending update» из SAC ingest response? Отдельный `agent.command` event? SSH/Ansible с SAC — вне scope агента | +| 5 | **Windows** | GPO/NETLOGON уже есть; remote = триггер `Deploy-LoginMonitor.ps1` через scheduled task / WinRM / SCCM — что допустимо по безопасности | +| 6 | **Авторизация** | Только admin SAC; audit log; подтверждение массового обновления; rate limit | +| 7 | **Отчёт о результате** | `agent.update.started` / `agent.update.success` / `agent.update.failed` в ingest; привязка к `host_id` | +| 8 | **Сеть** | Агент за NAT только исходящий HTTPS — предпочтителен **pull**, не inbound на хост | +| 9 | **Совместимость** | Связка с `schema_version`, откат, окно maintenance | + +--- + +## Черновые критерии приёмки (когда дойдём до реализации) + +- [ ] В UI «Хосты»: колонка/бейдж «версия OK / устарела / неизвестна». +- [ ] Настройка минимальной/рекомендуемой версии по продукту в SAC (или env). +- [ ] Problem или оповещение при расхождении (с cooldown). +- [ ] Действие admin: «Запросить обновление» на одном хосте / группе (MVP). +- [ ] Агент подтверждает попытку обновления событием в SAC. +- [ ] Документация: Linux + Windows runbook, ограничения безопасности. + +--- + +## Не в первой итерации (вероятно) + +- Полная замена Ansible/GPO/SCCM. +- Обновление SAC с агентов. +- macOS-агент. + +--- + +## См. также + +- [analytics-backlog.md](analytics-backlog.md) — отложенная аналитика +- [todo-2026-05-29.md](todo-2026-05-29.md) — оповещения и настройки +- Репозитории агентов: `update_ssh_monitor.sh`, `Deploy-LoginMonitor.ps1`, `update-rdp-monitor.ps1` diff --git a/docs/roadmap.md b/docs/roadmap.md index 9b68067..bc6d387 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -81,6 +81,20 @@ --- +## v0.7 — Версии агентов и удалённое обновление (ToDo) + +**Цель:** SAC контролирует актуальность `ssh-monitor` и `RDP-login-monitor` на хостах и может **инициировать обновление** без обхода всех машин вручную. + +- Сверка `product_version` с политикой SAC (min / recommended) +- UI: статус версии на карточке хоста, список отстающих +- Problems / оповещения при устаревании агента +- Команда обновления (предпочтительно **pull** с хоста: агент видит «нужно обновиться» и запускает свой updater) +- События `agent.update.*` в ingest для аудита + +**Проработка:** [agent-update-backlog.md](agent-update-backlog.md). + +--- + ## Не планируется (пока) - Замена Zabbix для инфраструктурного мониторинга diff --git a/docs/todo-2026-05-29.md b/docs/todo-2026-05-29.md index 97192d0..4139d91 100644 --- a/docs/todo-2026-05-29.md +++ b/docs/todo-2026-05-29.md @@ -84,5 +84,6 @@ UseSAC=exclusive→ только SAC ingest; TG/email = настройки SAC ( - [TZ.md](TZ.md) §4.6 F-NOT-01 … F-NOT-05 - [agent-integration.md](agent-integration.md) — режимы UseSAC +- [agent-update-backlog.md](agent-update-backlog.md) — **ToDo:** версии агентов и удалённое обновление из SAC - `backend/app/config.py` — `telegram_*` - `backend/app/services/telegram_notify.py` From 55f047cd3586e2397d1709d52884683754ad5751 Mon Sep 17 00:00:00 2001 From: PTah Date: Wed, 17 Jun 2026 11:35:17 +1000 Subject: [PATCH 3/3] fix: Seaca push uses same lifecycle text as Telegram (0.9.11) Reuse telegram templates for FCM title/body so agent start/restart reasons reach mobile without Seaca app changes. Co-authored-by: Cursor --- backend/app/services/mobile_notify.py | 4 +- backend/app/services/telegram_templates.py | 37 +++++++++++++ backend/app/version.py | 2 +- backend/tests/test_health.py | 4 +- backend/tests/test_mobile_notify.py | 25 ++++++++- backend/tests/test_telegram_templates.py | 63 +++++++++++++++++++++- frontend/src/version.ts | 2 +- 7 files changed, 129 insertions(+), 8 deletions(-) diff --git a/backend/app/services/mobile_notify.py b/backend/app/services/mobile_notify.py index f5bb27d..5e238bd 100644 --- a/backend/app/services/mobile_notify.py +++ b/backend/app/services/mobile_notify.py @@ -16,6 +16,7 @@ from app.models import Event, Problem from app.models.mobile_device import MobileDevice from app.services.notification_severity import severity_meets_minimum from app.services.notification_policy import get_effective_notification_policy +from app.services.telegram_templates import format_event_mobile_push logger = logging.getLogger(__name__) @@ -170,8 +171,7 @@ def _send_fcm_data( def _event_payload(event: Event) -> tuple[str, str, dict[str, str]]: - title = f"[{event.severity}] {event.title}" - body = (event.summary or "")[:200] + title, body = format_event_mobile_push(event) data = { "kind": "event", "id": str(event.id), diff --git a/backend/app/services/telegram_templates.py b/backend/app/services/telegram_templates.py index 0537453..0391cfa 100644 --- a/backend/app/services/telegram_templates.py +++ b/backend/app/services/telegram_templates.py @@ -506,6 +506,43 @@ def format_event_telegram_html(event: Event) -> str: return _append_event_source(_format_event_body_html(event), event) +_TELEGRAM_INLINE_TAGS = re.compile(r"]*)?>", re.I) +_TELEGRAM_ANCHOR_OPEN = re.compile(r"]*>", re.I) +_TELEGRAM_ANCHOR_CLOSE = re.compile(r"", re.I) + +_MOBILE_PUSH_BODY_MAX = 3500 + + +def telegram_html_to_plaintext(text: str) -> str: + """Plain text for Seaca push from the same HTML templates as Telegram.""" + out = sanitize_telegram_html(text) + out = _TELEGRAM_INLINE_TAGS.sub("", out) + out = _TELEGRAM_ANCHOR_OPEN.sub("", out) + out = _TELEGRAM_ANCHOR_CLOSE.sub("", out) + out = html.unescape(out) + out = re.sub(r"\n{3,}", "\n\n", out) + return out.strip() + + +def format_event_mobile_push(event: Event) -> tuple[str, str]: + """Title + body for FCM data payload (mirrors Telegram wording).""" + plain = telegram_html_to_plaintext(format_event_telegram_html(event)) + lines = [line.strip() for line in plain.split("\n") if line.strip()] + if lines: + title = lines[0] + body = "\n".join(lines[1:]).strip() + if not body: + body = (event.summary or "").strip() + else: + title = f"[{event.severity}] {event.title}" + body = (event.summary or "").strip() + if len(title) > 120: + title = title[:117] + "…" + if len(body) > _MOBILE_PUSH_BODY_MAX: + body = body[: _MOBILE_PUSH_BODY_MAX - 1] + "…" + return title, body + + def _format_rdg_html(event: Event) -> str: details = _details_dict(event) if event.type.endswith(".success"): diff --git a/backend/app/version.py b/backend/app/version.py index 3af75ca..21e3042 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.9.10" +APP_VERSION = "0.9.11" APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}" diff --git a/backend/tests/test_health.py b/backend/tests/test_health.py index cbf17d3..e2f888c 100644 --- a/backend/tests/test_health.py +++ b/backend/tests/test_health.py @@ -4,6 +4,6 @@ from app.version import APP_NAME, APP_VERSION, APP_VERSION_LABEL def test_version_constants(): - assert APP_VERSION == "0.9.10" + assert APP_VERSION == "0.9.11" assert APP_NAME == "Security Alert Center" - assert APP_VERSION_LABEL == "Security Alert Center v.0.9.10" + assert APP_VERSION_LABEL == "Security Alert Center v.0.9.11" diff --git a/backend/tests/test_mobile_notify.py b/backend/tests/test_mobile_notify.py index 9a0f7d1..8aca1ac 100644 --- a/backend/tests/test_mobile_notify.py +++ b/backend/tests/test_mobile_notify.py @@ -1,10 +1,33 @@ """FCM push must not break event ingest.""" +from datetime import datetime, timezone from unittest.mock import MagicMock, patch import pytest -from app.services.mobile_notify import MobileNotConfiguredError, _send_fcm_data +from app.models import Event, Host +from app.services.mobile_notify import MobileNotConfiguredError, _event_payload, _send_fcm_data + + +def test_event_payload_lifecycle_uses_telegram_wording(): + host = Host(hostname="WIN01", display_name="K6A-DC3", os_family="windows") + event = Event( + event_id="00000000-0000-4000-8000-000000000511", + host_id=1, + host=host, + occurred_at=datetime(2026, 5, 29, 9, 0, tzinfo=timezone.utc), + category="agent", + type="agent.lifecycle", + severity="info", + title="started", + summary="short", + details={"lifecycle": "started", "trigger": "settings_reload", "telegram_via": "sac"}, + payload={"source": {"product": "ssh-monitor", "product_version": "1.4.0-SAC"}}, + ) + title, body, data = _event_payload(event) + assert title == "✅ Агент запущен" + assert "graceful restart" in body + assert data["type"] == "agent.lifecycle" def test_send_fcm_data_swallows_token_errors_by_default(): diff --git a/backend/tests/test_telegram_templates.py b/backend/tests/test_telegram_templates.py index 342c35f..c7b5834 100644 --- a/backend/tests/test_telegram_templates.py +++ b/backend/tests/test_telegram_templates.py @@ -3,7 +3,13 @@ from datetime import datetime, timezone from app.models import Event, Host -from app.services.telegram_templates import format_event_telegram_html, format_rdp_login_html, html_escape +from app.services.telegram_templates import ( + format_event_mobile_push, + format_event_telegram_html, + format_rdp_login_html, + html_escape, + telegram_html_to_plaintext, +) def test_html_escape_special_chars(): @@ -145,6 +151,61 @@ def test_event_telegram_includes_sac_source_for_sac_daily_report(): assert "📡 Оповещение: SAC (Security Alert Center)" in text +def test_telegram_html_to_plaintext_strips_tags(): + assert telegram_html_to_plaintext("✅ Агент запущен\n🏢 Хост: WIN01") == ( + "✅ Агент запущен\n🏢 Хост: WIN01" + ) + + +def test_format_event_mobile_push_lifecycle_includes_trigger(): + host = Host(hostname="WIN01", display_name="K6A-DC3", os_family="windows") + event = Event( + event_id="00000000-0000-4000-8000-000000000509", + host_id=1, + host=host, + occurred_at=datetime(2026, 5, 29, 9, 0, tzinfo=timezone.utc), + category="agent", + type="agent.lifecycle", + severity="info", + title="started", + summary="Мониторинг запущен", + details={"lifecycle": "started", "trigger": "deploy_recycle", "telegram_via": "sac"}, + payload={"source": {"product": "rdp-login-monitor", "product_version": "1.2.30-SAC"}}, + ) + title, body = format_event_mobile_push(event) + assert title == "✅ Агент запущен" + assert "K6A-DC3" in body + assert "1.2.30-SAC" in body + assert "обновление скрипта" in body + assert "📡 Оповещение: SAC" in body + + +def test_format_event_mobile_push_uses_notification_body(): + host = Host(hostname="WIN01", display_name="K6A-DC3", os_family="windows") + body_text = "✅ Мониторинг логинов ЗАПУЩЕН\n🖥️ Сервер: K6A-DC3 (10.0.0.1)" + event = Event( + event_id="00000000-0000-4000-8000-000000000510", + host_id=1, + host=host, + occurred_at=datetime(2026, 5, 29, 9, 0, tzinfo=timezone.utc), + category="agent", + type="agent.lifecycle", + severity="info", + title="started", + summary="Мониторинг запущен", + details={ + "lifecycle": "started", + "trigger": "boot", + "notification_body": body_text, + "telegram_via": "sac", + }, + payload={"source": {"product": "rdp-login-monitor", "product_version": "1.2.31-SAC"}}, + ) + title, body = format_event_mobile_push(event) + assert title == "✅ Мониторинг логинов ЗАПУЩЕН" + assert "K6A-DC3 (10.0.0.1)" in body + + def test_lifecycle_started_template(): host = Host(hostname="WIN01", display_name="K6A-DC3", os_family="windows") event = Event( diff --git a/frontend/src/version.ts b/frontend/src/version.ts index 56f486f..6e238db 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.9.10"; +export const APP_VERSION = "0.9.11"; export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;