К основному содержимому

Защита WordPress на сервере: Nginx, права, xmlrpc

Безопасность · 19.04.2026 · 4 мин чтения
Иллюстрация к статье «Безопасность WordPress: полный чеклист защиты сайта»

WordPress — самая атакуемая CMS в мире. Около 90% взломов связаны с устаревшими плагинами, слабыми паролями и открытым xmlrpc.php. Этот чеклист закрывает все основные векторы атак.

1. Права на файлы и директории

find /var/www/wordpress -type d -exec chmod 755 {} \;
find /var/www/wordpress -type f -exec chmod 644 {} \;
chmod 400 /var/www/wordpress/wp-config.php
chown www-data:www-data /var/www/wordpress/wp-config.php

2. Защита wp-config.php и uploads в Nginx

location = /wp-config.php { deny all; }
location ~* /wp-content/uploads/.*\.php$ { deny all; }

3. Отключить xmlrpc.php

location = /xmlrpc.php { deny all; access_log off; log_not_found off; }

4. Защита страницы входа

location = /wp-login.php {
    allow 1.2.3.4;
    deny all;
    fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

5. Дополнения в wp-config.php

define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true);
// Сгенерировать ключи: https://api.wordpress.org/secret-key/1.1/salt/
define('AUTH_KEY', 'уникальный_ключ_1');
define('SECURE_AUTH_KEY', 'уникальный_ключ_2');

6. Чеклист WordPress Security

МераИнструментПриоритет
Обновить WP, темы, плагиныАвто-обновленияКритический
Сильный пароль + 2FAWP 2FA плагинКритический
Отключить xmlrpc.phpNginxВысокий
Права 644/755 на файлыchmodВысокий
WAF / FirewallWordfence, SucuriВысокий
Скрыть wp-login.php URLWPS Hide LoginСредний
Резервные копииUpdraftPlusКритический
SSL-сертификатLet's EncryptКритический
Плагины — главная угроза: 56% взломов WordPress происходит через уязвимые плагины. Регулярно обновляйте все плагины и удаляйте неиспользуемые — даже деактивированные плагины остаются уязвимостью.

Разбор типичных ошибок при закрытии WordPress

  • Запрос GET /xmlrpc.php в браузере возвращает текст XML-RPC server accepts POST requests only. — эндпоинт жив и отвечает, просто ждёт POST-запрос. Сам факт ответа 200 OK означает, что правило deny all ещё не применилось.
  • Конфиг Nginx отредактирован, а /wp-login.php из чужой сети по-прежнему открывается — типичная причина: правки внесли не в тот server {}, если на сервере отдельные блоки для HTTP и HTTPS или для нескольких доменов, а поправили только один из них.
  • access forbidden by rule, client: ..., server: ..., request: "GET /wp-config.php HTTP/1.1" — так выглядит в логе Nginx успешная блокировка через deny all; в браузере при этом виден обычный 403 Forbidden.
  • Резервная копия редактора вроде wp-config.php~ или wp-config.php.bak отдаётся сервером как обычный текст, а не выполняется как PHP — правило location = /wp-config.php совпадает только с точным именем файла, а копия с другим расширением проходит мимо и раскрывает пароль от базы данных открытым текстом.
  • Атака на xmlrpc.php методом system.multicall проверяет тысячи паролей одним HTTP-запросом вместо тысяч отдельных попыток — поэтому отключение xmlrpc.php снижает риск сильнее, чем кажется по одному безобидному на вид эндпоинту.

Способы защиты wp-login.php: что дают и где слабое место

СпособЧто даётСлабое место
IP allowlist в NginxПолностью закрывает вход посторонним адресамЛомается при динамическом IP, требует регулярного обновления правила
HTTP Basic Auth перед формой входаДополнительный пароль ещё до формы WordPressОдин общий пароль на всех, не привязан к конкретному пользователю
Скрытие URL (WPS Hide Login)Останавливает автоматический перебор ботами по стандартному адресуНе защищает от целевой атаки, если адрес всё же стал известен
Двухфакторная аутентификацияЗащищает аккаунт даже при утечке пароляНе ограничивает число попыток входа в саму форму

Когда эти меры не подходят как есть

  • WordPress Multisite с разными путями для каждого сайта сети — жёсткие правила location = на конкретный путь могут не совпасть с реальными URL сети, схему нужно адаптировать под конкретную установку.
  • Управляемый хостинг без доступа к конфигурации Nginx, только .htaccess или панель управления — правила из блока server {} применить нельзя, работает лишь то, что поддерживает панель или Apache через .htaccess.
  • Команда регулярно правит темы и плагины через встроенный файловый редактор в админке — включение DISALLOW_FILE_EDIT сломает привычный процесс; нужен переход на SFTP или git-деплой либо отказ от этой конкретной меры.
  • Сайт отдаёт данные мобильному приложению или headless-фронтенду через REST API — советы по блокировке xmlrpc.php не распространяются на REST API (/wp-json/), это отдельный механизм со своими правилами доступа.

Проверка, что защита реально работает

# Убедиться, что xmlrpc.php действительно закрыт (ожидается 403, а не 200)
curl -I https://example.com/xmlrpc.php

# Проверить, что резервные копии редактора не раздаются как текст
curl -I https://example.com/wp-config.php~
curl -I https://example.com/wp-config.php.bak

# Найти на сервере файлы, доступные на запись всем подряд
find /var/www/wordpress -type f -perm /o+w

Первые три запроса должны вернуть 403 или 404, а не 200. Последняя команда должна вернуть пустой список: если find что-то нашёл, права на эти файлы шире, чем задано в первом разделе статьи, и их нужно поправить отдельно.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке