Примитивная защита опубликованного RDP-сервера

Ранее писал про простую, но довольно эффективную «защиту от брутфорсеров», но что делать если у вас нет роутера, на котором можно такую защиту построить?

Можно сделать «наколеночное» примитивное, но все таки работающее решение внутри самого сервера. Единственное ограничение — ОС на сервере должна быть минимум Windows Server 2012 R2.

Итак идея в следующем.

  • в ОС Windows Server с версии 2012 неудачные попытки подключения в RDP-сессию стали отображаться в соответствующем журнале(EventID=140, Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational), с указанием IP подключающегося (в Server 2016 — еще лучше стало, там все в SECURITY лог пишется, и имя пользователя и IP — можно из одного события все данные брать).
  • Делаем в Windows Firewall правило с именем «Block BAD-IP», в котором указываем, что хотим блокировать все соединения с неких IP (при создании правила внесите туда пару тестовых IP, 1.1.1.1 и 2.2.2.2 например). Это правило, вернее его список блокируемых IP мы будем в дальнейшем править скриптом
  • Делаем задание в планировщике, которое стартует при возникновении этого события и запускает скрипт на Powershell. Тут все просто — создать новое задание, триггером указать «When a specific event is logged» и далее указать нужные реквизиты события, назначить Action т.п.
  • Скрипт делает следующее:
    • вычитывает из журнала все события с ID=140 за последние ну скажем 30 минут, получаем из них IP адреса «брутфорсеров».
    • первый элемент массива — это очевидно адрес, на котором сработал скрипт, считаем сколько раз он присутствует в полученном массиве. Если больше порогового значения (например 5) — заносим его в соответствующее правило Windows Firewall
    • Отправляет письмо с сообщением о событии
  • PROFIT!

Ниже сам скрипт. Написан он второпях «на коленке», и наверняка может быть причесан и оптимизирован, тут я даже спорить не стану, если есть желание — меняйте на свое усмотрение.

# скрипт автоматически добавляет в уже существующее (!) правило Windows Firewall IP_адрес, с которого за последние 30 минут было больше 4 попыток входа на терминальный сервер с неправильным логином-паролем
# 
# Сколько времени отступаем назад в минутах
$measureTime=(get-date)-(new-timespan -minute 30)

# Получаем массив(строго массив! даже если там только один адрес!) IP-адресов с которых идет брутфорс. В Windows Server 2012R2 это журнал событий Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational и сообщение с ID=140
[array]$IPs = Get-WinEvent -FilterHashtable @{Logname='Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational'; ID=140; StartTime=$measuretime} -ErrorAction SilentlyContinue | %{[regex]::match($_.message, "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b").value }

# Выясняем сколько раз содержится первый (тот на котором сработал скрипт) элемент массива в собственно полученном массиве адресов. 
#Если этот элемент встречается там больше 4 раз - запускаем действие добавления в правило Firewall, и пишем письмо
#Если нет - просто пишем письмо про это и указываем, что вхождений пока мало

if (($Ips -match $Ips[0]).count -gt 4)
{
# получаем список адресов из правила
$oldList = Get-NetFirewallRule -DisplayName 'Block BAD-IP' | Get-NetFirewallAddressFilter 

# обновляем список адресов
$newList = ($oldList.RemoteIP + $IPs[0])

# назначем новый список адресов в правило
Get-NetFirewallRule -DisplayName 'Block BAD-IP' | Get-NetFirewallAddressFilter | Set-NetFirewallAddressFilter -RemoteAddress $newList

Write-Host "Добавлен адрес: " + $Ips[0]
#region Mail
$smtpsrv         = "smtp.yandex.ru"
$from            = "user-mail@yandex.ru"
$to              = "user-mail@yandex.ru", "user-mail@send.smsc.ru"
$subj            = "ServiceRDP.AddedNewBad-IP-toFirewall. IP=" + $Ips[0]
$body            = "`r`n"
$enc             = [System.Text.Encoding]::UTF8
$usr             = "user-mail@yandex.ru"
$pwd             = ConvertTo-SecureString –String "verystrongpassword" –AsPlainText -Force
$creds           = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $usr, $pwd
#endregion Mail
Send-MailMessage $to $subj $body $smtpsrv -from $from -encoding $enc -credential $creds -useSSL


}
else 
{
Write-host ("IP Адрес: " + $Ips[0] + " содержится в массиве только " + ($Ips -match $Ips[0]).count + " раз")
#region Mail
$smtpsrv         = "smtp.yandex.ru"
$from            = "user-mail@yandex.ru"
$to              = "user-mail@yandex.ru"
$subj            = "ServiceRDP.New Incorrect Username-password from IP=" + $Ips[0] + " Count=" + ($Ips -match $Ips[0]).count
$body            = "`r`n"
$enc             = [System.Text.Encoding]::UTF8
$usr             = "user-mail@yandex.ru"
$pwd             = ConvertTo-SecureString –String "verystrongpassword" –AsPlainText -Force
$creds           = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $usr, $pwd
#endregion Mail
Send-MailMessage $to $subj $body $smtpsrv -from $from -encoding $enc -credential $creds -useSSL
}

Примечания:

  • В правиле Windows Firewall нужно чтобы было изначально пара адресов, иначе тот код что приведен выше не считает их списоком и ругается. Можно сам код поправить (мне лень), а можно просто внести изначально в правило пару адресов вида 1.1.1.1 и 2.2.2.2
  • В скрипте естественно нужно поправить реквизиты отправки почты, указав свои. Кроме того, в случае когда адрес таки добавляется в Firewall-правило, я отправляю письмо также в шлюз Email2SMS, чтобы получить СМС об этом. Чтобы знать. Если просто происходит «срабатывания» от 1 до 4 раз, то СМС об этом получать не обязательно, это и сами пользователи могут ошибаться с паролем.
  • Про сообщения генерируемые в логах при некорректных попытках входа можно подробно почитать тут Очень хорошая статья!
  • У автора вышеуказанной статьи можно взять еще бесплатную утилиту, наглядно показывающую кто когда и как успешно подключался к RDP-Серверу. Называется RDPSoft RDS Log Viewer

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Post Navigation

Яндекс.Метрика