XML-RPC в WordPress часто отключают целиком, но это не всегда подходит. Если у вас остались рабочие сценарии вроде мобильного приложения, внешнего клиента публикации или интеграции с сервисом, безопаснее не рубить endpoint полностью, а разрешить его только с нужных IP.
Ниже — практический вариант без выдуманных хуков и без лишней магии: сначала определяем, действительно ли XML-RPC нужен, потом ограничиваем доступ на уровне сервера или WordPress, а затем проверяем, что лишние запросы режутся, а нужные проходят.
Когда ограничение по IP лучше полного отключения
Полное отключение XML-RPC удобно, если вы точно знаете, что он нигде не используется. Но на реальных сайтах это не всегда так. Чаще всего XML-RPC нужен для одной из задач:
- публикация через внешние редакторы;
- подключение мобильного приложения WordPress;
- старые интеграции, которые не переведены на REST API;
- автоматизация, завязанная именно на XML-RPC, а не на REST.
Если хотя бы один такой сценарий есть, лучше ограничить доступ по IP. Это снижает поверхность атаки и не ломает рабочие интеграции.
Диагностика: кто реально ходит в xmlrpc.php
Перед изменениями стоит понять, есть ли живые обращения к /xmlrpc.php. Если у вас есть доступ к логам веб-сервера, это самый надёжный способ. Ищите запросы к файлу xmlrpc.php и смотрите IP, User-Agent и частоту.
Что искать в логах
В access-логах обычно достаточно фильтра по имени файла. Пример для nginx:
grep "xmlrpc.php" /var/log/nginx/access.log | tail -n 50Если запросы идут с одного-двух адресов, это хороший кандидат на whitelist. Если обращений много и они с разных IP, сначала разберитесь, какие из них принадлежат вашим сервисам, а какие — сканерам и брутфорсу.
Проверка снаружи
Можно вручную проверить ответ endpoint с разных IP. Если у вас есть VPS или тестовый сервер с другим адресом, выполните запрос:
curl -i https://example.com/xmlrpc.phpНормальный доступный endpoint обычно отвечает не 404, а сообщением о том, что XML-RPC сервер принимает только POST-запросы. Это уже сигнал, что файл доступен извне.
Как ограничить xmlrpc.php только для нужных IP
Есть два рабочих подхода: на уровне веб-сервера и на уровне WordPress. Если есть доступ к конфигу nginx или Apache, лучше делать ограничение там. Это быстрее и надёжнее. Если доступа к серверу нет, можно поставить проверку в mu-plugin или в обычный плагин.
| Подход | Плюсы | Минусы |
|---|---|---|
| nginx / Apache | Ранний отказ, меньше нагрузки, проще защитить | Нужен доступ к конфигу сервера |
| WordPress-код | Можно внедрить без правок веб-сервера | Запрос уже дошёл до PHP |
| Полное отключение | Самый жёсткий вариант | Ломает все интеграции, которые используют XML-RPC |
Вариант 1: ограничение в nginx
Если сайт работает на nginx, можно разрешить доступ только с конкретных IP. Пример для отдельного location:
location = /xmlrpc.php {
allow 203.0.113.10;
allow 198.51.100.25;
deny all;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php-fpm;
}Замените IP на свои. Если у вас несколько доверенных адресов, добавьте их отдельными строками allow. Всё остальное будет получать отказ.
Вариант 2: ограничение в Apache
Для Apache можно использовать правила в .htaccess или в конфиге виртуального хоста. Если сервер поддерживает mod_authz_core, подойдёт такой вариант:
<Files "xmlrpc.php">
Require ip 203.0.113.10 198.51.100.25
</Files>Если у вас старый Apache с другой схемой авторизации, синтаксис может отличаться. В таком случае лучше править основной конфиг виртуального хоста, а не надеяться на универсальный .htaccess.
Вариант 3: проверка в WordPress через mu-plugin
Если серверный доступ недоступен, можно отфильтровать запросы в WordPress. Это не так рано, как на уровне nginx, но всё ещё рабочий вариант. Создайте файл wp-content/mu-plugins/restrict-xmlrpc.php:
<?php
/**
* Plugin Name: Restrict XML-RPC by IP
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_filter( 'xmlrpc_enabled', function( $enabled ) {
if ( ! $enabled ) {
return false;
}
$allowed_ips = array(
'203.0.113.10',
'198.51.100.25',
);
$remote_ip = $_SERVER['REMOTE_ADDR'] ?? '';
if ( in_array( $remote_ip, $allowed_ips, true ) ) {
return true;
}
status_header( 403 );
nocache_headers();
exit;
} );Этот вариант полезен, если нужно быстро закрыть доступ без правок nginx/Apache. Но помните: запрос уже дошёл до PHP, поэтому для высоконагруженного сайта серверное ограничение предпочтительнее.
Пошаговое решение без лишнего риска
- Соберите список IP, которым действительно нужен XML-RPC.
- Проверьте, что эти адреса статические. Если IP меняется, whitelist будет ломаться.
- Сделайте резервную копию конфигурации сервера или файла, который будете менять.
- Внедрите ограничение на уровне nginx или Apache, если есть доступ.
- Если доступа к серверу нет, используйте
mu-pluginили обычный плагин. - Проверьте доступ с разрешённого и запрещённого IP.
Как проверить, что ограничение работает
Проверка должна быть с двух сторон: с доверенного адреса и с внешнего адреса, который не входит в whitelist.
Проверка с разрешённого IP
С доверенного сервера выполните:
curl -i https://example.com/xmlrpc.phpЕсли endpoint нужен для интеграции, он должен отвечать так, как и раньше. Для XML-RPC это может быть ответ с ошибкой метода или сообщение о том, что сервер принимает только POST. Главное — не получить 403 от вашего ограничения.
Проверка с запрещённого IP
С любого другого адреса запрос должен завершаться отказом. В зависимости от реализации это может быть 403 Forbidden или другой код, но доступ к XML-RPC должен быть закрыт.
Дополнительно проверьте, что:
- мобильное приложение WordPress всё ещё подключается, если оно в whitelist;
- внешний редактор публикует записи без ошибок;
- в логах нет постоянных 500-ошибок после изменения конфигурации;
- страница сайта и админка работают как раньше.
Частые ошибки и как их исправить
Ограничили не тот IP
Самая частая проблема — в whitelist добавляют IP локальной сети, а запросы на сервер идут через NAT, CDN или прокси. В результате нужный сервис получает 403. Решение простое: смотрите реальный адрес в логах и проверяйте цепочку проксирования.
Сломали доступ через CDN или reverse proxy
Если сайт стоит за Cloudflare, nginx или другим прокси, REMOTE_ADDR может показывать не конечного клиента, а адрес прокси. Тогда проверка в WordPress будет работать неправильно. В такой схеме лучше настраивать ограничение на уровне самого прокси или корректно разбирать заголовки, которым вы доверяете.
Добавили правило, но забыли перезагрузить конфиг
Для nginx и Apache изменения в конфиге не всегда применяются сразу. После правки проверьте синтаксис и перезагрузите сервис. Для nginx это обычно выглядит так:
nginx -t
systemctl reload nginxЕсли синтаксис сломан, не перезагружайте сервис вслепую: сначала исправьте ошибку в конфиге.
Оставили XML-RPC открытым для всех POST-запросов
Иногда делают проверку только на уровне WordPress, но забывают, что endpoint всё равно доступен и может нагружать PHP. Если есть возможность, лучше закрыть его на веб-сервере, а в WordPress оставить только дополнительную страховку.
Практические советы по безопасности и производительности
Если XML-RPC нужен только одной интеграции, не держите его открытым для всего интернета. Белый список из нескольких IP обычно проще сопровождать, чем потом разбирать последствия массовых попыток входа.
Полезно также:
- вести отдельный список сервисов, которым нужен XML-RPC, с их IP и контактами;
- проверять, не появился ли у провайдера сервиса новый адрес;
- не смешивать ограничение XML-RPC с отключением REST API — это разные механизмы;
- при возможности переводить старые интеграции на REST API или webhook-логику;
- держать правило в конфиге сервера, а не только в теме оформления.
Если вы используете плагины для общей защиты сайта, проверьте, не дублируют ли они это ограничение. Иногда два разных правила дают неожиданный результат: один слой разрешает, второй блокирует, и отладка занимает лишнее время.
Для сайтов, где важна чистка лишних следов и снижение поверхности атаки, иногда удобно сочетать точечные ограничения с инструментами вроде Clearfy Pro, но только если вам действительно нужен набор таких функций, а не ради самого плагина. Сначала решайте задачу на уровне сервера и архитектуры, потом уже добавляйте надстройки.
Когда лучше всё-таки отключить XML-RPC полностью
Если после проверки выяснилось, что XML-RPC не нужен ни одной интеграции, его можно отключить полностью. Это проще в сопровождении, чем whitelist, который надо поддерживать вручную. Но делать это стоит только после проверки всех клиентов и сервисов, иначе вы получите скрытую поломку, которая всплывёт позже.
Практический критерий простой: если вы не можете назвать хотя бы один реальный сценарий использования XML-RPC на сайте, вероятно, он вам не нужен. Если сценарий есть, ограничение по IP обычно даёт лучший баланс между безопасностью и совместимостью.