WordPress заваливают подбором паролей
Как отсечь подбор паролей к wp-login.php и xmlrpc.php и сканирование плагинов до того, как запросы дойдут до PHP, и закрыть сервер от прямых обращений.
Подбор паролей к wp-login.php и xmlrpc.php и сканирование плагинов нагружают
сервер и при установленном плагине безопасности: плагин работает внутри WordPress, и к
моменту отказа запрос уже запустил PHP.
Решение — отсекать такой трафик до сервера. Сайт подключается через WebShield, мусорные запросы останавливаются у нас, а сервер закрывается от прямых обращений.
Что получится: сайт работает через WebShield; сканеры, подбор паролей и инъекции
останавливаются у нас, а до сервера доходят посетители. Прямой доступ к серверу в обход
защиты закрыт.
Понадобится: доступ к регистратору домена и к серверу — к конфигу веб-сервера или
хотя бы к wp-config.php. Время: около часа, плюс ожидание смены NS.
1. Подключите домен
Заголовок раздела «1. Подключите домен»Личный кабинет → Домены → Добавить домен, введите example.com. Оставьте импорт
записей включённым и сверьте найденный список с текущей зоной. Особенно внимательно —
почту: MX, SPF, DKIM, DMARC. Не нашлась запись — добавьте вручную, прежде чем
менять NS.
Потом у регистратора замените NS на наши:
nsbox.webshield.pronshub.webshield.proПока смена расходится по сети, всё работает по-старому. Когда статус домена станет Делегирован, переходите дальше. Подробности и перенос через AXFR — в справке Передача управления доменом.
DNS переносить нельзя или не хочется? Сайт подключается и записями у вашего провайдера — см. Подключение без смены NS, дальше всё так же.
2. Пустите сайт через защиту
Заголовок раздела «2. Пустите сайт через защиту»- DNS → у записей
example.comиwwwвключите Прокси. - Хосты → для каждого из двух имён включите Обязателен SSL и Перенаправлять HTTP на HTTPS. Сертификат мы выпустим сами за пару минут.
Ваш сервер при этом остаётся как есть и продолжает отвечать на 443-м порту: к нему мы тоже ходим по HTTPS, и сертификат, который на нём уже стоит, подойдёт.
Проверка:
curl -sI https://example.com/ | grep -i '^server'Ответ server: WebShield.Pro значит, что запрос прошёл через нас.
С этого момента без всяких настроек работают сигнатуры против SQL-инъекций, XSS и обхода
путей, отсев известных сканеров, ограничение частоты на формах входа, админке и
xmlrpc.php, а адреса, которые настойчиво сканируют сайт, уходят в бан на всех наших
узлах.
3. Верните WordPress настоящие адреса посетителей
Заголовок раздела «3. Верните WordPress настоящие адреса посетителей»Теперь к серверу приходят наши узлы, и WordPress видит их адреса вместо адресов посетителей. Комментарии, журналы и плагины безопасности начнут путаться. Хуже всего с ограничителями попыток входа: заблокировав «нарушителя», такой плагин заблокирует наш узел — а вместе с ним всех, кто через него ходит.
Настоящий адрес мы передаём в заголовке X-Real-IP. Верить ему можно, только если запрос
действительно пришёл от нас, иначе подделать адрес сможет кто угодно. Поэтому сначала
возьмите секрет хоста: Хосты → хост → Доступ только через WebShield → Значение.
Затем добавьте в wp-config.php перед строкой /* That's all, stop editing! */:
// Адрес посетителя от WebShield — только для запросов, пришедших через нас.if (isset($_SERVER['HTTP_X_WEBSHIELD_ORIGIN_TOKEN'], $_SERVER['HTTP_X_REAL_IP']) && hash_equals('wso_ВАШ_ТОКЕН', $_SERVER['HTTP_X_WEBSHIELD_ORIGIN_TOKEN'])) { $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_REAL_IP'];}У example.com и www секреты разные. Если www только переадресует на основное имя,
хватит секрета основного.
4. Закройте сервер от прямых обращений
Заголовок раздела «4. Закройте сервер от прямых обращений»Адрес сервера никуда не делся: он остался в старых DNS-записях, в архивах и в базах сканеров. Кто его знает, обращается к сайту напрямую — мимо всего, что вы только что настроили. Поэтому сервер должен отвечать только запросам с тем же секретом.
Для nginx в блоке server вашего сайта:
if ($http_x_webshield_origin_token != "wso_ВАШ_ТОКЕН") { return 403; }Для Apache — в начале .htaccess в корне WordPress:
<If "%{HTTP:X-WebShield-Origin-Token} != 'wso_ВАШ_ТОКЕН'"> Require all denied</If>Правку делайте в веб-сервере, а не в PHP: обновление WordPress её не затрёт, и отказ не будет стоить запуска PHP. Перед этим убедитесь, что сайт открывается через нас (шаг 2), и держите под рукой SSH или панель хостинга. Подробнее, в том числе для других серверов и с автобаном через fail2ban, — в руководстве Атакуют напрямую по IP сервера.
Проверка:
# Напрямую — ожидаем 403.curl -sk -o /dev/null -w '%{http_code}\n' https://АДРЕС_СЕРВЕРА/ -H 'Host: example.com'# Через нас — 200.curl -s -o /dev/null -w '%{http_code}\n' https://example.com/5. Закройте xmlrpc.php
Заголовок раздела «5. Закройте xmlrpc.php»xmlrpc.php — старый интерфейс для удалённой публикации; им пользуются, например, Jetpack
и некоторые мобильные приложения. Метод system.multicall позволяет одним запросом
проверить много паролей. Если вы им не пользуетесь, закройте его на сервере:
location = /xmlrpc.php { return 403; }<Files "xmlrpc.php"> Require all denied</Files>6. Включите проверку браузера — когда понадобится
Заголовок раздела «6. Включите проверку браузера — когда понадобится»Всё, что выше, работает незаметно для посетителей. Если атака продолжается — ботнет подбирает пароли с тысяч адресов, и каждый адрес стучится редко, — включите на хосте Защита от ботов → Проверка браузера. Посетитель увидит экран проверки на секунду, а боты дальше не пройдут. Известных поисковых роботов проверка не задерживает.
Проверка останавливает и полезных роботов вашего же сайта. Перед включением добавьте в Исключения проверок на странице хоста:
/wp-cron.php— WordPress сам запускает фоновые задачи запросом к своему же адресу, и без исключения не выйдут отложенные записи и не отправятся письма;- адрес уведомлений платёжной системы — его подскажут настройки платёжного плагина.
Адрес вида
/?wc-api=…исключить нельзя (это корень сайта); включите в плагине адрес вида/wc-api/…; /wp-json/— если с сайтом работают мобильное приложение или внешние сервисы через REST API.
На исключённых путях сигнатуры, лимиты и баны продолжают действовать — снимается только экран проверки.
Проверка
Заголовок раздела «Проверка»- В Статистике на вкладке Защита растут «Атак отражено» и «IP заблокировано».
- В логе сервера пропали запросы к
wp-login.phpс сотен адресов и запросы к несуществующим плагинам. - Нагрузка на процессор снизилась.
Если не работает
Заголовок раздела «Если не работает»| Симптом | Причина и решение |
|---|---|
| Сайт отвечает 502 | Сервер не отвечает нам на 443-м порту. Проверьте, что HTTPS на нём работает, или выключите Перенаправлять HTTP на HTTPS, чтобы мы ходили к нему по HTTP. |
| Бесконечная переадресация | В WordPress адрес сайта начинается с http://, а мы переадресуем на HTTPS. В Настройки → Общие укажите адреса с https://. |
| После шага 4 сайт отвечает 403 всем | Токен в конфиге не совпадает с кабинетом или вставлен от другого хоста. Сверьте значение. |
| Плагин безопасности заблокировал всех | Шаг 3 не сделан или сделан после того, как плагин успел забанить адрес нашего узла. Добавьте код и очистите список блокировок плагина. |
| Не выходят запланированные записи | Включена проверка браузера, а /wp-cron.php не в исключениях. |
| Не проходят оплаты | Уведомления платёжной системы упираются в проверку браузера. Добавьте их адрес в исключения. |
Что дальше
Заголовок раздела «Что дальше»- CDN и защита — кеш, HTTP/3 и остальные параметры хоста. Кеш страниц включать можно: вошедшие пользователи и покупатели с товаром в корзине WooCommerce его минуют.
- Атакуют напрямую по IP сервера — что ещё выдаёт адрес сервера.
- Сайт под атакой — если прямо сейчас всё лежит.