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, общий порядок такой:
- Установить модуль WAF (обычно ModSecurity).
- Подключить набор правил (часто это OWASP Core Rule Set).
- Настроить режим работы: сначала мониторинг, потом блокировка.
- Сделать белые списки для ваших легитимных URL, если появляются ложные срабатывания.
- Проверить на тестовом трафике и только затем включить жесткий режим.
Критичный момент: начинать с режима, где блокировки не ломают сайт. Для 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 без лишних рисков
Ориентируйтесь на два принципа:
- Для wp-login.php предпочтительнее небольшие окна и умеренные пороги, чтобы отрезать массовые атаки, но оставить место человеку.
- Учитывайте, что у реальных пользователей могут быть задержки, плохая связь и ошибки ввода.
Практический путь:
- начните с умеренных значений и в первую неделю не делайте блокировки “навсегда”;
- логируйте действия 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 там, где это возможно.

