До основного вмісту

Захист від брутфорс-атак: 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-подібні системи (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) виставлено суворіше, ніж реальний профіль навантаження форми — наприклад, користувач випадково надсилає форму двічі поспіль або браузер повторює запит через повільне з'єднання. Рішення — переглянути параметри зони обмеження під реальні сценарії використання, а не просто знижувати поріг блокування навмання.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці