К основному содержимому

Защита от брутфорс-атак: fail2ban, CAPTCHA и rate limiting

Безопасность · 19.04.2026 · 5 мин чтения
Иллюстрация к статье «Защита от брутфорс-атак: fail2ban, CAPTCHA и rate limiting»

Брутфорс-атаки — перебор паролей автоматизированными ботами — остаются одним из самых распространённых векторов взлома. Ежедневно на типичный VPS-сервер приходится тысячи попыток подбора пароля к SSH и веб-формам. Многоуровневая защита делает такие атаки нерентабельными.

fail2ban: автоматическая блокировка атакующих

apt install fail2ban -y

# /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 3600     # Блокировка на 1 час
maxretry = 5        # После 5 неудачных попыток
findtime = 600      # В течение 10 минут

[sshd]
enabled  = true
port     = ssh,2222
logpath  = /var/log/auth.log

[nginx-http-auth]
enabled  = true
logpath  = /var/log/nginx/error.log

[nginx-limit-req]
enabled  = true
logpath  = /var/log/nginx/error.log

systemctl enable --now fail2ban

Управление fail2ban

fail2ban-client status sshd
fail2ban-client set sshd unbanip 1.2.3.4
fail2ban-client set sshd banip 5.6.7.8
grep "Ban " /var/log/fail2ban.log | tail -20

Rate Limiting в Nginx

http {
    limit_req_zone $binary_remote_addr zone=login:10m rate=1r/m;
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;
}
server {
    location /wp-login.php {
        limit_req zone=login burst=3 nodelay;
        limit_req_status 429;
    }
}

Геоблокировка через GeoIP2

apt install libnginx-mod-http-geoip2 -y

http {
    geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
        $geoip2_data_country_code country iso_code;
    }
    map $geoip2_data_country_code $allowed_country {
        default 0;
        UA 1; RU 1; PL 1; DE 1;
    }
}
server {
    if ($allowed_country = 0) { return 403; }
}

Защита формы входа через CAPTCHA

Для WordPress используйте плагин Cloudflare Turnstile или hCaptcha. Для собственных форм:

// PHP: проверка hCaptcha
$response = file_get_contents('https://hcaptcha.com/siteverify', false,
    stream_context_create(['http' => ['method' => 'POST',
    'content' => http_build_query([
        'secret' => 'YOUR_SECRET_KEY',
        'response' => $_POST['h-captcha-response']
    ])]]));
$result = json_decode($response);
if (!$result->success) { die('CAPTCHA failed'); }
Комбинированная защита: fail2ban + rate limiting + CAPTCHA + изменённый порт SSH — в совокупности делают брутфорс-атаку практически невозможной. Используйте все уровни, не ограничивайтесь одним.
Не блокируйте себя! Добавьте свой IP в whitelist fail2ban перед ужесточением настроек:
echo "ignoreip = 127.0.0.1/8 ВАШ_IP" >> /etc/fail2ban/jail.local

Частые ошибки настройки защиты

Сообщение или симптомПричина
Unable to find logfile при старте fail2banПуть logpath не совпадает с реальным расположением лога на дистрибутиве — например, CentOS пишет в /var/log/secure, а не /var/log/auth.log
nginx: [emerg] limit_req_zone duplicate zoneЗона с одинаковым именем объявлена в нескольких конфигах, которые подключаются одновременно
Легитимные пользователи получают 429 Too Many RequestsЗначение rate или burst выставлено слишком строго для реального профиля нагрузки формы
Собственный IP заблокирован fail2ban после тестаIP не был заранее добавлен в ignoreip — автоматическая разблокировка наступит только через bantime

Уровни защиты: что от чего защищает

ИнструментЧто защищаетОт какой атаки
fail2banSSH и веб-формы по логамПеребор паролей по логам сервисов
Rate limiting NginxHTTP-эндпоинтыМассовые запросы с одного IP
CAPTCHAФормы регистрации и входаАвтоматизированные боты без реального браузера
ГеоблокировкаВесь трафик из регионаАтаки с известных проблемных регионов

Когда одной защиты недостаточно

  • Атака идёт с тысяч разных IP одновременно (ботнет) — здесь fail2ban бессилен, нужна защита на уровне провайдера или Cloudflare
  • Пароли действительно слабые — никакая защита от перебора не заменит переход на надёжные пароли и SSH-ключи
  • При целевой атаке на конкретный сайт CAPTCHA обходится платными сервисами распознавания — добавляйте поведенческий анализ (например, Cloudflare Turnstile учитывает это)
  • Rate limiting настроен только на Nginx, а приложение слушает порт напрямую в обход прокси

Проверка результата

# Текущий статус джейла sshd
fail2ban-client status sshd

# Симуляция превышения лимита запросов
for i in $(seq 1 10); do curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-login.php; done

Если цикл выше не показал ни одного кода 429 — правило limit_req не применяется к этому location, проверьте конфиг Nginx через nginx -T. Смежные темы — базовая настройка fail2ban и DDoS-защита Nginx и Cloudflare.

fail2ban на разных дистрибутивах: где искать логи

Путь к системному логу аутентификации отличается между дистрибутивами, и это самая частая причина, по которой готовый jail.local «не работает» после копирования с другого сервера. Ubuntu и Debian пишут попытки входа по SSH в /var/log/auth.log, а RHEL-based системы (CentOS, AlmaLinux, Rocky Linux) — в /var/log/secure. Перед первым запуском fail2ban на новом сервере всегда проверяйте актуальный путь командой ls -la /var/log/ | grep -E "auth|secure", а не копируйте конфиг вслепую.

Частые вопросы

Поможет ли fail2ban, если атака идёт с тысяч разных IP-адресов одновременно?

Практически нет — fail2ban блокирует конкретный адрес после превышения порога неудачных попыток, а при распределённой атаке с огромного числа разных IP каждый адрес успевает сделать лишь пару попыток и не попадает под блокировку. Нужна защита уровнем выше — на стороне провайдера или через сервис вроде Cloudflare, который видит картину по всему трафику, а не по логам сервера.

Как не заблокировать самого себя во время настройки защиты?

Прежде чем ужесточать правила, нужно заранее добавить собственный IP-адрес в список исключений fail2ban — тогда сервис не станет банить его вместе со всеми остальными при проверках и тестах. Если доступ всё же пропал, обычно достаточно подождать истечения срока блокировки или снять бан через другой канал доступа, например консоль провайдера.

Останавливает ли CAPTCHA автоматизированных ботов полностью?

Не полностью — при целевой атаке на конкретный сайт CAPTCHA можно обойти с помощью платных сторонних сервисов распознавания, которые решают задачку за реального человека на стороне. Поэтому CAPTCHA стоит рассматривать как один из уровней защиты, а не как окончательное решение, и дополнять её поведенческим анализом или комбинировать с rate limiting и fail2ban.

Почему после настройки rate limiting легитимные пользователи иногда получают ошибку слишком частых запросов?

Обычно причина в том, что значение частоты запросов или всплеска (burst) выставлено строже, чем реальный профиль нагрузки формы — например, пользователь случайно отправляет форму дважды подряд или браузер повторяет запрос из-за медленного соединения. Решение — пересмотреть параметры зоны ограничения под реальные сценарии использования, а не просто снижать порог блокировки наугад.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке