fix(deploy): version compare for -SAC labels; refresh deploy docs
Compare deployed_version.txt with full label (e.g. 1.2.26-SAC) so GPO deploy exits when up to date. Restructure deploy-rdp-login-monitor.md with mermaid flow, Exchange vs DomainMonitors split, and remove duplicated sections. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+25
-6
@@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
.NOTES
|
.NOTES
|
||||||
Лог: C:\ProgramData\RDP-login-monitor\Logs\deploy.log
|
Лог: C:\ProgramData\RDP-login-monitor\Logs\deploy.log
|
||||||
|
|
||||||
|
Сравнение версий: метки вида 1.2.26-SAC сравниваются по полному тексту (без учёта регистра);
|
||||||
|
для upgrade/downgrade используется числовой префикс (1.2.26). См. Docs/deploy-rdp-login-monitor.md.
|
||||||
#>
|
#>
|
||||||
|
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
@@ -104,8 +107,8 @@ function Get-LocalDeployedVersion {
|
|||||||
try {
|
try {
|
||||||
$head = Get-Content -LiteralPath $LocalScript -TotalCount 120 -ErrorAction Stop
|
$head = Get-Content -LiteralPath $LocalScript -TotalCount 120 -ErrorAction Stop
|
||||||
foreach ($ln in $head) {
|
foreach ($ln in $head) {
|
||||||
if ($ln -match '^\s*\$ScriptVersion\s*=\s*["'']([0-9]+(?:\.[0-9]+){0,3})["'']') {
|
if ($ln -match '^\s*\$ScriptVersion\s*=\s*["'']([^"'']+)["'']') {
|
||||||
return $Matches[1]
|
return ([string]$Matches[1]).Trim() -replace '^v', ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch { }
|
} catch { }
|
||||||
@@ -113,19 +116,35 @@ function Get-LocalDeployedVersion {
|
|||||||
return $null
|
return $null
|
||||||
}
|
}
|
||||||
|
|
||||||
function Normalize-VersionOrNull {
|
function Normalize-DeployVersionLabel {
|
||||||
param([string]$Text)
|
param([string]$Text)
|
||||||
if ([string]::IsNullOrWhiteSpace($Text)) { return $null }
|
if ([string]::IsNullOrWhiteSpace($Text)) { return $null }
|
||||||
$t = $Text.Trim() -replace '^v', ''
|
return ([string]$Text).Trim() -replace '^v', ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function Normalize-VersionOrNull {
|
||||||
|
param([string]$Text)
|
||||||
|
$t = Normalize-DeployVersionLabel -Text $Text
|
||||||
|
if ($null -eq $t) { return $null }
|
||||||
try {
|
try {
|
||||||
return [version]$t
|
return [version]$t
|
||||||
} catch {
|
} catch { }
|
||||||
return $null
|
if ($t -match '^([0-9]+(?:\.[0-9]+){0,3})') {
|
||||||
|
try { return [version]$Matches[1] } catch { }
|
||||||
}
|
}
|
||||||
|
return $null
|
||||||
}
|
}
|
||||||
|
|
||||||
function Compare-VersionStrings {
|
function Compare-VersionStrings {
|
||||||
param([string]$Left, [string]$Right)
|
param([string]$Left, [string]$Right)
|
||||||
|
if ([string]::IsNullOrWhiteSpace($Left) -and [string]::IsNullOrWhiteSpace($Right)) { return 0 }
|
||||||
|
if ([string]::IsNullOrWhiteSpace($Left)) { return -1 }
|
||||||
|
if ([string]::IsNullOrWhiteSpace($Right)) { return 1 }
|
||||||
|
|
||||||
|
$lt = Normalize-DeployVersionLabel -Text $Left
|
||||||
|
$rt = Normalize-DeployVersionLabel -Text $Right
|
||||||
|
if ($lt.Equals($rt, [StringComparison]::OrdinalIgnoreCase)) { return 0 }
|
||||||
|
|
||||||
$a = Normalize-VersionOrNull -Text $Left
|
$a = Normalize-VersionOrNull -Text $Left
|
||||||
$b = Normalize-VersionOrNull -Text $Right
|
$b = Normalize-VersionOrNull -Text $Right
|
||||||
if ($null -eq $a -or $null -eq $b) { return $null }
|
if ($null -eq $a -or $null -eq $b) { return $null }
|
||||||
|
|||||||
@@ -33,6 +33,6 @@ powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monit
|
|||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monitor.ps1 -WhatIf
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monitor.ps1 -WhatIf
|
||||||
```
|
```
|
||||||
|
|
||||||
После pull обязательно проверьте **`version.txt`** на шаре — его номер определяет, подтянут ли обновления на клиентах и Exchange.
|
После pull обязательно проверьте **`version.txt`** на шаре — его номер определяет, подтянут ли обновления на клиентах. Метка может включать суффикс (например **`1.2.26-SAC`**); **`Deploy-LoginMonitor.ps1`** сравнивает её с **`deployed_version.txt`** по полной строке.
|
||||||
|
|
||||||
Файлы **`*.ps1`** при копировании пересохраняются как **UTF-8 с BOM** (иначе PowerShell 5.1 с NETLOGON может не разобрать кириллицу в скриптах). Скрипты **`Deploy-DomainMonitors.ps1`** и **`Install-DomainMonitors.ps1`** используют **ASCII** в рабочих строках — их можно запускать и без перепубликации.
|
Файлы **`*.ps1`** при копировании пересохраняются как **UTF-8 с BOM** (иначе PowerShell 5.1 с NETLOGON может не разобрать кириллицу в скриптах). Скрипты **`Deploy-DomainMonitors.ps1`** и **`Install-DomainMonitors.ps1`** используют **ASCII** в рабочих строках — их можно запускать и без перепубликации.
|
||||||
|
|||||||
+128
-149
@@ -1,57 +1,106 @@
|
|||||||
# Развёртывание RDP Login Monitor в домене
|
# Развёртывание RDP Login Monitor в домене
|
||||||
|
|
||||||
Монитор ставится в **`C:\ProgramData\RDP-login-monitor\`**, задачи планировщика создаёт сам **`Login_Monitor.ps1`** (параметр `-InstallTasks`). Доставку по сети выполняет **`Deploy-LoginMonitor.ps1`**.
|
Монитор ставится в **`C:\ProgramData\RDP-login-monitor\`**, задачи планировщика создаёт **`Login_Monitor.ps1 -InstallTasks`**. Доставку по сети выполняет **`Deploy-LoginMonitor.ps1`**.
|
||||||
|
|
||||||
См. также: [exchange-mail-security.md](exchange-mail-security.md) (отдельно, только сервер Exchange).
|
- Публикация на 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\`
|
`\\dc.contoso.local\NETLOGON\RDP-login-monitor\`
|
||||||
|
|
||||||
Минимум для RDP-монитора на всех ПК/серверах:
|
|
||||||
|
|
||||||
| Файл | Назначение |
|
| Файл | Назначение |
|
||||||
|------|------------|
|
|------|------------|
|
||||||
| `Login_Monitor.ps1` | Основной скрипт (логика мониторинга; без локальных секретов). |
|
| `Login_Monitor.ps1` | Основной скрипт мониторинга |
|
||||||
| `Sac-Client.ps1` | Клиент Security Alert Center (обязателен для SAC, копируется рядом с монитором). |
|
| `Sac-Client.ps1` | Клиент SAC (обязателен для SAC; сверка SHA256 при деплое) |
|
||||||
| `login_monitor.settings.example.ps1` | Образец настроек на шаре (Telegram, SAC, SMTP, 4740). |
|
| `login_monitor.settings.example.ps1` | Образец настроек (bootstrap локального settings) |
|
||||||
| `version.txt` | **Одна строка** — номер версии пакета на шаре (см. раздел «Версии» ниже). |
|
| `version.txt` | **Одна строка** — версия пакета на шаре (например `1.2.26-SAC`) |
|
||||||
| `Deploy-LoginMonitor.ps1` | Установщик: сравнивает версию, копирует монитор и Sac-Client, вызывает `-InstallTasks`, при необходимости запускает процесс монитора. |
|
| `Deploy-LoginMonitor.ps1` | Установщик для GPO / scheduled task |
|
||||||
|
|
||||||
Полный список файлов для публикации на шару — в [deploy-netlogon-publish.md](deploy-netlogon-publish.md).
|
Полный список файлов на шару (включая Exchange): [deploy-netlogon-publish.md](deploy-netlogon-publish.md).
|
||||||
|
|
||||||
## Как это работает
|
**Не копируются Deploy-LoginMonitor:** `ignore.lst`, `login_monitor.settings.ps1` (секреты локальны).
|
||||||
|
|
||||||
1. **`Deploy-LoginMonitor.ps1`** определяет корень дистрибутива:
|
## Алгоритм Deploy (GPO startup / scheduled task)
|
||||||
- параметр **`-SourceShareRoot`** `\\server\share\RDP-login-monitor`, **или**
|
|
||||||
- если скрипт запущен по UNC, берётся **родительская папка** этого файла.
|
|
||||||
|
|
||||||
2. Читается **`version.txt`** на шаре и сравнивается с локальной меткой **`deployed_version.txt`**. Если метки нет — подтягивается **`$ScriptVersion`** из установленного **`Login_Monitor.ps1`**.
|
```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]
|
||||||
|
```
|
||||||
|
|
||||||
3. Версия на шаре **совпадает** с локальной — выход **без копирования**, **кроме** случаев:
|
Корень дистрибутива: **`-SourceShareRoot`** или родитель каталога `Deploy-LoginMonitor.ps1` при запуске по UNC.
|
||||||
- на ПК **нет** `Sac-Client.ps1` или его SHA256 **отличается** от шары;
|
|
||||||
- в `login_monitor.settings.ps1` **нет** блока SAC (`$UseSAC`, `$SacUrl`, `$SacApiKey`) — тогда добавляется **`UseSAC = 'dual'`** из example (без перезаписи Telegram, если возможно).
|
|
||||||
|
|
||||||
4. Версия на шаре **новее** (или сработало условие выше) — остановка процессов → копирование **`Login_Monitor.ps1`** и **`Sac-Client.ps1`** → настройка SAC в settings при необходимости → **`Login_Monitor.ps1 -InstallTasks`** → **`deployed_version.txt`** → запуск монитора.
|
Локальная метка версии: **`C:\ProgramData\RDP-login-monitor\deployed_version.txt`**. Если файла нет — версия берётся из **`$ScriptVersion`** в установленном `Login_Monitor.ps1`.
|
||||||
|
|
||||||
5. Версия на шаре **старее** — откат блокируется, пока не указан **`-AllowDowngrade`**.
|
### Когда деплой **не** копирует файлы
|
||||||
|
|
||||||
Лог: **`C:\ProgramData\RDP-login-monitor\Logs\deploy.log`**.
|
Версия на шаре **совпадает** с локальной **и** одновременно:
|
||||||
|
|
||||||
|
- 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.26-SAC`**) сравниваются **по полной строке**; для порядка версий используется числовой префикс `1.2.26`.
|
||||||
|
|
||||||
|
Лог: **`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`
|
||||||
|
|
||||||
|
Подавление шума WinRM (HealthMailbox, loopback) и лишних **4624 LT3**.
|
||||||
|
|
||||||
|
**Мониторинг очередей транспорта и правил пересылки** — другой скрипт, **не** через GPO RDP-монитора:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\B26\NETLOGON\RDP-login-monitor\Deploy-DomainMonitors.ps1" -Target Exchange
|
||||||
|
```
|
||||||
|
|
||||||
|
Подробно: [exchange-mail-security.md](exchange-mail-security.md).
|
||||||
|
|
||||||
## Локальные настройки: `login_monitor.settings.ps1`
|
## Локальные настройки: `login_monitor.settings.ps1`
|
||||||
|
|
||||||
На каждом компьютере: **`C:\ProgramData\RDP-login-monitor\login_monitor.settings.ps1`**.
|
Путь: **`C:\ProgramData\RDP-login-monitor\login_monitor.settings.ps1`**.
|
||||||
|
|
||||||
- Секреты и параметры сайта (Telegram, SMTP, **4740**, `$IgnoreAdvapiNetworkLogonSourceIps`) — **только** в этом файле.
|
| Действие Deploy | Условие |
|
||||||
- Образец в репозитории и на шаре: **`login_monitor.settings.example.ps1`**.
|
|-----------------|--------|
|
||||||
- **`Deploy-LoginMonitor.ps1`** **не перезаписывает** существующий `login_monitor.settings.ps1`, если SAC уже настроен (`UseSAC` не `off`, заданы `$SacUrl` и `$SacApiKey`).
|
| Копирует example → settings | Файла settings ещё нет |
|
||||||
- Если файла нет — Deploy **один раз** копирует example → settings (**`UseSAC = 'dual'`**).
|
| Дописывает блок SAC из example | Нет `$UseSAC` / `$SacUrl` / `$SacApiKey` |
|
||||||
- Если файл есть, но **нет блока SAC** — Deploy **дописывает** блок из example (Telegram/SMTP не трогает).
|
| **Не перезаписывает** целиком | SAC уже настроен (`UseSAC` не `off`, ключ и URL заданы) |
|
||||||
- Если **нет** строки `$ServerDisplayName` — Deploy **дописывает** закомментированную подсказку `# $ServerDisplayName = '<имя ПК>'`.
|
| Подсказка `# $ServerDisplayName = '<COMPUTERNAME>'` | Строки `$ServerDisplayName` нет |
|
||||||
- Если **нет** `$DailyReportEnabled` — Deploy **дописывает** закомментированную подсказку `# $DailyReportEnabled = $false` (суточный отчёт только из SAC). Если в файле ошибочно `= false` без `$` — Deploy **исправляет** на `$false`.
|
| Подсказка / починка `$DailyReportEnabled` | Нет переменной или `= false` без `$` → `$false` |
|
||||||
- На сервере с **ролью Exchange** Deploy **дописывает** (если строк нет): `${Ignore4624-LT3-EmptyIP-Event} = $true`, `$WinRmIgnoreLocalSource = 1`, `$WinRmIgnoreMachineAccounts = 1` — подавление HealthMailbox/локального WinRM и шумовых 4624 LT3.
|
| Exchange noise (см. выше) | Роль Exchange и нет соответствующих строк |
|
||||||
|
|
||||||
|
Секреты (Telegram, **`sac_*`**, SMTP, 4740) правятся **вручную** на машине.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$root = 'C:\ProgramData\RDP-login-monitor'
|
$root = 'C:\ProgramData\RDP-login-monitor'
|
||||||
@@ -60,48 +109,41 @@ Copy-Item '\\B26\NETLOGON\RDP-login-monitor\login_monitor.settings.example.ps1'
|
|||||||
notepad (Join-Path $root 'login_monitor.settings.ps1')
|
notepad (Join-Path $root 'login_monitor.settings.ps1')
|
||||||
```
|
```
|
||||||
|
|
||||||
DPAPI: **`Encrypt-DpapiForRdpMonitor.ps1`** — строки Base64 в settings.
|
DPAPI: **`Encrypt-DpapiForRdpMonitor.ps1`**.
|
||||||
|
|
||||||
## Опционально: `ignore.lst`
|
### Security Alert Center
|
||||||
|
|
||||||
Файл **`C:\ProgramData\RDP-login-monitor\ignore.lst`** — подавление отдельных алертов **4624/4625/4740**. Синтаксис — в **[README.md](../README.md)** (раздел 7) и **`ignore.lst.example`**. Deploy с шары **`ignore.lst` не копирует**.
|
```powershell
|
||||||
|
$UseSAC = 'dual' # off | exclusive | dual | fallback
|
||||||
|
$SacUrl = 'https://sac.kalinamall.ru'
|
||||||
|
$SacApiKey = 'sac_...'
|
||||||
|
```
|
||||||
|
|
||||||
## Опционально на КД: блокировки AD (4740)
|
Проверка: **`Login_Monitor.ps1 -CheckSac`**. После правок settings — **`Restart-RdpLoginMonitor.ps1`** или **`-RequestRestart`**.
|
||||||
|
|
||||||
Включается только если монитор запущен на КД с именем **`$LockoutMonitorDomainController`**. Параметры задаются в **`login_monitor.settings.ps1`** на этом КД (`$NetBiosDomainName`, `$ExchangeIisLogPath`, …).
|
## Задачи, heartbeat, ignore.lst
|
||||||
|
|
||||||
## Heartbeat и watchdog
|
| Задача | Назначение |
|
||||||
|
|--------|------------|
|
||||||
- **`Logs\last_heartbeat.txt`** — обновление по **`$HeartbeatInterval`** (по умолчанию 1 ч).
|
|
||||||
- Нет обновления дольше **`$HeartbeatStaleAlertMultiplier × интервал`** — оповещение.
|
|
||||||
- Задача **`RDP-Login-Monitor-Watchdog`** — каждые 5 мин проверяет процесс и поднимает при падении.
|
|
||||||
|
|
||||||
## Задачи планировщика (`-InstallTasks`)
|
|
||||||
|
|
||||||
| Имя | Назначение |
|
|
||||||
|-----|------------|
|
|
||||||
| **`RDP-Login-Monitor`** | Запуск при старте ОС |
|
| **`RDP-Login-Monitor`** | Запуск при старте ОС |
|
||||||
| **`RDP-Login-Monitor-Watchdog`** | Контроль процесса каждые 5 мин |
|
| **`RDP-Login-Monitor-Watchdog`** | Контроль процесса каждые 5 мин |
|
||||||
|
|
||||||
Проверка:
|
Логи: **`login_monitor.log`**, **`watchdog.log`**, **`Logs\last_heartbeat.txt`**.
|
||||||
|
|
||||||
```powershell
|
**`ignore.lst`** — локально, Deploy не копирует. Синтаксис: [README.md](../README.md) (раздел 7).
|
||||||
Get-ScheduledTask -TaskName 'RDP-Login-Monitor','RDP-Login-Monitor-Watchdog' -ErrorAction SilentlyContinue
|
|
||||||
```
|
|
||||||
|
|
||||||
Логи: **`login_monitor.log`**, **`watchdog.log`**.
|
**4740 на КД:** только если имя узла совпадает с **`$LockoutMonitorDomainController`** в settings на этом КД.
|
||||||
|
|
||||||
## GPO (автозагрузка): проверенная схема
|
## GPO и периодический deploy
|
||||||
|
|
||||||
1. Файлы на `\\B26\NETLOGON\RDP-login-monitor\`
|
1. Файлы на `\\B26\NETLOGON\RDP-login-monitor\` (`update-rdp-monitor.ps1` на DC публикации).
|
||||||
2. GPO на OU **компьютеров** → **Сценарии PowerShell** автозагрузки → `Deploy-LoginMonitor.ps1`
|
2. GPO на OU **компьютеров** → **Сценарии PowerShell** автозагрузки → `Deploy-LoginMonitor.ps1`.
|
||||||
3. Security Filtering: группа компьютеров (например `B26\RDP-Login`), права Read + Apply GPO
|
3. Security Filtering: группа компьютеров; на шару — Read для **SYSTEM** / Domain Computers.
|
||||||
4. Доступ на шару для **SYSTEM** / Domain Computers
|
4. После смены membership — **перезагрузка** (не только `gpupdate`).
|
||||||
5. После смены membership — **перезагрузка** (не только `gpupdate`)
|
|
||||||
|
|
||||||
**Нюансы:** UNC в NETLOGON не копируется в SYSVOL GPO — это нормально. Deploy после `-InstallTasks` делает `schtasks /Run` для немедленного старта монитора.
|
Deploy после `-InstallTasks` запускает монитор; задача **`RDP-Login-Monitor`** поднимет его при следующей загрузке.
|
||||||
|
|
||||||
### Периодический Deploy на серверах без перезагрузок
|
**Серверы без частых перезагрузок:**
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File ".\Install-DeployScheduledTask.ps1" `
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File ".\Install-DeployScheduledTask.ps1" `
|
||||||
@@ -111,7 +153,7 @@ powershell.exe -NoProfile -ExecutionPolicy Bypass -File ".\Install-DeploySchedul
|
|||||||
-RunNow
|
-RunNow
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ручной deploy
|
**Ручной deploy** (от администратора):
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\B26\NETLOGON\RDP-login-monitor\Deploy-LoginMonitor.ps1"
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\B26\NETLOGON\RDP-login-monitor\Deploy-LoginMonitor.ps1"
|
||||||
@@ -119,124 +161,61 @@ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\B26\NETLOGON\RDP-logi
|
|||||||
|
|
||||||
Параметры: **`-WhatIf`**, **`-SkipStartMonitorAfterUpdate`**, **`-AllowDowngrade`**.
|
Параметры: **`-WhatIf`**, **`-SkipStartMonitorAfterUpdate`**, **`-AllowDowngrade`**.
|
||||||
|
|
||||||
## Обновление на любой Windows-машине (чеклист)
|
## Обновление: чеклист
|
||||||
|
|
||||||
Цель: новые **`Login_Monitor.ps1`**, **`Sac-Client.ps1`**, при необходимости настройки SAC — без ручного копирования с рабочей станции.
|
### A. Публикация на шару (один раз на релиз)
|
||||||
|
|
||||||
### A. Один раз: публикация на шару (сервер, где есть git)
|
|
||||||
|
|
||||||
1. На DC3 (или другом хосте публикации):
|
|
||||||
```powershell
|
|
||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monitor.ps1
|
|
||||||
```
|
|
||||||
Скрипт делает `git pull` с **git.kalinamall.ru** и копирует файлы в `\\b26\NETLOGON\RDP-login-monitor\`.
|
|
||||||
|
|
||||||
2. Убедитесь, что на шаре есть **`Sac-Client.ps1`** и в **`version.txt`** — новая версия (например `1.2.0-SAC`).
|
|
||||||
|
|
||||||
### B. На каждой целевой машине (автоматически)
|
|
||||||
|
|
||||||
Если настроена GPO / задача с **`Deploy-LoginMonitor.ps1`** — достаточно дождаться запуска Deploy (при старте ОС, по расписанию или после `gpupdate /force` + перезагрузки).
|
|
||||||
|
|
||||||
Deploy **сам**:
|
|
||||||
- сравнит `version.txt` на шаре с `C:\ProgramData\RDP-login-monitor\deployed_version.txt`;
|
|
||||||
- скопирует **`Login_Monitor.ps1`** и **`Sac-Client.ps1`**;
|
|
||||||
- перерегистрирует задачи (`-InstallTasks`);
|
|
||||||
- **не трогает** `login_monitor.settings.ps1`.
|
|
||||||
|
|
||||||
### C. Ручное обновление одной машины (без GPO)
|
|
||||||
|
|
||||||
От **администратора** PowerShell:
|
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass `
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monitor.ps1
|
||||||
-File "\\b26\NETLOGON\RDP-login-monitor\Deploy-LoginMonitor.ps1"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Проверка:
|
Проверьте на шаре **`Sac-Client.ps1`** и **`version.txt`** (например `1.2.26-SAC`).
|
||||||
|
|
||||||
|
### B. На целевых машинах
|
||||||
|
|
||||||
|
GPO или scheduled task — дождаться startup / `-RunNow`. Ручная проверка:
|
||||||
|
|
||||||
```powershell
|
```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'
|
Select-String -Path 'C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1' -Pattern 'ScriptVersion'
|
||||||
Test-Path 'C:\ProgramData\RDP-login-monitor\Sac-Client.ps1'
|
Test-Path 'C:\ProgramData\RDP-login-monitor\Sac-Client.ps1'
|
||||||
Get-ScheduledTask -TaskName 'RDP-Login-Monitor','RDP-Login-Monitor-Watchdog' -ErrorAction SilentlyContinue
|
Get-ScheduledTask -TaskName 'RDP-Login-Monitor','RDP-Login-Monitor-Watchdog' -ErrorAction SilentlyContinue
|
||||||
Get-Content 'C:\ProgramData\RDP-login-monitor\Logs\deploy.log' -Tail 15
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Graceful restart (без убийства PowerShell)
|
Повторный запуск Deploy без смены версии должен дать **`Актуально, копирование не требуется`**.
|
||||||
|
|
||||||
После правки **`login_monitor.settings.ps1`** (SAC, Telegram):
|
### C. Graceful restart
|
||||||
|
|
||||||
|
После правки settings (без смены `Login_Monitor.ps1`):
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass `
|
powershell.exe -NoProfile -ExecutionPolicy Bypass `
|
||||||
-File "C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1" -RequestRestart
|
-File "C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1" -RequestRestart
|
||||||
```
|
```
|
||||||
|
|
||||||
Или скрипт из репозитория/шары: **`Restart-RdpLoginMonitor.ps1`**.
|
После Deploy нового **`Login_Monitor.ps1`** — recycle:
|
||||||
|
|
||||||
Чтобы подхватить **новый `Login_Monitor.ps1` с диска** (после Deploy), нужен **recycle** — новый скрытый процесс, старый завершается сам:
|
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass `
|
powershell.exe -NoProfile -ExecutionPolicy Bypass `
|
||||||
-File "C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1" -RequestRestart -Recycle
|
-File "C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1" -RequestRestart -Recycle
|
||||||
```
|
```
|
||||||
|
|
||||||
**`Deploy-LoginMonitor.ps1`** записывает **`restart.request`** напрямую (без дочернего PowerShell) и ждёт до **35 с**; **`Stop-Process -Force`** только если таймаут.
|
**`Deploy-LoginMonitor.ps1`** пишет **`restart.request`**, ждёт до **35 с**, затем **`Stop-Process -Force`** только при таймауте.
|
||||||
|
|
||||||
Сигнал: файл **`C:\ProgramData\RDP-login-monitor\restart.request`** (создаётся автоматически, не редактировать вручную).
|
## Версии
|
||||||
|
|
||||||
### D. Первичная установка (ещё нет ProgramData)
|
| Файл | Роль |
|
||||||
|
|------|------|
|
||||||
1. Deploy (как в C) — создаст каталог и при отсутствии settings скопирует **`login_monitor.settings.ps1`** из example.
|
|
||||||
2. Отредактируйте **`C:\ProgramData\RDP-login-monitor\login_monitor.settings.ps1`** (SAC, при необходимости 4740).
|
|
||||||
3. Проверка SAC:
|
|
||||||
```powershell
|
|
||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass `
|
|
||||||
-File 'C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1' -CheckSac
|
|
||||||
```
|
|
||||||
|
|
||||||
## Security Alert Center (SAC)
|
|
||||||
|
|
||||||
В **`login_monitor.settings.ps1`** на машине (не перезаписывается Deploy):
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
$UseSAC = 'dual' # off | exclusive | dual | fallback
|
|
||||||
$SacUrl = 'https://sac.kalinamall.ru'
|
|
||||||
$SacApiKey = 'sac_...' # ключ из SAC
|
|
||||||
```
|
|
||||||
|
|
||||||
Режимы:
|
|
||||||
- **`dual`** — SAC + Telegram (рекомендуется на переходе);
|
|
||||||
- **`exclusive`** — только SAC;
|
|
||||||
- **`fallback`** — SAC, при сбоях — Telegram.
|
|
||||||
|
|
||||||
После правок settings перезапуск не обязателен: watchdog поднимет процесс; для проверки:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
powershell.exe -NoProfile -ExecutionPolicy Bypass `
|
|
||||||
-File 'C:\ProgramData\RDP-login-monitor\Login_Monitor.ps1' -CheckSac
|
|
||||||
```
|
|
||||||
|
|
||||||
В SAC UI: **Отчёты** / **События** — события `rdp.login.*`, `report.daily.rdp`, `agent.heartbeat`.
|
|
||||||
|
|
||||||
### Диагностика
|
|
||||||
|
|
||||||
- Group Policy Operational log
|
|
||||||
- `Logs\deploy.log`, `login_monitor.log`, `watchdog.log`
|
|
||||||
|
|
||||||
## Версии: `version.txt` и `$ScriptVersion`
|
|
||||||
|
|
||||||
| Что | Роль |
|
|
||||||
|-----|------|
|
|
||||||
| **`version.txt` на шаре** | Триггер обновления для Deploy |
|
| **`version.txt` на шаре** | Триггер обновления для Deploy |
|
||||||
| **`$ScriptVersion` в скрипте** | Версия в логах и Telegram |
|
| **`deployed_version.txt` локально** | Метка после успешного деплоя |
|
||||||
|
| **`$ScriptVersion` в Login_Monitor.ps1** | Версия в логах и Telegram |
|
||||||
|
|
||||||
Поднимайте **`version.txt`** при каждой выкладке на NETLOGON.
|
Поднимайте **`version.txt`** при каждой выкладке на NETLOGON; строка в **`version.txt`** и **`$ScriptVersion`** должны совпадать (включая суффикс `-SAC`).
|
||||||
|
|
||||||
## Безопасность
|
## Безопасность и UNC
|
||||||
|
|
||||||
- Ограничьте ACL на шару (в example/settings могут быть секреты для домена B26).
|
- Ограничьте ACL на шару (в example могут быть доменные секреты).
|
||||||
- DPAPI: **`Encrypt-DpapiForRdpMonitor.ps1`** (значения в **`login_monitor.settings.ps1`**)
|
- DPAPI для токенов в **`login_monitor.settings.ps1`**.
|
||||||
- Внутренний git (git.kalinamall.ru): доверенный; секреты допустимы в **`login_monitor.settings.example.ps1`**
|
- При ошибках подписи с FQDN-шары: короткое имя DC и **`-ExecutionPolicy Bypass`**.
|
||||||
|
|
||||||
## UNC и ExecutionPolicy
|
Диагностика: Group Policy Operational log, **`Logs\deploy.log`**, **`deploy_installtasks_*.log`**.
|
||||||
|
|
||||||
При ошибках подписи с FQDN-шары используйте короткое имя DC: `\\DC01\NETLOGON\...` и **`powershell.exe -ExecutionPolicy Bypass -File "..."`**.
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
Скрипт **`Exchange-MailSecurity.ps1`** предназначен **только для сервера Microsoft Exchange** с Exchange Management Shell (EMS). Не устанавливается на все компьютеры домена через GPO RDP-монитора.
|
Скрипт **`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).
|
||||||
|
|
||||||
## Назначение
|
## Назначение
|
||||||
|
|
||||||
| Функция | Режим | Расписание (задача планировщика) |
|
| Функция | Режим | Расписание (задача планировщика) |
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ PowerShell-набор для мониторинга входов в Windows с
|
|||||||
- Документация по развёртыванию: **[Docs/README.md](Docs/README.md)** (RDP-монитор, Exchange, NETLOGON).
|
- Документация по развёртыванию: **[Docs/README.md](Docs/README.md)** (RDP-монитор, Exchange, NETLOGON).
|
||||||
- **`Encrypt-DpapiForRdpMonitor.ps1`** — опционально для подготовки DPAPI-строк токена/chat id и пароля SMTP (`$MailSmtpPasswordProtectedB64` в файле настроек).
|
- **`Encrypt-DpapiForRdpMonitor.ps1`** — опционально для подготовки DPAPI-строк токена/chat id и пароля SMTP (`$MailSmtpPasswordProtectedB64` в файле настроек).
|
||||||
- **Локальные настройки RDP-монитора:** **`login_monitor.settings.ps1`** в каталоге установки (образец **`login_monitor.settings.example.ps1`**). При автообновлении **`Login_Monitor.ps1`** с шары файл настроек **не перезаписывается** (как **`exchange_monitor.settings.ps1`** для Exchange).
|
- **Локальные настройки RDP-монитора:** **`login_monitor.settings.ps1`** в каталоге установки (образец **`login_monitor.settings.example.ps1`**). При автообновлении **`Login_Monitor.ps1`** с шары файл настроек **не перезаписывается** (как **`exchange_monitor.settings.ps1`** для Exchange).
|
||||||
- **Security Alert Center (SAC):** модуль **`Sac-Client.ps1`** (копируется вместе с `Login_Monitor.ps1`). Режимы **`$UseSAC`**: `off` | `exclusive` | `dual` | `fallback` — контракт в репозитории **security-alert-center** (`docs/agent-integration.md`). Версия релиза: **`$ScriptVersion`** и **`version.txt`** (сейчас **1.2.17-SAC**); **`Sac-Client.ps1`** передаёт ту же версию в SAC (`product_version`).
|
- **Security Alert Center (SAC):** модуль **`Sac-Client.ps1`** (копируется вместе с `Login_Monitor.ps1`). Режимы **`$UseSAC`**: `off` | `exclusive` | `dual` | `fallback` — контракт в репозитории **security-alert-center** (`docs/agent-integration.md`). Версия релиза: **`$ScriptVersion`** и **`version.txt`** (сейчас **1.2.26-SAC**); **`Sac-Client.ps1`** передаёт ту же версию в SAC (`product_version`).
|
||||||
|
|
||||||
## Что изменилось (важное)
|
## Что изменилось (важное)
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ PowerShell-набор для мониторинга входов в Windows с
|
|||||||
- **`auditpol` на русской Windows**: настройка/проверка аудита опирается на категорию **`Вход/выход`** и подкатегории **`Вход в систему` / `Выход из системы`** (ожидается строка **`Успех и сбой`**). Это устраняет ошибки вида `0x00000057` из‑за несуществующего на RU ОС имени `Logon`.
|
- **`auditpol` на русской Windows**: настройка/проверка аудита опирается на категорию **`Вход/выход`** и подкатегории **`Вход в систему` / `Выход из системы`** (ожидается строка **`Успех и сбой`**). Это устраняет ошибки вида `0x00000057` из‑за несуществующего на RU ОС имени `Logon`.
|
||||||
- **Стабильность**: `auditpol` вызывается по полному пути `%SystemRoot%\System32\auditpol.exe` (без зависимости от PATH), stdout+stderr объединяются через `ProcessStartInfo`.
|
- **Стабильность**: `auditpol` вызывается по полному пути `%SystemRoot%\System32\auditpol.exe` (без зависимости от PATH), stdout+stderr объединяются через `ProcessStartInfo`.
|
||||||
- **Агрегация 4625 (брутфорс)**: при включённом `$FailedLogonRateLimitEnabled` — уровень 1: **5** неудачных попыток за **60** с с одного источника для **одной** учётной записи (IP+user); уровень 2: **12** попыток за **60** с с одного IP (несколько логинов). Пока порог не достигнут — поштучные 4625; при всплеске — сводные алерты, одиночные подавляются. Параметры в начале `Login_Monitor.ps1`. Автоблокировка IP не выполняется.
|
- **Агрегация 4625 (брутфорс)**: при включённом `$FailedLogonRateLimitEnabled` — уровень 1: **5** неудачных попыток за **60** с с одного источника для **одной** учётной записи (IP+user); уровень 2: **12** попыток за **60** с с одного IP (несколько логинов). Пока порог не достигнут — поштучные 4625; при всплеске — сводные алерты, одиночные подавляются. Параметры в начале `Login_Monitor.ps1`. Автоблокировка IP не выполняется.
|
||||||
- **Exchange Mail Security** (`Exchange-MailSecurity.ps1`): на **сервере Exchange** — очереди, пересылка на внешние адреса, watchdog. Руководство: **[Docs/exchange-mail-security.md](Docs/exchange-mail-security.md)**.
|
- **Exchange Mail Security** (`Exchange-MailSecurity.ps1`): на **сервере Exchange** — очереди, пересылка на внешние адреса, watchdog. Руководство: **[Docs/exchange-mail-security.md](Docs/exchange-mail-security.md)**. GPO **`Deploy-LoginMonitor.ps1`** на MailServer ставит тот же RDP-монитор и дописывает WinRM/4624 noise в **`login_monitor.settings.ps1`**; **`Deploy-DomainMonitors.ps1 -Target Exchange`** — отдельно.
|
||||||
|
|
||||||
## 1) Подготовка
|
## 1) Подготовка
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user