RDS Сервер

Защита сервера удалённых рабочих столов от подбора пароля

Скрипт powershell запускается 1 раз в час, ищет по журналу ip-адреса которые несколько раз пытались залогиниться, затем создает правило брандмауэра и блочит эти айпишники. Отладка и запуск с правами администратора, а в планировщике из под учетки СИСТЕМА. Скрипт не работает без установленной службы!

# количество неудачных попыток входа с одного IP адреса, при достижении которого нужно заблокировать IP
$badAttempts = 5
# Просмотр лога за последние 1 час
$intervalHours = 1
# Если в блокирующем правиле более 100 уникальных IP адресов, создать новое правило Windows Firewall
$ruleMaxEntries = 100
# номер порта, на котором слушает RDP
$RdpLocalPort=3389
# файл с логом работы PowerShell скрипта
$log = "c:\ps\fail2ban-RDP.txt"
# Список доверенных IP адресов, которые нельзя блокировать
$trustedIPs = @("192.168.1.10", "192.168.1.11")
# Телеграм-бот для отправки сообщений. Если не используется, то закомментируем весь блок #Пишем в телегу в конце скрипта
$token = "0000000000:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$chat_id = "00000000000"
$mestext = "%E2%9B%94 Blocked Brute-Force address "

# Поехали: 
$badRDPlogons = Get-WinEvent -FilterHashTable @{LogName='Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational';ID='140';StartTime=([DateTime]::Now.AddHours(-$intervalHours))}
$ipsArray = $badRDPlogons.Properties | group-object -property value | where {$_.Count -gt $Attempts} | Select -property Name
# Удалить доверенные IP адреса 
$ipsArray = $ipsArray.name | Where-Object { $trustedIPs -notcontains $_ }
if ($ipsArray.Count -eq 0) {
    return
}
[System.Collections.ArrayList]$ips = @()
[System.Collections.ArrayList]$current_ip_lists = @()
$ips.AddRange([string[]]$ipsArray)
$ruleCount = 1
$ruleName = "BlockRDPBruteForce" + $ruleCount
$foundRuleWithSpace = 0
while ($foundRuleWithSpace -eq 0) {
    $firewallRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
    if ($null -eq $firewallRule) {
        New-NetFirewallRule -DisplayName $ruleName –RemoteAddress 1.1.1.1 -Direction Inbound -Protocol TCP –LocalPort $RdpLocalPort -Action Block
        $firewallRule = Get-NetFirewallRule -DisplayName $ruleName
        $current_ip_lists.Add(@(($firewallRule | Get-NetFirewallAddressFilter).RemoteAddress))
        $foundRuleWithSpace = 1
    } else {
        $current_ip_lists.Add(@(($firewallRule | Get-NetFirewallAddressFilter).RemoteAddress))
        if ($current_ip_lists[$current_ip_lists.Count – 1].Count -le ($ruleMaxEntries – $ips.Count)) {
            $foundRuleWithSpace = 1
        } else {
            $ruleCount++
            $ruleName = "BlockRDPBruteForce" + $ruleCount
        }
    }
}
# Удалить IP адреса, которые уже есть в правиле 
for ($i = $ips.Count – 1; $i -ge 0; $i--) {
    foreach ($current_ip_list in $current_ip_lists) {
        if ($current_ip_list -contains $ips[$i]) {
            $ips.RemoveAt($i)
            break
        }
    }
}
if ($ips.Count -eq 0) {
    exit
}
#записать в лог
$current_ip_list = $current_ip_lists[$current_ip_lists.Count – 1]
foreach ($ip in $ips) {
    $current_ip_list += $ip
    (Get-Date).ToString().PadRight(22) + ' | ' + $ip.PadRight(15) + ' | The IP address has been blocked due to ' + ($badRDPlogons | Where-Object { $_.IpAddress -eq $ip }).Count + ' failed login attempts over ' + $intervalHours + ' hours in rule ' + $ruleName >> $log
}

#Пишем в телегу
foreach ($ip in $ips) {
    $text = $mestext + $ip.PadRight(15)
    $URI = "https://api.telegram.org/bot" + $token + "/sendMessage?chat_id=" + $chat_id + "&text=" + $text + "&disable_notification=True"
    $Request = Invoke-WebRequest -URI ($URI)
}

# Заблокировать IP в firewall
Set-NetFirewallRule -DisplayName $ruleName -RemoteAddress $current_ip_list