DISABLE_WP_CRON = true не закриває endpoint wp-cron.php; він лише зупиняє WordPress від виконання власного loopback-запиту. Файл залишається доступним з вебу, тому будь-хто все ще може звернутися до нього та спровокувати повне завантаження (bootstrap) WordPress.
Ця прихована точка входу може марнувати ресурси CPU, пам'яті та PHP workers, особливо на завантажених сайтах. Якщо ви думали, що вже зачинили двері, то це не так — поки що.
Чому це налаштування часто розуміють неправильно
Коли WordPress виконує заплановане завдання, він спочатку намагається зробити швидкий HTTP-запит до власного файлу wp-cron.php. Встановлення DISABLE_WP_CRON у значення true наказує ядру пропустити цей внутрішній запит. Ядро не змінює конфігурацію вебсервера і не додає жодного рівня автентифікації до wp-cron.php. Скрипт залишається публічною URL-адресою, яка повертає статус 200, навіть якщо PHP-процес переривається раніше.
Зловмисник, який дізнається URL, може повторно надсилати запити (ping), змушуючи WordPress щоразу завантажувати всі плагіни, теми та базу даних. На спільному хостингу або на сайті з обмеженою кількістю PHP workers цей єдиний endpoint може стати вектором 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. Це дозволить перехопити запити, які якось обходять правило сервера — наприклад, через інше ім'я хоста або правило на edge-сервері CDN.
4. Придушіть асинхронні виклики Action Scheduler
Багато плагінів використовують бібліотеку Action Scheduler, яка може створювати власні loopback-запити. Використовуйте хук action_scheduler_queue_runner і робіть ранній вихід (return early) для запитів, що не є CLI, щоб запобігти спробам бібліотеки відкрити власні двері.
5. Від'єднайте чергу від хука WP-Cron
Видаліть стандартний черговий запускник Action Scheduler, який прив'язаний до хука wp cron. Це гарантує, що черга запускатиметься лише тоді, коли ви явно активуєте її через командний рядок.
Правильний запуск завдань
Коли публічний endpoint заблоковано, використовуйте системний планувальник, щоб викликати WordPress раз на хвилину (або з іншою потрібною частотою) через WP-CLI:
wp cron event run --due-now
Ця єдина команда обробляє основні cron-події та чергу Action Scheduler у контрольованому середовищі, використовуючи той самий PHP-процес, який ви б використовували для будь-якого іншого CLI-завдання.
Переваги, які можна виміряти
- Безпека – жоден неавторизований користувач не зможе запустити важкі фонові процеси.
- Продуктивність – PHP workers залишаються доступними для реальних відвідувачів; стрибки споживання пам'яті через випадкові запити 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 від самостійного звернення до себе; воно не закриває публічний endpoint wp-cron.php. Заблокуйте файл на рівні вебсервера, додайте резервний варіант у вигляді mu-plugin і спрямуйте всі заплановані завдання через системний планувальник за допомогою WP-CLI. Це захистить сайт, зменшить зайве навантаження на PHP і дасть вам точний контроль над часом виконання фонових завдань.
