☰
WEB SECURITY / PRACTICE

Rate limiting для захисту wp-login.php від брутфорсу

Rate limiting для захисту wp-login.php від брутфорсу

Сторінка входу WordPress, зазвичай wp-login.php, часто стає першою ціллю автоматизованих атак. Боти перебирають паролі, надсилаючи сотні або тисячі запитів, створюючи навантаження на сервер і підвищуючи ризик захоплення облікового запису.

Складний пароль важливий, але сам по собі не вирішує проблему. Практичний захист складається з rate limiting, тимчасового блокування, двофакторної автентифікації, контролю XML-RPC, моніторингу журналів і правильного налаштування проксі або CDN.

Що таке rate limiting і як він зупиняє брутфорс

Rate limiting обмежує кількість запитів до певного ресурсу за визначений проміжок часу. Для wp-login.php ліміт найчастіше розраховують за IP-адресою, а після його перевищення сервер повертає відповідь 429 Too Many Requests або тимчасово блокує подальші запити.

Наприклад, можна дозволити до 5–10 невдалих спроб за 15 хвилин для однієї IP-адреси. Точне значення залежить від кількості адміністраторів, наявності спільної корпоративної мережі та способу роботи команди.

Мета rate limiting — не зробити вхід неможливим, а різко зменшити швидкість автоматичного підбору. Водночас це не заміна унікальним паролям, 2FA та оновленням WordPress, тем і плагінів.

  • Для перевищення ліміту використовуйте статус 429, а не звичайну сторінку помилки.
  • Застосовуйте окремі правила до wp-login.php, а не до всього сайту.
  • Перед блокуванням врахуйте, що кілька користувачів можуть виходити в інтернет через одну публічну IP-адресу.
  • Не покладайтеся лише на обмеження за IP: розподілені атаки можуть використовувати багато адрес.

Як налаштувати обмеження на рівні Nginx

Якщо сайт працює на Nginx, rate limiting краще виконувати до передавання запиту PHP-FPM і WordPress. Це зменшує навантаження на процеси PHP та базу даних. Нижче наведено базовий приклад, який потрібно адаптувати до конфігурації конкретного сервера.

Директива limit_req_zone зазвичай розміщується в контексті http, а limit_req — у server або location. Значення rate=10r/m означає приблизно десять запитів на хвилину для однієї IP-адреси. Параметр burst дозволяє короткий сплеск запитів, але не скасовує загальне обмеження.

  • Перевірте конфігурацію командою nginx -t перед перезавантаженням сервера.
  • Не застосовуйте правило до всього домену без тестування: воно може блокувати звичайні сторінки, AJAX-запити та роботу Elementor.
  • Якщо перед Nginx працює CDN, балансувальник або reverse proxy, спочатку налаштуйте коректне визначення реальної IP-адреси клієнта.
  • Не довіряйте заголовку X-Forwarded-For без налаштування списку довірених проксі, інакше зловмисник зможе підміняти IP.
http {
    limit_req_zone $binary_remote_addr zone=wp_login:10m rate=10r/m;

    server {
        location = /wp-login.php {
            limit_req zone=wp_login burst=5 nodelay;
            limit_req_status 429;

            include fastcgi_params;
            fastcgi_pass unix:/run/php/php-fpm.sock;
        }
    }
}

Що перевірити після зміни конфігурації

Переконайтеся, що wp-login.php продовжує відкриватися, форма входу надсилається без помилок, а після перевищення порогу сервер справді повертає 429. Перевіряйте access log і error log, але не записуйте в журнали паролі, cookies або повний вміст POST-запитів.

Фактичний шлях до PHP-FPM, назва сокета та структура конфігурації відрізняються між серверами. Не копіюйте приклад без перевірки: неправильний fastcgi_pass може зробити сторінку входу недоступною.

Apache, WAF і CDN: де краще блокувати атаки

На Apache аналогічну задачу можна реалізувати за допомогою модулів, правил reverse proxy або зовнішнього WAF. Конкретний синтаксис залежить від хостингу, тому на shared hosting часто простіше налаштувати правило в панелі WAF або звернутися до адміністратора сервера.

WAF або CDN може відсікати підозрілий трафік ще до того, як він потрапить на вебсервер. Це особливо корисно під час масованої атаки, коли запити до WordPress уже самі по собі створюють навантаження. На цьому рівні можна поєднати rate limiting з CAPTCHA, перевіркою репутації IP та правилами для окремих країн або мереж.

Не варто бездумно блокувати весь трафік до wp-login.php. Адміністратори можуть використовувати VPN, мобільні мережі або корпоративний NAT, а автоматичні правила WAF іноді помилково реагують на нормальну поведінку.

  • На рівні WAF обмежуйте частоту POST-запитів до wp-login.php, якщо це підтримується без блокування звичайного GET-запиту.
  • Використовуйте тимчасове блокування, а не безстроковий бан, якщо немає ознак серйозної компрометації.
  • CAPTCHA доцільніше показувати після підозрілої активності, а не кожному відвідувачу.
  • Переконайтеся, що health-check, моніторинг і дозволені IP-адреси не потрапляють під правило.

Додатковий захист WordPress і Elementor

Rate limiting захищає конкретну точку входу, але не усуває інші причини компрометації. Для всіх адміністративних акаунтів увімкніть двофакторну автентифікацію, використовуйте унікальні довгі паролі та надавайте користувачам мінімально необхідні ролі.

Не використовуйте логін admin або очевидні імена на кшталт назви компанії. Перевірте, чи не розкривається ім’я користувача через повідомлення про помилку, REST API, авторські URL або інші публічні механізми. Повідомлення про невдалий вхід не повинно підказувати, чи існує конкретний користувач.

WordPress, Elementor, доповнення до Elementor, теми та всі плагіни потрібно своєчасно оновлювати. Вразливий плагін може стати шляхом атаки навіть тоді, коли wp-login.php добре захищений.

Окремо оцініть XML-RPC. Якщо він не потрібен для мобільного застосунку, зовнішньої інтеграції або іншого робочого процесу, його можна обмежити на рівні сервера чи WAF. Не вимикайте його механічно, якщо сайт реально залежить від цієї функції.

  • Увімкніть 2FA щонайменше для адміністраторів і редакторів.
  • Забороніть використання повторно застосованих паролів.
  • Видаліть непотрібні плагіни та теми, а не просто деактивуйте їх.
  • Перевірте резервні копії та можливість відновлення до початку налаштувань безпеки.
  • Не змінюйте URL входу як єдиний захід: боти можуть знаходити нову адресу через посилання, відповіді сервера або сканування.

Як відстежувати невдалі входи та реагувати на атаку

Журнали вебсервера допомагають побачити частоту запитів, IP-адреси, user agent, коди відповідей і час атаки. Однак сам access log не завжди показує, чи була спроба автентифікації невдалою. Для повної картини потрібні журнали WordPress або інструмент аудиту, налаштований без збереження чутливих даних.

Шукайте повторювані запити до wp-login.php, різке зростання відповідей 401, 403 або 429, звернення з великої кількості адрес і спроби входу під неіснуючими логінами. Важлива не лише окрема IP-адреса, а й повторювані шаблони: однакові user agent, часові інтервали та мережі.

Після виявлення атаки перевірте, чи не було успішних входів, змін користувачів, встановлення невідомих плагінів або редагування файлів. Якщо є ознаки компрометації, змініть паролі, відкличте активні сесії, перевірте адмінів і відновіть сайт із перевіреної резервної копії за потреби.

  • Зберігайте журнали достатньо довго для аналізу, але контролюйте їхній розмір і доступ.
  • Налаштуйте сповіщення про серії невдалих входів і появу нового адміністратора.
  • Регулярно переглядайте заблоковані IP та помилкові блокування.
  • Не публікуйте журнали у відкритому доступі: вони можуть містити технічну інформацію про сайт.

Типові помилки під час налаштування rate limiting

Надто жорсткий ліміт може заблокувати реальних адміністраторів, особливо якщо вся команда працює з однієї IP-адреси. Надто м’який ліміт майже не впливає на брутфорс. Починайте з помірного правила, спостерігайте за журналами та коригуйте його на основі реальної поведінки.

Ще одна поширена помилка — встановлення обмеження лише в плагіні. Плагін може зменшити кількість спроб автентифікації, але кожен запит до нього вже обробляється вебсервером і часто доходить до PHP. Для захисту ресурсів краще поєднати серверний або WAF-рівень із контролем у WordPress.

Не тестуйте блокування лише з тієї самої IP-адреси без плану відновлення доступу. Перед змінами підготуйте консольний або хостинговий доступ до сервера, список довірених адрес і спосіб тимчасово вимкнути правило.

  • Не блокуйте IP назавжди без перевірки: адреси можуть бути динамічними або спільними.
  • Не вважайте код 429 проблемою сервера — це очікувана відповідь при перевищенні ліміту.
  • Не забувайте про IPv6: правила мають коректно обробляти IPv4 та IPv6.
  • Не перевіряйте захист реальним масованим навантаженням на робочому сайті.

Поширені запитання

Який ліміт спроб входу встановити для wp-login.php?

Як стартове значення можна розглянути 5–10 невдалих спроб за 15 хвилин для однієї IP-адреси. Але його потрібно перевірити на реальній аудиторії: для спільних мереж або великої команди може знадобитися м’якше правило.

Чи достатньо встановити плагін для обмеження входів?

Плагін корисний як додатковий рівень, але не завжди захищає сервер від самого потоку запитів. Rate limiting на Nginx, Apache, WAF або CDN може відсікати трафік раніше, тому оптимально поєднувати ці рівні.

Чи потрібно повністю блокувати wp-login.php?

Зазвичай ні. Повне блокування ускладнить адміністрування і може створити проблеми для інтеграцій. Краще обмежити частоту запитів, вимагати 2FA, застосовувати WAF-правила та, якщо можливо, дозволити доступ лише з перевірених мереж.

Чому після rate limiting сайт усе одно отримує багато запитів?

Ліміт може діяти лише на одну IP-адресу, тоді як бот використовує розподілену мережу. Також правило може бути налаштоване на рівні WordPress і не зменшувати навантаження на PHP. Для масованих атак потрібні WAF, CDN, аналіз шаблонів і додаткові правила блокування.

Чи потрібно захищати XML-RPC так само, як wp-login.php?

Так, якщо XML-RPC використовується для спроб автентифікації або створює непотрібне навантаження. Якщо функція не потрібна, її можна обмежити. Перед вимкненням перевірте залежності сайту, мобільних застосунків та інтеграцій.

Висновок

Надійний захист wp-login.php — це поєднання серверного або WAF-рівня rate limiting, 2FA, унікальних паролів, оновлень і контролю журналів. Обмеження у 5–10 спроб за 15 хвилин може бути відправною точкою, але його потрібно адаптувати до структури команди та мережі.

Налаштовуйте правила поступово, тестуйте код 429, перевіряйте реальну IP-адресу за reverse proxy та майте аварійний доступ до сервера. Так можна зменшити ризик брутфорсу, не перетворивши захист на причину блокування власних користувачів.

← Усі матеріали веб-безпеки