Короткий ответ

Brute force — это поток неуспешных аутентификаций, не «один опечатавшийся Иван». Сначала сохраните логи (Security 4625, auth.log/journalctl -u ssh), иначе ротация или атакующий их сотрут. Затем ограничьте источник: firewall/nft/fail2ban, закрытый WAN, lockout. Не отключайте firewall «чтобы админка открылась». Не публикуйте 22/3389 в интернет как «временное».

Если уже есть Success после пачки Fail — это уже подозрительный вход, не только brute.

Симптомы и как отличить

  • На host.example: тысячи Failed password / Invalid user с 10.0.10.55.
  • На Windows Server: 4625 Status 0xC000006D / sub 0xC000006A (неверный пароль) пачкой; иногда 4740 lockout ivan.petrov.
  • Канал RDP «мигает», sshd держит кучу preauth-процессов.
  • Мониторинг: всплеск на 22/tcp или 3389/tcp.
КартинаЭто не bruteКуда
Один Fail, потом Success с того же корпоративного VPNопечаткане банить /24 офиса
Syn-flood без SSH bannervolumetricсеть/rate, не jail по паролю
Слушатель на странном порту плюс bruteещё backdoorпорт
Fail, затем Acceptedкомпрометациявход

Возможные причины

  1. 22 или 3389 торчат на WAN, парольная аутентификация.
  2. Слабые имена admin/Administrator, нет lockout.
  3. Нет rate-limit/fail2ban, либо jail в detect-only.
  4. IPv6 слушает, jail только на IPv4.
  5. Бот идёт на VPN-портал, а вы смотрите только sshd.
  6. Легитимный сканер уязвимостей без белого списка — выглядит так же, но в заявке SOC он должен быть.

Диагностика

Сохраните сырьё до бана, который может оборвать текущий поток (это нормально, копия важнее «посмотреть ещё пять минут живьём»).

1. Снять логи попыток

Windows (WS-042 или бастион RDP):

New-Item -ItemType Directory -Force C:\IR\brute | Out-Null
wevtutil epl Security C:\IR\brute\Security.evtx /ow:true
Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4625; StartTime=(Get-Date).AddHours(-24) } |
  Group-Object { $_.Properties[19].Value } |
  Sort-Object Count -Descending |
  Select-Object -First 15 Count, Name

Индекс свойства IP в 4625 зависит от шаблона события; если Properties[19] пустой — читайте XML/IpAddress из сообщения. Не подгоняйте «красивый» индекс наобум: откройте одно событие в Event Viewer и сверьте.

Ubuntu host.example:

sudo mkdir -p /var/ir/brute
sudo journalctl -u ssh --since '24 hours ago' | sudo tee /var/ir/brute/sshd.txt >/dev/null
sudo grep -c 'Failed password' /var/log/auth.log 2>/dev/null || true
sudo journalctl -u ssh --since '24 hours ago' | awk '/Failed password/{print $(NF-3)}' | sort | uniq -c | sort -nr | head

2. Кто слушает

Get-NetTCPConnection -State Listen | Where-Object { $_.LocalPort -in 22,3389 }
Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name PortNumber
ss -lntp | grep -E ':22|:3389'
sudo sshd -T | grep -Ei 'port|passwordauthentication|permitrootlogin|maxauthtries'

3. Уже есть Success?

Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4624; StartTime=(Get-Date).AddHours(-24) } |
  Where-Object { $_.Message -match '10\.0\.10\.55' }
sudo journalctl -u ssh --since '24 hours ago' | grep -E 'Accepted (password|publickey)' | grep '10.0.10.55'

Если да — параллельно блокируйте учётку, не только IP.

Решение

Сценарий A. Источник один (10.0.10.55)

Ограничьте на периметре и на хосте.

sudo nft add rule inet filter input ip saddr 10.0.10.55 tcp dport 22 drop
# либо UFW:
sudo ufw deny from 10.0.10.55 to any port 22 proto tcp
sudo ufw status numbered

Windows Firewall (не Off):

New-NetFirewallRule -Name 'IR-block-brute-src' -DisplayName 'IR block 10.0.10.55' `
  -Direction Inbound -Action Block -RemoteAddress 10.0.10.55

Fail2Ban, если пакет уже стоит: проверьте, что jail sshd банит, не только пишет. Не выдумывайте кастомные regex «с форума» в инциденте — штатный filter sshd и banaction в живой firewall.

Сценарий B. Распределённый бот

/32 не спасёт. Снимите сервис с интернета: RDP только через VPN/RDG, SSH только с jump AllowUsers + ключи. На время — rate limit на firewall (лимит новых сессий на 22/3389), не «открыть всё». Account lockout на AD включите осознанно: слишком жёсткий порог станет DoS по ivan.petrov.

Сценарий C. Идёт lockout своих

Это brute, который попал в имена реальных пользователей. Блок источника + временный перенос RDP/SSH на нестандарт не как «безопасность», а как передышка, плюс обязательный VPN. Сообщите helpdesk, почему ivan.petrov 4740.

Как проверить, что проблема устранена

  • Новые 4625/Failed password с 10.0.10.55 прекратились (или режутся на периметре, до хоста не доходят).
  • Копии логов лежат в C:\IR\brute и /var/ir/brute, не только в живом журнале.
  • sshd -T / RDP не слушают WAN; firewall Enabled.
  • Легитимный вход админа с jump проходит.
  • Если был Success атакующего — учётка заблокирована, сессии сброшены.
sudo journalctl -u ssh -n 20 --no-pager
sudo fail2ban-client status sshd 2>/dev/null || true

Если не помогло

  • Бан есть, поток жив по IPv6 — добавьте правило на ip6 saddr.
  • Fail2ban Currently banned 0 при тысячах Fail — backend/journal vs файл, неверный filter; чините jail после инцидента, сейчас режьте nft/UFW вручную.
  • 4625 идут с множества IP на 3389 WAN — без снятия DNAT это не закончится.
  • Логи уже пустые — журналы очищены, восстанавливайте с коллектора.
  • После бана «пропал весь офис» — вы задели NAT; откатите /24, оставьте /32 и закройте WAN.

Профилактика

  • Нет 22/3389 на белых адресах; только VPN + jump.
  • Ключи SSH, PasswordAuthentication no, PermitRootLogin no.
  • MFA на VPN и на RDP-шлюз.
  • Централизованные логи, алерт по порогу 4625/Failed password.
  • Lockout с разумным порогом и мониторингом 4740.

FAQ

Можно ли сменить порт SSH с 22 на 2222 и считать закрытым?

Нет. Это снижение шума сканеров, не модель доступа. Нужен фильтр по источнику и ключи.

Стоит ли сразу fail2ban в production в пике атаки?

Если пакета нет — быстрее nft/ufw deny и закрытие WAN. Ставить jail «с нуля» под огнём можно сломать SSH себе. Сначала ручной блок.

Банить ли всю страну GeoIP?

Только если бизнес явно не работает оттуда и вы понимаете ложные срабатывания. Для brute достаточно закрыть сервис с WAN.

Нужно ли менять пароли всех, кого перечислили в Fail?

Если Success не было и имена стандартные (root, admin) — приоритет закрыть вход. Если светились реальные ivan.petrov и был риск spray по AD — ротируйте по смене учёток.

Почему ping до сервера есть, а brute продолжается?

ICMP не аутентификация. Режьте TCP 22/3389, не «выключайте ping».