# Интеграция агентов с SAC Контракт между **ssh-monitor**, **RDP-login-monitor** и **Security Alert Center**. Изменения вносятся в репозитории агентов отдельными задачами. --- ## 1. Режим `UseSAC` ### 1.1. Параметры конфигурации **ssh-monitor** (`/etc/ssh-monitor.conf`): ```ini # off | exclusive | dual | fallback UseSAC="exclusive" SAC_URL="https://sac.kalinamall.ru/api/v1/events" SAC_API_KEY="sac_xxxxxxxx" SAC_SPOOL_DIR="/var/lib/ssh-monitor/sac-spool" SAC_SEND_HEARTBEAT="1" SAC_FALLBACK_FAILURES="5" SAC_TIMEOUT_SEC="12" ``` **RDP-login-monitor** (`Login_Monitor.ps1` или отдельный `.conf`): ```powershell $UseSAC = "exclusive" # off | exclusive | dual | fallback $SacUrl = "https://sac.kalinamall.ru/api/v1/events" $SacApiKey = "sac_xxxxxxxx" $SacSpoolDir = "D:\Soft\Logs\sac-spool" ``` ### 1.2. Матрица поведения | Событие | `off` | `exclusive` | `dual` | `fallback` | |---------|-------|-------------|--------|------------| | Auth / sudo / ban / RDP login | Telegram/email с агента | Только SAC JSON | SAC + Telegram | SAC; при сбоях → Telegram | | Daily report | С агента | SAC формирует и шлёт | Оба | SAC, fallback как выше | | Heartbeat | С агента (если включён) | Только SAC (`agent.heartbeat`) | Оба | SAC | | Локальный LOG_FILE | Да | Да | Да | Да | ### 1.3. Проверка при старте - `UseSAC=off` — без изменений: хотя бы один канал `NOTIFY_CHAIN` (как сейчас). - `UseSAC≠off` — обязательны `SAC_URL`, `SAC_API_KEY`; HTTP `GET {base}/health` OK. - `--check-sac` / `Test-SacConnection` — отправка `agent.test`, ожидание `202`. --- ## 2. Протокол ingest ### 2.1. Запрос ```http POST /api/v1/events HTTP/1.1 Host: sac.kalinamall.ru Content-Type: application/json Authorization: Bearer sac_xxxxxxxx Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000 { ... событие по event-schema-v1.json ... } ``` ### 2.2. Ответ ```json { "status": "accepted", "event_id": "550e8400-e29b-41d4-a716-446655440000", "sac_event_url": "/events/12345", "problem_id": null } ``` ### 2.3. Spool при ошибке 1. Записать JSON в `SAC_SPOOL_DIR/{event_id}.json`. 2. Периодически (каждая итерация цикла / отдельный timer) повторять POST. 3. После успеха — удалить файл. 4. Лимит размера spool (например 500 MB) — логировать WARN, не удалять без алерта. --- ## 3. Маппинг уведомлений → типы событий ### 3.1. ssh-monitor | Текущий текст (сокращённо) | `type` | `severity` | |----------------------------|--------|------------| | Успешное SSH | `ssh.login.success` | info | | Неудачная SSH | `ssh.login.failed` | warning | | IP заблокирован | `ssh.ip.banned` | high | | Лимит без бана | `ssh.ip.bruteforce.threshold` | warning | | Массовый брутфорс | `ssh.bruteforce.mass` | high | | Sudo | `privilege.sudo.command` | warning–critical* | | logind new/removed/failed | `session.logind.*` | info–warning | | Ежедневный отчёт | `report.daily.ssh` | info | | Heartbeat | `agent.heartbeat` | info | \* critical — по эвристике команды (`useradd`, `passwd`, `rm -rf`, …) в `details.risk_level`. **Дополнительные поля в `details` (exclusive):** - `user`, `source_ip`, `port`, `attempt_number`, `max_attempts` - `sudo`: `run_as`, `command`, `pwd`, `risk_level` - `ban`: `ban_until`, `enable_ip_ban` - `brute`: `window_sec`, `fails_in_window` - `whitelist_matched`: boolean ### 3.2. RDP-login-monitor | Событие | `type` | `severity` | |---------|--------|------------| | 4624 успех | `rdp.login.success` | info | | 4625 неудача | `rdp.login.failed` | warning | | 4648 | `auth.explicit.credentials` | warning | | RD Gateway 302 | `rdg.connection.success` | info | | RD Gateway 303 | `rdg.connection.failed` | warning | | Старт/стоп | `agent.lifecycle` | info | | Отчёт | `report.daily.rdp` | info | **Дополнительные поля:** - `event_id_windows`, `logon_type`, `ip_address`, `workstation_name` - `gateway_target`, `gateway_error_code` - `filtered_out`, `filter_reason` --- ## 4. Поля `dedup_key` (рекомендации) | Тип | Формат dedup_key | |-----|------------------| | ssh.login.success | `{product}\|{host}\|ssh.login.success\|{user}\|{ip}` | | ssh.login.failed | `{product}\|{host}\|ssh.login.failed\|{ip}` (окно в SAC) | | privilege.sudo | `{product}\|{host}\|sudo\|{user}\|{hash(command)}` | | rdp.login.failed | `{product}\|{host}\|rdp.failed\|{ip}\|{user}` | SAC применяет cooldown по `dedup_key` + правилам. --- ## 5. Точки встраивания в код агентов ### ssh-monitor - Новая функция `send_sac_event()` вызывается из мест, где сейчас `notify_send "$message"`. - Обёртка `notify_or_sac()`: - `UseSAC=off` → `notify_send` - `exclusive` → только `send_sac_event` (в `summary` — тот же текст) - `dual` → оба - `fallback` → `send_sac_event`; при fail increment counter → при пороге `notify_send` ### RDP-login-monitor - `Send-SacEvent` + замена вызовов `Send-TelegramMessage` для событий мониторинга. - Heartbeat и daily report — отдельные типы в SAC. --- ## 6. Обратная совместимость - По умолчанию `UseSAC=off` — поведение 100% как сейчас. - `BACKUP_WEBHOOK_URL` в ssh-monitor при `exclusive` не используется для обычных алертов (только emergency в `fallback` — опционально). --- ## 7. Чеклист готовности агента - [ ] Параметры конфига задокументированы в README агента - [ ] `--check-sac` / `Test-SacConnection` - [ ] Spool и повторная отправка - [ ] Все типы из п. 3 покрыты - [ ] `event_id` UUID на каждое событие - [ ] Секреты не в git --- ## 8. См. также - [event-schema-v1.json](event-schema-v1.json) - [TZ.md](TZ.md) §3.2, §4.8