chore(home): mirror from kalinamall (038363c) with papatramp URLs

This commit is contained in:
2026-07-14 20:44:01 +10:00
commit 6d102603c2
46 changed files with 12612 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
# Документация RDP-login-monitor
Руководства по развёртыванию и эксплуатации скриптов мониторинга.
| Документ | Описание |
|----------|----------|
| [deploy-rdp-login-monitor.md](deploy-rdp-login-monitor.md) | **Login_Monitor.ps1** — NETLOGON, GPO, задачи планировщика, версии, 4740 на КД |
| [exchange-mail-security.md](exchange-mail-security.md) | **Exchange-MailSecurity.ps1** — очереди, пересылка на внешние адреса, установка |
| [deploy-netlogon-publish.md](deploy-netlogon-publish.md) | Публикация пакета на шару (`update-rdp-monitor.ps1`) |
Общий каталог установки на серверах: **`C:\ProgramData\RDP-login-monitor\`**.
Краткий обзор возможностей — в корневом **[README.md](../README.md)**.
+81
View File
@@ -0,0 +1,81 @@
# Публикация пакета на NETLOGON
Скрипт **`update-rdp-monitor.ps1`** на сервере публикации (например DC3) выполняет `git pull` и копирует файлы в шару.
## Путь на шаре (`-NetlogonDest`)
После `git pull` скрипт копирует дистрибутив в UNC-каталог NETLOGON:
```text
\\<имя-DC>\NETLOGON\RDP-login-monitor
```
`<имя-DC>` — NetBIOS-имя или FQDN **контроллера домена**, где лежит SYSVOL (тот же хост, с которого GPO запускает `Deploy-LoginMonitor.ps1`). Примеры:
- `\\K6A-DC3\NETLOGON\RDP-login-monitor`
- `\\dc01.corp.example.com\NETLOGON\RDP-login-monitor`
Значение по умолчанию в скрипте — **заглушка** `\\dc.contoso.local\NETLOGON\RDP-login-monitor`. В реальном домене её **нужно переопределить**, иначе после успешного `git pull` будет ошибка **«Не найден сетевой путь»** (скрипт не достучится до несуществующего хоста).
Проверка перед публикацией:
```powershell
Test-Path '\\K6A-DC3\NETLOGON\RDP-login-monitor'
# или хотя бы корень шары:
Test-Path '\\K6A-DC3\NETLOGON'
```
Должно вернуть `True` под учётной записью, с которой запускаете публикацию (на DC — обычно локальный админ; с рабочей станции — доменный админ с доступом к NETLOGON).
## Параметры по умолчанию
| Параметр | Значение |
|----------|----------|
| `$RepoPath` | `C:\Soft\Git\RDP-login-monitor` |
| `$NetlogonDest` | `\\dc.contoso.local\NETLOGON\RDP-login-monitor` *(заглушка — замените на свой DC)* |
| `$GitUrl` | `https://git.papatramp.ru/PapaTramp/RDP-login-monitor.git` |
| `$GitBranch` | `main` |
| `$LogFile` | `C:\soft\Logs\update-rdp-monitor.log` |
## Копируемые файлы
- `Login_Monitor.ps1`
- `Sac-Client.ps1`
- `version.txt`
- `Deploy-LoginMonitor.ps1`
- `Restart-RdpLoginMonitor.ps1`
- `Exchange-MailSecurity.ps1`
- `Notify-Common.ps1`
- `Install-DomainMonitors.ps1`
- `Deploy-DomainMonitors.ps1`
- `exchange_monitor.settings.example.ps1`
- `login_monitor.settings.example.ps1`
## Запуск
**На сервере публикации** (клон репозитория + доступ к NETLOGON):
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Soft\Git\RDP-login-monitor\update-rdp-monitor.ps1 `
-NetlogonDest '\\K6A-DC3\NETLOGON\RDP-login-monitor'
```
Другой remote git (закрытое зеркало):
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Soft\Git\RDP-login-monitor\update-rdp-monitor.ps1 `
-NetlogonDest '\\K6A-DC3\NETLOGON\RDP-login-monitor' `
-GitUrl 'https://git.papatramp.ru/PapaTramp/RDP-login-monitor.git'
```
Пробный прогон без копирования:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Soft\Git\RDP-login-monitor\update-rdp-monitor.ps1 `
-NetlogonDest '\\K6A-DC3\NETLOGON\RDP-login-monitor' `
-WhatIf
```
После pull обязательно проверьте **`version.txt`** на шаре — его номер определяет, подтянут ли обновления на клиентах. Метка может включать суффикс (например **`1.2.27-SAC`**); **`Deploy-LoginMonitor.ps1`** сравнивает её с **`deployed_version.txt`** по полной строке.
Файлы **`*.ps1`** при копировании пересохраняются как **UTF-8 с BOM** (иначе PowerShell 5.1 с NETLOGON может не разобрать кириллицу в скриптах). Скрипты **`Deploy-DomainMonitors.ps1`** и **`Install-DomainMonitors.ps1`** используют **ASCII** в рабочих строках — их можно запускать и без перепубликации.
+237
View File
@@ -0,0 +1,237 @@
# Развёртывание RDP Login Monitor в домене
Монитор ставится в **`C:\ProgramData\RDP-login-monitor\`**, задачи планировщика создаёт **`Login_Monitor.ps1 -InstallTasks`**. Доставку по сети выполняет **`Deploy-LoginMonitor.ps1`**.
- Публикация на NETLOGON: [deploy-netlogon-publish.md](deploy-netlogon-publish.md)
- Exchange Mail Security (отдельный пакет): [exchange-mail-security.md](exchange-mail-security.md)
## Файлы на файловой шаре
Каталог, доступный **конечным компьютерам** на чтение (учётная запись компьютера домена / SYSTEM), например:
`\\dc.contoso.local\NETLOGON\RDP-login-monitor\`
| Файл | Назначение |
|------|------------|
| `Login_Monitor.ps1` | Основной скрипт мониторинга |
| `Sac-Client.ps1` | Клиент SAC (обязателен для SAC; сверка SHA256 при деплое) |
| `login_monitor.settings.example.ps1` | Образец настроек (bootstrap локального settings) |
| `version.txt` | **Одна строка** — версия пакета на шаре (например `1.2.27-SAC`) |
| `Deploy-LoginMonitor.ps1` | Установщик для GPO / scheduled task |
Полный список файлов на шару (включая Exchange): [deploy-netlogon-publish.md](deploy-netlogon-publish.md).
**Не копируются Deploy-LoginMonitor:** `ignore.lst`, `login_monitor.settings.ps1` (секреты локальны).
## Алгоритм Deploy (GPO startup / scheduled task)
```mermaid
flowchart TD
A[GPO startup или RDP-Login-Monitor-Deploy] --> B[Deploy-LoginMonitor.ps1 с UNC]
B --> C{Login_Monitor.ps1 и version.txt на шаре?}
C -->|нет| Z[exit 0, запись в deploy.log]
C -->|да| D[Сравнение version.txt vs deployed_version.txt]
D --> E{Нужна работа?}
E -->|версия совпадает, bundle OK, settings OK| F["Актуально — exit 0"]
E -->|новая версия / патчи / первый запуск| G[Graceful stop монитора]
G --> H[Copy Login_Monitor.ps1 + Sac-Client.ps1]
H --> I[Sync settings из example + post-patches]
I --> J[Login_Monitor.ps1 -InstallTasks]
J --> K[deployed_version.txt + deploy_last_update.txt]
K --> L[Start monitor]
```
Корень дистрибутива: **`-SourceShareRoot`** или родитель каталога `Deploy-LoginMonitor.ps1` при запуске по UNC.
Локальная метка версии: **`C:\ProgramData\RDP-login-monitor\deployed_version.txt`**. Если файла нет — версия берётся из **`$ScriptVersion`** в установленном `Login_Monitor.ps1`.
### Когда деплой **не** копирует файлы
Версия на шаре **совпадает** с локальной **и** одновременно:
- SHA256 **`Login_Monitor.ps1`** и **`Sac-Client.ps1`** совпадает с шарой;
- в **`login_monitor.settings.ps1`** уже есть настроенный SAC (или не требуется bootstrap);
- применены post-patches: подсказки **`$ServerDisplayName`**, **`$DailyReportEnabled`**, на Exchange — noise settings.
Иначе деплой **продолжается** (даже при совпадении номера версии): другой hash bundle, донастройка SAC, исправление `DailyReportEnabled = false` без `$`, дописывание Exchange-фильтров и т.д.
### Upgrade / downgrade
| Ситуация | Поведение |
|----------|-----------|
| Версия на шаре **новее** | Полный цикл деплоя |
| Версия **совпадает**, но нужны патчи | Полный цикл (см. выше) |
| Версия на шаре **старее** | Пропуск, пока не указан **`-AllowDowngrade`** |
Метки с суффиксом (**`1.2.27-SAC`**) сравниваются **по полной строке**; для порядка версий используется числовой префикс `1.2.27`.
Лог: **`C:\ProgramData\RDP-login-monitor\Logs\deploy.log`**. Ошибки пишутся в лог и завершаются **`exit 0`** (удобно для GPO).
## Сервер Exchange и GPO Deploy-LoginMonitor
**`Deploy-LoginMonitor.ps1` не копирует отдельный Exchange-пакет** — на MailServer те же **`Login_Monitor.ps1`** + **`Sac-Client.ps1`**, что на RDS и рабочих станциях.
При обнаружении роли Exchange (реестр, каталог установки, службы) Deploy **только дописывает** в **`login_monitor.settings.ps1`**, если строк ещё нет:
- `${Ignore4624-LT3-EmptyIP-Event} = $true`
- `$WinRmIgnoreLocalSource = 1`
- `$WinRmIgnoreMachineAccounts = 1`
- `$WinRmExchangeStrictMode = 1`
Подавление шума WinRM (HealthMailbox, loopback), ложных WinRM 91↔4624 (Outlook/LT3) и лишних **4624 LT3**.
**Мониторинг очередей транспорта и правил пересылки** — другой скрипт, **не** через GPO RDP-монитора:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\dc.contoso.local\NETLOGON\RDP-login-monitor\Deploy-DomainMonitors.ps1" -Target Exchange
```
Подробно: [exchange-mail-security.md](exchange-mail-security.md).
## Локальные настройки: `login_monitor.settings.ps1`
Путь: **`C:\ProgramData\RDP-login-monitor\login_monitor.settings.ps1`**.
| Действие Deploy | Условие |
|-----------------|--------|
| Копирует example → settings | Файла settings ещё нет |
| Дописывает блок SAC из example | Нет `$UseSAC` / `$SacUrl` / `$SacApiKey` |
| **Не перезаписывает** целиком | SAC уже настроен (`UseSAC` не `off`, ключ и URL заданы) |
| Подсказка `# $ServerDisplayName = '<COMPUTERNAME>'` | Строки `$ServerDisplayName` нет |
| Подсказка / починка `$DailyReportEnabled` | Нет переменной или `= false` без `$``$false` |
| Exchange noise (см. выше) | Роль Exchange и нет соответствующих строк |
Секреты (Telegram, **`sac_*`**, SMTP, 4740) правятся **вручную** на машине.
```powershell
$root = 'C:\ProgramData\RDP-login-monitor'
Copy-Item '\\dc.contoso.local\NETLOGON\RDP-login-monitor\login_monitor.settings.example.ps1' `
(Join-Path $root 'login_monitor.settings.ps1')
notepad (Join-Path $root 'login_monitor.settings.ps1')
```
DPAPI: **`Encrypt-DpapiForRdpMonitor.ps1`**.
### Security Alert Center
```powershell
$UseSAC = 'dual' # off | exclusive | dual | fallback
$SacUrl = 'https://sac.example.com'
$SacApiKey = 'sac_...'
```
Проверка: **`Login_Monitor.ps1 -CheckSac`**. После правок settings — **`Restart-RdpLoginMonitor.ps1`** или **`-RequestRestart`**.
## Задачи, heartbeat, ignore.lst
| Задача | Назначение |
|--------|------------|
| **`RDP-Login-Monitor`** | Запуск при старте ОС |
| **`RDP-Login-Monitor-Watchdog`** | Контроль процесса каждые 5 мин |
Логи: **`login_monitor.log`**, **`watchdog.log`**, **`Logs\last_heartbeat.txt`**.
**`ignore.lst`** — локально, Deploy не копирует. Синтаксис: [README.md](../README.md) (раздел 7).
**4740 на КД:** только если имя узла совпадает с **`$LockoutMonitorDomainController`** в settings на этом КД.
## GPO и периодический deploy
1. Файлы на `\\dc.contoso.local\NETLOGON\RDP-login-monitor\` (`update-rdp-monitor.ps1` на DC публикации).
2. GPO на OU **компьютеров****Сценарии PowerShell** автозагрузки → `Deploy-LoginMonitor.ps1`.
3. Security Filtering: группа компьютеров; на шару — Read для **SYSTEM** / Domain Computers.
4. После смены membership — **перезагрузка** (не только `gpupdate`).
Deploy после `-InstallTasks` запускает монитор; задача **`RDP-Login-Monitor`** поднимет его при следующей загрузке.
**Серверы без частых перезагрузок:**
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File ".\Install-DeployScheduledTask.ps1" `
-TaskName "RDP-Login-Monitor-Deploy" `
-DeployScriptPath "\\dc.contoso.local\NETLOGON\RDP-login-monitor\Deploy-LoginMonitor.ps1" `
-RepeatMinutes 60 `
-RunNow
```
**Ручной deploy** (от администратора):
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\dc.contoso.local\NETLOGON\RDP-login-monitor\Deploy-LoginMonitor.ps1"
```
Параметры: **`-WhatIf`**, **`-SkipStartMonitorAfterUpdate`**, **`-AllowDowngrade`**.
## Обновление: чеклист
### A. Публикация на шару (один раз на релиз)
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monitor.ps1
```
Проверьте на шаре **`Sac-Client.ps1`** и **`version.txt`** (например `1.2.27-SAC`).
### B. На целевых машинах
GPO или scheduled task — дождаться startup / `-RunNow`. Ручная проверка:
```powershell
Get-Content 'C:\ProgramData\RDP-login-monitor\Logs\deploy.log' -Tail 20
Select-String -Path 'C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1' -Pattern 'ScriptVersion'
Test-Path 'C:\ProgramData\RDP-login-monitor\Sac-Client.ps1'
Get-ScheduledTask -TaskName 'RDP-Login-Monitor','RDP-Login-Monitor-Watchdog' -ErrorAction SilentlyContinue
```
Повторный запуск Deploy без смены версии должен дать **`Актуально, копирование не требуется`**.
### C. Graceful restart
После правки settings (без смены `Login_Monitor.ps1`):
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass `
-File "C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1" -RequestRestart
```
После Deploy нового **`Login_Monitor.ps1`** — recycle:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass `
-File "C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1" -RequestRestart -Recycle
```
**`Deploy-LoginMonitor.ps1`** пишет **`restart.request`**, ждёт до **35 с**, затем **`Stop-Process -Force`** только при таймауте.
## Обновление через SAC (WinRM)
Альтернатива NETLOGON/GPO: кнопка **«Обновить через WinRM»** на карточке хоста в SAC (сервер ≥ 0.20.15).
| Этап | Где | Действие |
|------|-----|----------|
| 1 | SAC | `git fetch` RDP-login-monitor → zip (`.ps1` с UTF-8 BOM) |
| 2 | Клиент (WinRM) | `Invoke-WebRequest``/api/v1/agent/rdp-bundle/<token>` |
| 3 | Клиент | Распаковка в `C:\ProgramData\RDP-login-monitor\_sac_staging` |
| 4 | Клиент | `Deploy-LoginMonitor.ps1 -SourceShareRoot _sac_staging` |
**Требования:** domain admin в SAC; `SAC_PUBLIC_URL` доступен с ПК; `rdp_git_repo_url` в настройках обновлений. **`Deploy-LoginMonitor.ps1` на шаре NETLOGON для этого пути не обязателен** — скрипт приходит в zip.
Лог операции — в модалке SAC сразу при старте. См. [agent-control-plane.md](https://git.papatramp.ru/PapaTramp/security-alert-center/src/branch/main/docs/agent-control-plane.md) §4.3.
## Версии
| Файл | Роль |
|------|------|
| **`version.txt` на шаре** | Триггер обновления для Deploy |
| **`deployed_version.txt` локально** | Метка после успешного деплоя |
| **`$ScriptVersion` в Login_Monitor.ps1** | Версия в логах и Telegram |
Поднимайте **`version.txt`** при каждой выкладке на NETLOGON; строка в **`version.txt`** и **`$ScriptVersion`** должны совпадать (включая суффикс `-SAC`).
## Безопасность и UNC
- Ограничьте ACL на шару (в example могут быть доменные секреты).
- DPAPI для токенов в **`login_monitor.settings.ps1`**.
- При ошибках подписи с FQDN-шары: короткое имя DC и **`-ExecutionPolicy Bypass`**.
Диагностика: Group Policy Operational log, **`Logs\deploy.log`**, **`deploy_installtasks_*.log`**.
+268
View File
@@ -0,0 +1,268 @@
# Exchange Mail Security — руководство
Скрипт **`Exchange-MailSecurity.ps1`** предназначен **только для сервера Microsoft Exchange** с Exchange Management Shell (EMS). Не устанавливается на все компьютеры домена через GPO RDP-монитора.
На Exchange-сервере GPO **`Deploy-LoginMonitor.ps1`** по-прежнему ставит **`Login_Monitor.ps1`** (RDP/WinRM/4624) и при необходимости дописывает noise settings в **`login_monitor.settings.ps1`**. Пакет **`Exchange-MailSecurity.ps1`** доставляется отдельно — см. раздел «Деплой на Exchange» ниже и [deploy-rdp-login-monitor.md](deploy-rdp-login-monitor.md).
## Назначение
| Функция | Режим | Расписание (задача планировщика) |
|---------|--------|----------------------------------|
| **Очереди транспорта** | `-Mode Queues` | `RDP-Exchange-TransportQueues` — каждые **10** мин |
| **Пересылка на внешние адреса** (BEC) | `-Mode Inbox` | `RDP-Exchange-InboxRules` — ежедневно **02:00** |
| **Контроль heartbeat** | `-Watchdog` | `RDP-Exchange-MailSecurity-Watchdog` — каждые **15** мин |
Каталог установки (общий с RDP-монитором): **`C:\ProgramData\RDP-login-monitor\`**.
## Что считается «несанкционированной пересылкой»
Скрипт ищет доставку почты **на домены вне организации** (не из списка принятых доменов Exchange).
### 1. Правила Inbox (`Get-InboxRule`)
Для **включённых** правил проверяются:
- `ForwardTo`
- `RedirectTo`
- `ForwardAsAttachmentTo`
Если целевой SMTP-адрес указывает на домен **не** из `Get-AcceptedDomain` (типы **Authoritative** и **InternalRelay**) и не в **whitelist** — фиксируется находка.
**Повышенная важность (Критическая):** включённое правило с `DeleteMessage` или `MarkAsRead`.
**Отключённые правила** (`$ScanDisabledInboxRulesWithExternalForward = $true`): внешняя пересылка фиксируется с важностью **«Средняя (правило отключено)»**.
### 2. Пересылка на уровне ящика (`Get-Mailbox`)
Проверяются ящики с заполненными:
- `ForwardingSmtpAddress`
- `ForwardingAddress`
Это отдельный от Inbox Rule механизм («пересылать всю почту на внешний ящик») — частый вектор BEC.
### 3. Правила транспорта (`Get-TransportRule`)
Для **включённых** transport rules проверяются действия с адресами:
- `RedirectMessageTo`
- `BlindCopyTo`
- `CopyTo`
При внешнем SMTP — находка с типом **TransportRule**.
### Что не отслеживается
- Делегирование, Send As, скрытые EWS-правила без Inbox rule
- Пересылка только между **внутренними** accepted domains
- Чтение почты злоумышленником **без** настройки forward
## Очереди транспорта
`Get-Queue`: если **`MessageCount`** на очереди больше **`$QueueMessageCountThreshold`** (по умолчанию **150**), отправляется оповещение.
Повтор алерта по той же очереди — не чаще **`$QueueAlertCooldownSeconds`** (по умолчанию **900** с), состояние в `Logs\exchange_queue_alert_state.json`.
## Оповещения и baseline
- Каналы: **Telegram** и/или **Email** (модуль **`Notify-Common.ps1`**).
- Пересылка: **`$AlertOnlyOnNewForwardingFindings = $true`** — алерт при **новой** находке (`Logs\exchange_forwarding_baseline.json`).
- **Первый скан:** **`$SuppressAlertsOnFirstBaselineRun = $true`** (по умолчанию) — существующие пересылки **только в baseline**, без всплеска алертов; одна **сводка** (`$SendInboxScanSummary`).
### Dry-run перед первым Inbox-сканом
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\dc.contoso.local\NETLOGON\RDP-login-monitor\Exchange-MailSecurity.ps1" -Mode Inbox -WhatIf
```
`-WhatIf` подключает EMS, считает объём (`Get-Mailbox` / VIP-фильтр), **не вызывает** `Get-InboxRule`, не шлёт уведомления и не пишет baseline. Рекомендуется перед `-InstallTasks` и первым ночным `-Mode Inbox`.
При полном скане без VIP скрипт пишет **WARN** в лог; проблемные ящики — в **`$SkipInboxScanMailboxes`**.
- Далее — алерт только при **новых** или **изменённых** пересылках (в т.ч. включили ранее отключённое правило).
- **`$NotifyWhenForwardingScanClean = $false`** — не слать «всё чисто» при нуле находок.
## Режим VIP (пилот)
В **`exchange_monitor.settings.ps1`**:
```powershell
$VipMailboxesOnly = $true
$VipMailboxes = @('director@domain.ru', 'cfo@domain.ru')
$VipMailboxPatterns = @('*@domain.ru') # опционально
```
- **Список** — точные SMTP.
- **Шаблоны** — дополнительно обход `Get-Mailbox` и отбор по `-like`.
- Mailbox forwarding и Inbox rules — только в рамках VIP.
- Для полного домена: **`$VipMailboxesOnly = $false`**.
## Файлы на шаре NETLOGON
| Файл | Назначение |
|------|------------|
| `Exchange-MailSecurity.ps1` | Основной скрипт |
| `Notify-Common.ps1` | Отправка Telegram/Email |
| `Install-DomainMonitors.ps1` | `-Target Exchange` → регистрация задач |
| `Deploy-DomainMonitors.ps1` | Копирование с шары |
| `exchange_monitor.settings.example.ps1` | Образец настроек (на сервер — вручную) |
| `version.txt` | Версия пакета (общая с RDP-монитором) |
## Установка (пошагово)
### 1. Публикация на шару
На сервере публикации: `update-rdp-monitor.ps1` (см. [deploy-netlogon-publish.md](deploy-netlogon-publish.md)).
### 2. Деплой на Exchange (от администратора)
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\dc.contoso.local\NETLOGON\RDP-login-monitor\Deploy-DomainMonitors.ps1" -Target Exchange
```
Скрипт копирует файлы в `C:\ProgramData\RDP-login-monitor\`, вызывает **`Install-DomainMonitors.ps1 -Target Exchange`**, который регистрирует задачи планировщика.
Метка версии: `deployed_domain_monitors_version.txt`. Лог: `Logs\deploy_domain_monitors.log`.
### 3. Локальные настройки (один раз)
```powershell
# После Deploy v1.6.4+ образец лежит в ProgramData; иначе — с NETLOGON:
$ex = 'C:\ProgramData\RDP-login-monitor'
$src = Join-Path $ex 'exchange_monitor.settings.example.ps1'
if (-not (Test-Path -LiteralPath $src)) {
$src = '\\dc.contoso.local\NETLOGON\RDP-login-monitor\exchange_monitor.settings.example.ps1'
}
Copy-Item -LiteralPath $src -Destination (Join-Path $ex 'exchange_monitor.settings.ps1')
notepad (Join-Path $ex 'exchange_monitor.settings.ps1')
```
Задайте:
- `$TelegramBotToken` / `$TelegramChatID` (или DPAPI `...ProtectedB64`)
- при необходимости SMTP
- `$ExternalDomainWhitelist` — доверенные внешние домены
- для пилота: `$VipMailboxesOnly = $true` и `$VipMailboxes = @('user@domain.ru')`
Файл **`exchange_monitor.settings.ps1` не перезаписывается** при деплое.
### 4. Права
Учётная запись **SYSTEM** (задачи планировщика) должна иметь возможность:
- загрузить EMS на сервере;
- выполнять `Get-Mailbox`, `Get-InboxRule`, `Get-Queue`, `Get-TransportRule`, `Get-AcceptedDomain`.
На практике на Exchange-сервере под SYSTEM это обычно работает при локальном snap-in; при ошибках RBAC — запуск задачи от служебной УЗ с правами просмотра получателей.
### 5. Удалённый EMS
Если скрипт запускается **не** на Exchange, укажите в settings:
```powershell
$ExchangeServerFqdn = 'mail.contoso.local'
```
(подключение через `New-PSSession -ConfigurationName Microsoft.Exchange`).
## Ручной запуск и проверка
```powershell
# Очереди (быстро)
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\ProgramData\RDP-login-monitor\Exchange-MailSecurity.ps1" -Mode Queues
# Полный скан пересылки (может занять часы на большом количестве ящиков)
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\ProgramData\RDP-login-monitor\Exchange-MailSecurity.ps1" -Mode Inbox
# Watchdog
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\ProgramData\RDP-login-monitor\Exchange-MailSecurity.ps1" -Watchdog
# Переустановка задач
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\ProgramData\RDP-login-monitor\Exchange-MailSecurity.ps1" -InstallTasks
```
Проверка задач:
```powershell
schtasks /Query /TN "RDP-Exchange-TransportQueues" /V /FO LIST
schtasks /Query /TN "RDP-Exchange-InboxRules" /V /FO LIST
schtasks /Query /TN "RDP-Exchange-MailSecurity-Watchdog" /V /FO LIST
```
## Логи и служебные файлы
| Путь | Назначение |
|------|------------|
| `Logs\exchange_mail_security.log` | Основной лог |
| `Logs\exchange_watchdog.log` | Watchdog |
| `Logs\last_exchange_queues_ok.txt` | Успешный скан очередей |
| `Logs\last_exchange_inbox_scan_ok.txt` | Успешный скан пересылки |
| `Logs\exchange_forwarding_baseline.json` | Baseline находок (id правил/пересылок) |
| `Logs\exchange_queue_alert_state.json` | Cooldown алертов по очередям |
### Watchdog
- Нет обновления **очередей** > **20** мин (`$QueuesHeartbeatStaleSeconds`) → алерт.
- Нет обновления **inbox scan** > **26** ч (`$InboxHeartbeatStaleSeconds`) → алерт.
## Основные параметры в `Exchange-MailSecurity.ps1`
| Параметр | По умолчанию | Смысл |
|----------|--------------|--------|
| `$QueueMessageCountThreshold` | 150 | Порог сообщений в очереди |
| `$QueueAlertCooldownSeconds` | 900 | Пауза между алертами по одной очереди |
| `$ScanInboxRules` | `$true` | Скан Inbox rules |
| `$ScanMailboxForwarding` | `$true` | Скан forwarding на ящике |
| `$ScanTransportRules` | `$true` | Скан transport rules |
| `$AlertOnlyOnNewForwardingFindings` | `$true` | Только новые находки |
| `$VipMailboxesOnly` | `$false` | Только VIP-ящики |
| `$VipMailboxPatterns` | `@()` | Wildcard для VIP |
| `$SuppressAlertsOnFirstBaselineRun` | `$true` | Первый скан без N алертов |
| `$ScanDisabledInboxRulesWithExternalForward` | `$true` | Отключённые правила с внешним forward |
| `$SendInboxScanSummary` | `$true` | Сводка после скана |
| `$InboxScanBatchSize` | 50 | Пауза каждые N ящиков |
| `$InboxScanBatchDelaySeconds` | 3 | Задержка между батчами |
| `$ExcludeMailboxPatterns` | HealthMailbox*, … | Исключения |
| `$SkipInboxScanMailboxes` | `k.selezneva@example.com` | Не вызывать `Get-InboxRule` (битый rule store) |
Переопределение — в **`exchange_monitor.settings.ps1`**.
После починки ящика удалите его из `$SkipInboxScanMailboxes`.
## Формат оповещения (пересылка)
Пример:
```text
📧 Exchange: пересылка на внешний адрес
Тип: InboxRule | MailboxForwarding | TransportRule
Ящик: user@example.com
Правило: …
Куда: attacker@gmail.com (внешний)
Важность: Критическая | Высокая
```
## Обновление версии
1. Поднять **`version.txt`** в репозитории и на шаре.
2. `update-rdp-monitor.ps1` или ручное копирование.
3. На Exchange:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\dc.contoso.local\NETLOGON\RDP-login-monitor\Deploy-DomainMonitors.ps1" -Target Exchange
```
## Устранение неполадок
| Симптом | Действие |
|---------|----------|
| «Не удалось загрузить Exchange Management Shell» | Запуск на mailbox/Exchange server; проверить snap-in / `$ExchangeServerFqdn` |
| Нет алертов | Проверить `exchange_monitor.settings.ps1`, Telegram/SMTP, лог `exchange_mail_security.log` |
| Слишком много алертов в первый день | По умолчанию подавлены (`$SuppressAlertsOnFirstBaselineRun`); иначе whitelist + baseline |
| Inbox scan долгий | `$VipMailboxesOnly = $true`; увеличить `$InboxScanBatchDelaySeconds` |
| Ошибки Get-InboxRule на ящике | В логе будет «ошибка mailbox» — штатно, скан продолжается |
## Связанные документы
- [deploy-rdp-login-monitor.md](deploy-rdp-login-monitor.md) — RDP-монитор на ПК/серверах
- [deploy-netlogon-publish.md](deploy-netlogon-publish.md) — выкладка на шару
- [README.md](README.md) — оглавление Docs