WordPress на VPS почти всегда становится целью автоматизированных сканеров. Их задачи простые: найти уязвимые версии, подобрать логин и пароль к wp-login.php, дернуть xmlrpc.php, спровоцировать ошибки в плагинах и собрать информацию по страницам админки. Защита работает лучше всего слоями: WAF отсекает подозрительный трафик до PHP, fail2ban режет переборы по логам веб-сервера, а ограничения на вход уменьшают поверхность для подбора.

Ниже разберем практическую схему, которая подходит большинству сайтов на Nginx или Apache с PHP-FPM. Акцент будет именно на WAF, fail2ban и ограничениях на вход в WordPress, без попыток “запретить все подряд” и сломать сайт.

WAF для WordPress на VPS: что он дает и где его лучше ставить

WAF (Web Application Firewall) анализирует HTTP-запросы и сопоставляет их с правилами атаки: сигнатурами инъекций, аномальными заголовками, подозрительными URL, типичными паттернами перебора. Важно, что WAF работает на уровне запросов до выполнения WordPress-логики, поэтому он эффективен против части атак до того, как они дойдут до PHP.

На практике WAF полезен в трех сценариях:

  • блокировка запросов с явными признаками инъекций или эксплойтов;
  • отсеивание мусорного трафика к wp-login.php и wp-admin;
  • снижение нагрузки на сервер при сканировании и частых невалидных запросах.

Ставить WAF можно по-разному. Если нужен быстрый старт и минимум возни, используют внешние сервисы (например, Cloudflare). Если важен контроль над правилами и детальная настройка под свой сервер, чаще выбирают ModSecurity локально на VPS.

Варианты WAF: внешний сервис или локальный ModSecurity

Внешний WAF:

  • обычно проще подключается;
  • быстрее обновляет правила;
  • часто лучше защищает от крупных объемов трафика.

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

Локальный WAF (часто это ModSecurity):

  • дает полный контроль над правилами и исключениями;
  • позволяет подстраивать режимы под конкретный сайт;
  • требует аккуратной настройки, чтобы не получить лишние блокировки.

Для темы “WordPress на VPS” логично рассматривать ModSecurity как базовый вариант, а внешние сервисы — как альтернативу или дополнение.

Подключение WAF на Nginx/Apache: общая схема без привязки к дистрибутиву

Независимо от того, Nginx или Apache, общий порядок такой:

  1. Установить модуль WAF (обычно ModSecurity).
  2. Подключить набор правил (часто это OWASP Core Rule Set).
  3. Настроить режим работы: сначала мониторинг, потом блокировка.
  4. Сделать белые списки для ваших легитимных URL, если появляются ложные срабатывания.
  5. Проверить на тестовом трафике и только затем включить жесткий режим.

Критичный момент: начинать с режима, где блокировки не ломают сайт. Для ModSecurity это обычно означает старт с Detection-only (или эквивалентным режимом), чтобы увидеть, что он считает атакой, но не запрещает запросы.

Подстройка правил под WordPress: CRS, исключения и whitelisting

OWASP CRS — хороший старт, но WordPress “не чистый статический сайт”: там много динамических URL, разных параметров и форм. Поэтому неизбежны ложные срабатывания, особенно после обновлений плагинов.

Практический подход:

  • сначала включить правила в мониторинге;
  • собрать 50–200 записей из лога за период реальной активности (вход админа, обычные страницы, контакты);
  • выяснить, какие правила триггерятся на нормальные запросы;
  • сделать исключения точечно, по URI, параметрам или типу проверки.

Типовые места, где чаще всего появляются проблемы:

  • страницы входа и восстановления пароля (wp-login.php и wp-register.php, если включена регистрация);
  • запросы к wp-admin/admin-ajax.php (в зависимости от плагинов);
  • REST API (wp-json/…) — некоторые правила могут ругаться на параметры.

Хорошее правило для исключений: не отключать правила глобально. Снижайте строгость только для конкретного URI и только при необходимости.

Проверка работы WAF без сбоев

Перед тем как “закручивать гайки”, проверьте WAF так:

  • зайдите в админку и обновите одну страницу/плагин (обычное действие, которое вы делаете регулярно);
  • выполните вход под своим пользователем;
  • проверьте формы, которые отправляют POST-запросы (контакты, комментарии, заявки);
  • проверьте, что публикация и редактирование работают без 403.

Если в логах появляются блокировки именно для вашего нормального трафика, исправляйте правила до включения режима блокировки на максимум.

Полезно иметь план отката: например, возможность быстро переключить ModSecurity в detection-only через конфиг или переменные окружения. Тогда вы не рискуете “поймать” сайт без доступа.

fail2ban: как отсечь перебор и атаки на wp-login.php по логам

fail2ban работает иначе, чем WAF. Он не анализирует содержимое запроса “как WAF”, а отслеживает события в логах: повторяющиеся ошибки авторизации, подозрительные коды ответов, признаки перебора. Дальше fail2ban временно блокирует источник (IP или диапазон) на заданное время.

Это хорошо ложится на задачу защиты входа:

  • боты пробуют множество пар логин/пароль;
  • сервер получает много одинаковых ошибок в логах;
  • fail2ban фиксирует повторяемость и режет поток.

Важно: fail2ban эффективен там, где ваш веб-сервер пишет понятные события. Если логирование настроено так, что перебор не отражается, fail2ban будет “молчать”.

Какие логи использовать на VPS

Для Nginx типично анализировать access.log и error.log, но конкретный jail зависит от того, как вы настроили логи и коды ответа. Для WordPress входа обычно полезны:

  • обращения к /wp-login.php;
  • 401/403/404, которые появляются при попытках входа;
  • сообщения от PHP-FPM и Nginx о проблемных запросах (если они коррелируют с перебором).

Для Apache логирование тоже различается. Поэтому корректнее ориентироваться не на “магические” названия путей, а на содержимое: найдите строки, которые появляются во время попыток входа и перебора, и используйте те же форматы в fail2ban.

Практическая проверка:

  • временно запустите fail2ban в режиме, где видно, что он считает подходящими событиями;
  • сделайте 3–5 ручных неудачных попыток входа;
  • убедитесь, что fail2ban действительно реагирует и увеличивает счетчик.

Базовые jail’ы fail2ban для WordPress: логика, а не магия

Ниже примерная логика jail’ов для WordPress. Точные регулярки зависят от ваших лог-форматов, поэтому воспринимайте это как шаблон.

Обычно используют отдельные jails:

  • для wp-login.php (основной перебор);
  • для admin-ajax.php при ошибках, если у вас там есть признаки атаки;
  • для xmlrpc.php (если вы не отключили его и видите переборы/эксплойт-запросы);
  • опционально для общего “web-auth” поведения.

Пример конфигурации jail’ов (идея, которую вы адаптируете под свои логи):

  • jail для wp-login.php: фильтр ловит последовательные запросы к wp-login.php с кодами 401/403 или характерными сообщениями;
  • action: блокирует IP на короткое время, чтобы бот не успевал подобрать пароль.

В настройках fail2ban чаще всего используются параметры:

  • maxretry: сколько неудачных событий до блокировки;
  • findtime: окно времени, в котором считаются события;
  • bantime: сколько длится блокировка.

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

Как подобрать bantime, findtime и maxretry без лишних рисков

Ориентируйтесь на два принципа:

  1. Для wp-login.php предпочтительнее небольшие окна и умеренные пороги, чтобы отрезать массовые атаки, но оставить место человеку.
  2. Учитывайте, что у реальных пользователей могут быть задержки, плохая связь и ошибки ввода.

Практический путь:

  • начните с умеренных значений и в первую неделю не делайте блокировки “навсегда”;
  • логируйте действия fail2ban (какие IP банятся и за что);
  • посмотрите, не банит ли он ваши собственные IP в моменты, когда вы тестируете доступ.

Если вы используете VPN или корпоративную сеть, учитывайте, что IP может быть общим для нескольких людей. В таком случае запрет может задеть не только атакующих.

Ручная проверка fail2ban и типичные ошибки

Проверка должна быть простой:

  • попробуйте специально вызвать повторяющиеся события входа (например, намеренно ввести неверный пароль несколько раз в течение findtime);
  • убедитесь, что в fail2ban зафиксировался счетчик;
  • проверьте, что IP действительно блокируется (в iptables/nftables) и что затем доступ к странице входа прекращается.

Типичные ошибки:

  • неверный регулярный шаблон в filter: тогда fail2ban не видит события;
  • бан “не того” кода ответа: например, если вы ловите 404 от случайного сканера, можно получить много бессмысленных блокировок;
  • конфликт с уже настроенными rate limit на уровне Nginx/Apache: тогда вы можете неправильно интерпретировать поведение логов.

Решение: сначала убедитесь, что fail2ban ловит именно ваши события перебора. Только потом поднимайте строгость.

Ограничения на вход в WordPress: что реально снижает риск перебора

Ограничения на вход часто дают самый заметный эффект. Причина проста: почти все атаки направлены на конкретные точки входа — wp-login.php и доступ к wp-admin. Если вы сокращаете частоту попыток и уменьшаете полезность перебора, автоматизация теряет эффективность.

Под “ограничениями” здесь понимаются:

  • контроль частоты запросов (rate limiting);
  • ограничения по IP (гео/адреса/диапазоны);
  • отключение лишних поверхностей вроде xmlrpc.php;
  • усиление процесса входа (например, 2FA) и снижение вероятности успешного подбора.

Ограничение доступа по IP и гео: когда это уместно

Ограничение по IP подходит, если:

  • у вас есть стабильные адреса админов (офис, провайдер, VPN, подсети);
  • вы не ожидаете вход админки из стран, где у вас нет пользователей.

Технически это делается на уровне WAF, веб-сервера или через firewall. Важно не делать “жесткий запрет всему миру” без исключений: иначе вы получите проблемы при смене IP.

Практическая схема:

  • разрешить доступ к wp-admin и wp-login.php только с ваших подсетей;
  • для остальных — либо блокировать, либо разрешать только WAF/проверенному адресу;
  • предусмотреть “окно обслуживания”: когда вам нужно сменить IP, вы временно расширяете правила.

Если такой схемы нет, не страшно: тогда используйте rate limiting и fail2ban вместо IP-блокировки.

Запрет xmlrpc.php и почему это часть защиты входа

xmlrpc.php часто становится мишенью для переборов и атак через WordPress-интерфейсы. На практике многие сайты могут жить без XML-RPC, особенно если вы не используете удаленные публикации и интеграции.

Полезное правило: отключайте xmlrpc.php только если вы уверены, что он не нужен. Проверить можно по вашим интеграциям и функциям: автопубликации из внешних сервисов, мобильные клиенты, плагины синхронизации.

Как отключить:

  • на уровне WordPress через настройки/плагины или код (в зависимости от вашего процесса);
  • на уровне веб-сервера через запрет доступа к /xmlrpc.php;
  • дополнительно на уровне WAF, если вы оставляете его включенным.

Если вы отключаете xmlrpc.php, атаки на него перестают быть для злоумышленника частью “плана”.

Ограничение по частоте запросов к wp-login.php и wp-admin

Rate limiting уменьшает скорость попыток входа, даже если IP “чистый” и не попадает под fail2ban. Делать его можно на уровне Nginx (limit_req) или через правила WAF.

Пример логики, которую вы подстраиваете под сайт:

  • ограничить частоту запросов к wp-login.php на IP или на комбинацию IP+User-Agent;
  • отдельно ограничить POST-запросы, потому что логин — это обычно POST;
  • сделать “щадящее” поведение для реальных пользователей: например, не блокировать на полчаса после одной ошибки.

Лучше начать с умеренной скорости. Слишком жесткие значения приводят к проблемам у пользователей с нестабильным интернетом и у админов, которые забыли пароль и несколько раз повторили попытки.

Усиление входа: 2FA и снижение поверхности подбора

Если цель — именно защитить вход, а не только отловить перебор, подключите двухфакторную аутентификацию для админов. Это не заменяет fail2ban и WAF, но делает перебор пароля почти бесполезным: даже если пароль угадали, второй фактор останавливает доступ.

Минимальные правила по безопасности входа:

  • используйте уникальные сложные пароли для админов;
  • не используйте стандартные логины вроде admin;
  • ограничьте число пользователей с правами администратора;
  • обновляйте плагины, темы и ядро WordPress регулярно.

Это не “общие слова”. Большая часть успешных компрометаций происходит из-за комбинации: старый плагин плюс доступ к админке, который можно получить перебором.

Практический чек-лист внедрения: WAF, fail2ban и ограничения на вход

Чтобы внедрение не превратилось в череду “то работает, то нет”, делайте по шагам.

  • Подготовьте основу:
  • обновите WordPress, темы и плагины;
  • проверьте доступность админки и сделайте бэкап;
  • убедитесь, что у вас включено логирование для Nginx/Apache и PHP.
  • Включите WAF в безопасном режиме:
  • стартуйте с мониторинга (не блокируйте сразу);
  • соберите логи с активностью на сайте;
  • настройте точечные исключения для ваших реальных URL.
  • Переведите WAF в режим блокировок постепенно:
  • сначала на наиболее рискованные категории (подозрительные запросы к входу);
  • затем расширяйте покрытие, если нет ложных срабатываний.
  • Настройте fail2ban на перебор входа:
  • проверьте, что фильтры корректно матчят строки ваших логов;
  • убедитесь, что блокировка происходит для повторяющихся попыток к wp-login.php;
  • ограничьте время bantime, чтобы не блокировать случайно.
  • Введите ограничения на вход:
  • rate limiting для wp-login.php и wp-admin;
  • по возможности доступ к админке только с доверенных IP или через VPN;
  • отключите xmlrpc.php, если он не нужен;
  • включите 2FA для админов.
  • Протестируйте перед публичным ужесточением:
  • проверьте вход с вашего аккаунта;
  • проверьте типовые формы и отправку POST;
  • проверьте, что WAF не блокирует обычные запросы.
  • Настройте мониторинг и удержание доступа:
  • храните быстрый способ отката конфигураций WAF и fail2ban;
  • проверьте, что логи доступны для анализа (хотя бы в файловой системе);
  • добавьте уведомления, если вы ведете систему мониторинга.

Этот порядок снижает риск “закрыть себе доступ” в первые дни после внедрения.

Мониторинг и поддержка: как не остаться без админки

После того как защита включена, важна поддержка. WAF может начать блокировать новые легитимные запросы после обновления плагинов, а fail2ban иногда реагирует на изменения лог-формата.

Обновления WordPress и правил WAF

При обновлениях:

  • сначала обновляйте на тестовом стенде, если он есть;
  • если теста нет, делайте обновление в окно с готовностью откатить;
  • после обновления проверяйте вход и основные формы, как минимум на уровне “залогиниться и создать/отредактировать”.

Правила WAF тоже могут обновляться, если вы используете OWASP CRS. В таком случае лучше применять обновления контролируемо: сначала в мониторинг, потом в блокировку.

Что смотреть в логах каждый день или после изменений

Минимальный набор для контроля:

  • записи WAF о том, какие правила срабатывают на ваш трафик;
  • события fail2ban: какие IP забанены, сколько попыток, по каким событиям;
  • ошибки 403/404 в доступе к wp-login.php и wp-admin (особенно если 403 резко выросли).

Если вы видите рост 403 на вашим же IP, сначала разберитесь, чем именно это вызвано: WAF-правилами или fail2ban-блокировками.

Как быстро восстановить доступ при ошибке настройки

Надежный подход:

  • заранее держите отдельную сессию или способ входа по доверенному IP;
  • храните резервные конфиги WAF и fail2ban;
  • уметь переключить ModSecurity обратно в detection-only;
  • уметь снять бан через fail2ban-client или перезапуск службы.

Если у вас есть возможность управлять доступом через firewall, держите отдельный “админский” путь: доступ к SSH и к админке с определенного IP, чтобы вы могли восстановиться при сбое HTTP-уровня.

Заключение: рабочая схема защиты WordPress на VPS

Защита WordPress на VPS держится на сочетании трех вещей: WAF отсекает подозрительные запросы до PHP, fail2ban снижает эффективность перебора по логам, а ограничения на вход уменьшают скорость и вероятность успешного подбора. Важно не пытаться “сразу заблокировать все”, а внедрять по шагам: сначала мониторинг, затем блокировки, затем тонкая настройка под ваш сайт.

Если вы начнете с этой последовательности и выделите время на проверку входа и типовых форм, вы получите ощутимую защиту без потери управляемости. Следующий практический шаг: выбрать ваш веб-сервер (Nginx или Apache), включить WAF в мониторинг и параллельно подготовить fail2ban под wp-login.php, после чего добавить rate limiting и отключение xmlrpc.php там, где это возможно.