DISABLE_WP_CRON = true не закрывает доступ к эндпоинту wp-cron.php; это лишь останавливает WordPress от выполнения собственного loopback-запроса. Файл остается доступным из сети, поэтому любой желающий все еще может обратиться к нему и инициировать полную загрузку (bootstrap) WordPress.
Эта скрытая точка входа может расходовать ресурсы CPU, память и PHP-воркеры, особенно на высоконагруженных сайтах. Если вы думали, что «закрыли дверь», то это не так — пока что.
Почему эту настройку часто понимают неправильно
Когда WordPress выполняет запланированную задачу, он сначала пытается отправить быстрый HTTP-запрос к собственному файлу wp-cron.php. Установка DISABLE_WP_CRON в значение true приказывает ядру пропустить этот внутренний запрос. Ядро не меняет конфигурацию веб-сервера и не добавляет уровень аутентификации для wp-cron.php. Скрипт остается публичным URL-адресом, который возвращает статус 200, даже если PHP-процесс завершается преждевременно.
Злоумышленник, обнаруживший этот URL, может многократно обращаться к нему, заставляя WordPress каждый раз загружать все плагины, темы и базу данных. На виртуальном хостинге или сайте с ограниченным количеством PHP-воркеров этот единственный эндпоинт может стать вектором для DoS-атаки (denial-of-service).
Что на самом деле нужно сделать
Чтобы перенести выполнение запланированных задач на планировщик системного уровня (cron, systemd-timer и т. д.) и закрыть публичный доступ, выполните следующие пять шагов.
1. Отключите внутренний loopback
Добавьте строку
define( 'DISABLE_WP_CRON', true );
в wp-config.php. Это предотвратит попытки WordPress выполнить собственный HTTP-запрос, но не остановит внешние вызовы.
2. Заблокируйте wp-cron.php на уровне веб-сервера
Например, в Nginx добавьте блок location, который возвращает 403 Forbidden:
location = /wp-cron.php {
return 403;
}
Теперь сервер отклоняет запрос еще до запуска PHP, исключая затраты на загрузку (bootstrap) системы.
3. Добавьте mu-plugin в качестве страховки
Создайте must-use плагин (разместите его в wp-content/mu-plugins), который будет логировать любой запрос к wp-cron.php и завершаться с кодом 403. Это позволит перехватить запросы, которые каким-то образом обходят правило сервера — например, через другой хостнейм или правила на границе CDN.
4. Подавите асинхронные вызовы Action Scheduler
Многие плагины используют библиотеку Action Scheduler, которая может порождать собственные loopback-запросы. Используйте хук action_scheduler_queue_runner и делайте ранний выход (return early) для запросов, не являющихся CLI, чтобы библиотека не пыталась «открыть свои собственные двери».
5. Отключите очередь от хука WP-Cron
Удалите стандартный обработчик очереди Action Scheduler, привязанный к хуку wp cron. Это гарантирует, что очередь будет запускаться только тогда, когда вы явно вызываете её из командной строки.
Правильный запуск задач
Когда публичный эндпоинт закрыт, используйте системный планировщик для вызова WordPress раз в минуту (или с любой другой необходимой частотой) через WP-CLI:
wp cron event run --due-now
Эта единственная команда обрабатывает как основные события cron, так и очередь Action Scheduler в контролируемой среде, используя тот же PHP-процесс, который вы использовали бы для любой другой CLI-задачи.
Измеримые преимущества
- Безопасность — неавторизованный пользователь не может запустить тяжелые фоновые задачи.
- Производительность — PHP-воркеры остаются доступными для реальных посетителей; скачки потребления памяти из-за случайных обращений к cron исчезают.
- Надежность — планирование становится проактивным; вы точно знаете, когда выполняется задача, потому что ею управляет системный cron, а не загрузка страницы посетителем.
На что обратить внимание после изменений
Не полагайтесь на HTTP-статус wp-cron.php; он все еще может возвращать 200, даже если запрос заблокирован на уровне PHP. Вместо этого:
- Следите за размером очереди Action Scheduler. Растущая очередь часто сигнализирует о пропущенных запусках.
- Проверяйте серверные логи на наличие записей «403» из блока
locationдля wp-cron.php. - Наблюдайте за количеством процессов PHP-FPM или FastCGI в периоды пикового трафика, чтобы подтвердить снижение нагрузки.
Предостережение
Некоторые администраторы оставляют DISABLE_WP_CRON в значении false, так как на сайтах с низкой посещаемостью cron срабатывает естественным образом. Описанный выше подход полностью устраняет эту зависимость, но добавляет этап обслуживания: вы должны гарантировать надежную работу системного планировщика. Если демон cron на сервере выйдет из строя, запланированные задачи остановятся. Сочетайте эту настройку с мониторингом системной службы cron, чтобы избежать этой ловушки.
Итог: установка DISABLE_WP_CRON в значение true лишь останавливает WordPress от самопроизвольных запросов; она не закрывает публичный эндпоинт wp-cron.php. Заблокируйте файл на уровне веб-сервера, добавьте резервный mu-plugin и направьте всю запланированную работу через системный планировщик с помощью WP-CLI. Это обезопасит сайт, сократит ненужную нагрузку на PHP и даст вам полный контроль над временем выполнения фоновых задач.
