opened image

RDP‑мониторинг: аудит событий, мгновенные алерты в Telegram или email

Ни один «логгер» не поможет, если не включены корректные политики аудита. Правильная конфигурация даёт:

  • прозрачность: кто/когда/откуда вошёл по RDP;

  • быстрые алерты при неожиданных входах;

  • доказательную базу при инцидентах.

 

 

Включаем аудит входов/выходов и RDP‑сессий

 

Выполните от имени администратора (PowerShell или CMD):

REM Базовый аудит входов/выходов
AuditPol /set /subcategory:"Logon" /success:enable /failure:enable
AuditPol /set /subcategory:"Logoff" /success:enable
AuditPol /set /subcategory:"Special Logon" /success:enable
AuditPol /set /subcategory:"Logon with explicit credentials" /success:enable /failure:enable

REM Дополнительные события логона/логаута (RDP‑сессии, тайм-ауты и т.п.)
AuditPol /set /subcategory:"Other Logon/Logoff Events" /success:enable /failure:enable

REM Рекомендуется: отслеживание изменений политик аутентификации/авторизации
AuditPol /set /subcategory:"Authentication Policy Change" /success:enable /failure:enable
AuditPol /set /subcategory:"Authorization Policy Change" /success:enable /failure:enable

 

Проверить состояние:

AuditPol /get /category:"Logon/Logoff"

 

Где смотреть события:

журнал безопасности Event Viewer → Windows Logs → Security

 

Ключевые события:

  • 4624 — успешный вход (RDP = LogonType 10)

  • 4625 — неудачный вход (ошибка пароля, несуществующая учётка и т.п.)

  • 4634 — выход из системы

  • 4778/4779 — подключение/отключение от RDP‑сеанса

Фильтрация RDP: LogonType = 10 (RemoteInteractive)

 

 

Создаем триггер на событие

 

Мы будем запускать PowerShell‑скрипт только когда срабатывает RDP‑событие (например, 4624 с LogonType=10). Это делается через Планировщик заданий с Event Trigger.

 

Вариант A. Через графический интерфейс

  1. Откройте Event Viewer → Windows Logs → Security.

  2. Отфильтруйте события по ID = 4624.

  3. Найдите любую успешную RDP‑событие (вкладка DetailsEventData → LogonType = 10).

  4. Правый клик → Attach Task To This Event…

  5. Имя: RDP_Alert_On_4624_Lt10

  6. Действие: Start a Programpowershell.exe

  7. Аргументы:

    -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\RdpAlert.ps1"
    
  8. Готово.

 

Затем отредактируйте триггер → вкладка TriggersEdit… → вкладка CustomNew Event FilterXMLEdit query manually и вставьте точный XML‑фильтр:

<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">
      *[System[(EventID=4624)]]
      and
      *[EventData[Data[@Name='LogonType']='10']]
    </Select>
  </Query>
</QueryList>

 

Вариант B. Одной командой

 

Создайте задачу через schtasks:

schtasks /Create /TN "RDP_Alert_On_4624_Lt10" ^
  /SC ONEVENT ^
  /EC Security ^
  /MO "*[System[(EventID=4624)]] and *[EventData[Data[@Name='LogonType']='10']]" ^
  /TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\RdpAlert.ps1" ^
  /RU SYSTEM

Аналогично можно создать задачи для 4625 (неудачные входы) и для 4778/4779 (подключение/отключение сеансов).

 

 

Скрипт уведомлений (Telegram и/или email)

 

Создайте папку и скрипт:

New-Item -ItemType Directory -Path C:\Scripts -Force | Out-Null
notepad C:\Scripts\RdpAlert.ps1

 

Вставьте скрипт ниже и сохраните.

 

🔔 RdpAlert.ps1 — универсальный алёртер

  • Парсит полученное событие;

  • Проверяет «белый список» аккаунтов/IP;

  • Проверяет «разрешённые часы»;

  • Шлёт алерт в Telegram и/или на email.

Заполните константы $BotToken, $ChatId, $Smtp*.

 

# RdpAlert.ps1
# Работает как целевое действие в Task Scheduler (ONEVENT). Не требует резидентного агента.

param()

# -------------------- Настройки --------------------
# Telegram Bot API
$BotToken = "123456789:REPLACE_WITH_YOUR_BOT_TOKEN"
$ChatId   = "REPLACE_WITH_YOUR_CHAT_ID"     # например, свой user/chat id

# Email SMTP (по желанию)
$SmtpServer   = "smtp.example.com"
$SmtpPort     = 587
$SmtpFrom     = "rdp-alert@example.com"
$SmtpTo       = "security@example.com"
$SmtpUser     = "rdp-alert@example.com"
$SmtpPassword = "REPLACE_WITH_PASSWORD"
$UseTLS       = $true

# Бизнес-логика: белый список и рабочие часы
$AllowedUsers = @('Administrator','svc.admin')        # ожидаемые аккаунты
$AllowedIPs   = @('203.0.113.10','198.51.100.25')     # строками
$WorkingHours = 8..20                                  # разрешённые часы (локальное время сервера)
$AlertOnWorkingHoursOnly = $false                      # если true — алерты только в рабочие часы

# Посылать дубль e-mail?
$SendEmail = $false

# -------------------- Вспомогательные функции --------------------
function Send-Telegram {
    param(
        [string]$Text
    )
    try {
        $uri = "https://api.telegram.org/bot$BotToken/sendMessage"
        $body = @{
            chat_id = $ChatId
            text    = $Text
            parse_mode = "HTML"
            disable_web_page_preview = $true
        }
        Invoke-RestMethod -Method Post -Uri $uri -Body $body -ErrorAction Stop | Out-Null
    } catch {
        # Лог ошибки в локальный файл
        Add-Content -Path "C:\Scripts\RdpAlert.log" -Value ("Telegram error: " + $_.Exception.Message)
    }
}

function Send-Mail {
    param(
        [string]$Subject,
        [string]$Body
    )
    try {
        $secure = ConvertTo-SecureString $SmtpPassword -AsPlainText -Force
        $cred   = New-Object System.Management.Automation.PSCredential($SmtpUser, $secure)

        Send-MailMessage -To $SmtpTo -From $SmtpFrom -Subject $Subject -Body $Body `
            -SmtpServer $SmtpServer -Port $SmtpPort -UseSsl:$UseTLS -Credential $cred -ErrorAction Stop
    } catch {
        Add-Content -Path "C:\Scripts\RdpAlert.log" -Value ("SMTP error: " + $_.Exception.Message)
    }
}

# -------------------- Получение контекста события --------------------
# Когда задача запускается триггером ONEVENT, последняя событие доступно так:
# $Args[0] может содержать XML события; в Task Scheduler этого нет,
# поэтому дочитываем последнее событие, подходящее под фильтр (4624 + LogonType=10).
$evt = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 50 |
       Where-Object {
            ($_.Properties | Where-Object { $_.Value -eq '10' }).Count -gt 0
       } |
       Select-Object -First 1

if (-not $evt) { exit 0 }

# Разбор EventData
$xml = [xml]$evt.ToXml()
$data = @{}
foreach ($d in $xml.Event.EventData.Data) {
    $name = $d.Name
    if (-not [string]::IsNullOrEmpty($name)) { $data[$name] = [string]$d.'#text' }
}

# Типовые поля
$TargetUser   = $data['TargetUserName']
$IpAddress    = $data['IpAddress']
$Workstation  = $data['WorkstationName']
$LogonType    = $data['LogonType']
$LogonProcess = $data['LogonProcessName']
$AuthPackage  = $data['AuthenticationPackageName']
$When = $evt.TimeCreated

# -------------------- Бизнес‑правила --------------------
$hour = (Get-Date).Hour
$hourOk = $WorkingHours -contains $hour
$ipOk   = ($IpAddress -and ($AllowedIPs -contains $IpAddress))
$userOk = ($TargetUser -and ($AllowedUsers -contains $TargetUser))

$expected = ($ipOk -or $userOk) -and ($AlertOnWorkingHoursOnly ? $hourOk : $true)

# Формируем сообщение
$header = if ($expected) { "✅ Expected/Allowed RDP logon" } else { "🚨 RDP logon ALERT" }
$msg = @"
$header

Time:        $When
User:        $TargetUser
Source IP:   $IpAddress
Workstation: $Workstation
LogonType:   $LogonType
Process:     $LogonProcess
AuthPkg:     $AuthPackage
EventID:     4624 (Success Logon)

Host:        $(hostname)
"@

# Условие уведомления: шлём всегда, или только при неожиданных событиях
$send = $true   # смените на: (!$expected) — если хотите тревожить только о неожиданных

# Отправка
if ($send) {
    Send-Telegram -Text $msg
    if ($SendEmail) {
        Send-Mail -Subject "[RDP] $header on $(hostname)" -Body $msg
    }
}

 

 

Хотите алерт только при неожиданных входах? В скрипте смените $send = $true на:

$send = (!$expected)

 

 

Добавьте ещё триггеры (необязательно, но полезно)

 

  • Неудачные входы (4625) — подбор пароля, ошибки логина:

    schtasks /Create /TN "RDP_Alert_On_4625" ^
      /SC ONEVENT /EC Security ^
      /MO "*[System[(EventID=4625)]] and *[EventData[Data[@Name='LogonType']='10']]" ^
      /TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\RdpAlert.ps1" ^
      /RU SYSTEM
    

 

  • Подключение/отключение RDP‑сеанса (4778/4779):

    schtasks /Create /TN "RDP_Session_Connect_4778" ^
      /SC ONEVENT /EC Security ^
      /MO "*[System[(EventID=4778)]]" ^
      /TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\RdpAlert.ps1" ^
      /RU SYSTEM
    
    schtasks /Create /TN "RDP_Session_Disconnect_4779" ^
      /SC ONEVENT /EC Security ^
      /MO "*[System[(EventID=4779)]]" ^
      /TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\RdpAlert.ps1" ^
      /RU SYSTEM
    

 

 

Советы по безопасности (практический минимум)

 

  1. Всегда включайте NLA (Network Level Authentication) для RDP.

  2. Ограничьте доступ брандмауэром: разрешайте RDP только с белых IP или через VPN.

  3. 2FA / LAPS (локальные пароли с ротацией), регулярная смена паролей служебных аккаунтов.

  4. Разведите админские учётки и повседневную работу (админ — только для админ‑сессий).

  5. Резервируйте журналы (минимум 512–1024 МБ для Security) и экспортируйте их централизованно.

 

Вариант для многих серверов: Windows Event Forwarding (WEF)

 

Если у вас несколько хостов, вместо того чтобы ставить триггеры на каждом, сделайте:

  • Collector (pull): настройте один сервер как «Windows Event Collector».

  • На серверах‑источниках включите подписки (GPO → Subscriptions).

  • Сделайте одно задание с триггером на Коллекторе по 4624/4625/4778/4779 → запускайте там же RdpAlert.ps1.

 

Это даёт:

  • единую точку настройки алертов и правил;

  • централизованное хранение логов (удобно для ретроспективы/форенсики).

 

Проверка и отладка

  • Убедитесь, что события появляются: Event Viewer → Security (4624/4625/4778/4779).

  • Протестируйте вход по RDP с внешнего IP из белого списка — должно прийти «✅ Expected…».

  • Протестируйте с IP вне списка — должно прийти «🚨 ALERT…».

  • Если Telegram не доходит — проверьте C:\Scripts\RdpAlert.log и токен/чат‑ID.

  • Если email не доходит — проверьте TLS/порт/аккаунты SMTP, не блокирует ли почтовый сервер.

 

Итог

  1. Включили правильный аудит → события RDP появились в Security.

  2. Поставили Event Trigger в Task Scheduler → нет резидентных сервисов, срабатывает только «по факту».

  3. Добавили Telegram/email‑алерты → мгновенное сообщение при входе или при аномалиях.

  4. По желанию — централизация через WEF, дополнительные триггеры на 4625/4778/4779, белые списки/рабочие часы.

Это надёжная, минималистичная и одновременно «боевая» схема: работает на чистом Windows, легко масштабируется и понятна даже непрофессионалам (админу достаточно выполнить приведённые шаги один‑в‑один).