DISABLE_WP_CRON = true không đóng kín endpoint wp-cron.php; nó chỉ ngăn WordPress tự thực hiện yêu cầu loopback của chính mình. Tệp này vẫn có thể truy cập được từ web, vì vậy bất kỳ ai cũng có thể truy cập nó và buộc WordPress phải thực hiện quá trình bootstrap đầy đủ.

Điểm truy cập ẩn đó có thể gây lãng phí CPU, bộ nhớ và các PHP workers, đặc biệt là trên các trang web bận rộn. Nếu bạn nghĩ rằng mình đã đóng cửa, thì thực tế là chưa đâu.

Tại sao thiết lập này thường bị hiểu lầm

Khi WordPress chạy một tác vụ đã lên lịch, trước tiên nó sẽ thử thực hiện một yêu cầu HTTP nhanh đến tệp wp-cron.php của chính nó. Việc đặt DISABLE_WP_CRON thành true sẽ yêu cầu nhân (core) bỏ qua yêu cầu nội bộ đó. Nhân WordPress không thay đổi cấu hình máy chủ web, cũng không thêm bất kỳ lớp xác thực nào vào wp-cron.php. Tập lệnh này vẫn là một URL công khai trả về trạng thái 200 ngay cả khi tiến trình PHP bị hủy sớm.

Một kẻ tấn công nếu phát hiện ra URL này có thể ping nó liên tục, khiến WordPress phải tải tất cả các plugin, theme và cơ sở dữ liệu mỗi lần như vậy. Trên một máy chủ dùng chung (shared host) hoặc một trang web có giới hạn PHP workers, endpoint duy nhất đó có thể trở thành một vector tấn công từ chối dịch vụ (denial-of-service).

Những gì thực sự cần phải làm

Để chuyển các công việc đã lên lịch sang trình lập lịch ở cấp độ hệ thống (cron, systemd-timer, v.v.) và đóng cánh cửa công khai, hãy thực hiện theo năm bước sau.

1. Vô hiệu hóa loopback nội bộ

Thêm dòng

define( 'DISABLE_WP_CRON', true );

vào wp-config.php. Điều này ngăn WordPress thực hiện yêu cầu HTTP của chính nó, nhưng nó không ngăn chặn các cuộc gọi từ bên ngoài.

2. Chặn wp-cron.php tại máy chủ web

Ví dụ với Nginx, hãy chèn một location block trả về 403 Forbidden:

location = /wp-cron.php {
    return 403;
}

Giờ đây, máy chủ sẽ từ chối yêu cầu trước khi PHP bắt đầu, giúp loại bỏ chi phí bootstrap.

3. Thêm một mu-plugin làm lưới an toàn

Tạo một must-use plugin (đặt trong wp-content/mu-plugins) để ghi lại (log) bất kỳ yêu cầu nào chạm tới wp-cron.php và thoát với mã 403. Điều này giúp bắt được các yêu cầu bằng cách nào đó đã vượt qua quy tắc của máy chủ—có thể thông qua một hostname khác hoặc một quy tắc CDN edge.

4. Ngăn chặn các cuộc gọi async của Action Scheduler

Nhiều plugin sử dụng thư viện Action Scheduler, thư viện này có thể tạo ra các yêu cầu loopback của riêng nó. Hãy hook vào action_scheduler_queue_runner và return sớm đối với các yêu cầu không phải CLI, nhằm ngăn thư viện cố gắng tự mở các cánh cửa của chính nó.

5. Gỡ bỏ queue runner khỏi hook WP-Cron

Gỡ bỏ Action Scheduler queue runner mặc định đang được gắn vào hook wp cron. Điều này đảm bảo hàng đợi chỉ chạy khi bạn kích hoạt nó một cách rõ ràng từ dòng lệnh.

Chạy các tác vụ đúng cách

Khi endpoint công khai đã được đóng kín, hãy sử dụng trình lập lịch hệ thống để gọi WordPress mỗi phút một lần (hoặc bất kỳ tần suất nào bạn cần) thông qua WP-CLI:

wp cron event run --due-now

Lệnh duy nhất đó sẽ xử lý các sự kiện cron của nhân hàng đợi Action Scheduler trong một môi trường được kiểm soát, sử dụng cùng một tiến trình PHP mà bạn sẽ sử dụng cho bất kỳ tác vụ CLI nào khác.

Những lợi ích bạn có thể đo lường được

  • Bảo mật – Không người dùng không xác thực nào có thể bắt đầu các công việc chạy ngầm nặng nề.
  • Hiệu suất – Các PHP workers luôn sẵn sàng cho khách truy cập thực; các đợt tăng vọt bộ nhớ do các lần truy cập cron không mong muốn sẽ biến mất.
  • Độ tin cậy – Việc lập lịch trở nên chủ động; bạn biết chính xác khi nào một tác vụ chạy vì nó được điều khiển bởi cron của hệ thống, chứ không phải bởi lượt tải trang của khách truy cập.

Những điều cần theo dõi sau khi thay đổi

Đừng dựa vào mã trạng thái HTTP của wp-cron.php; nó vẫn có thể trả về 200 ngay cả khi đã bị PHP chặn. Thay vào đó:

  • Theo dõi kích thước hàng đợi Action Scheduler. Một hàng đợi ngày càng lớn thường là dấu hiệu của việc các lần chạy bị bỏ lỡ.
  • Kiểm tra nhật ký (log) máy chủ để tìm các mục "403" từ location block của wp-cron.php.
  • Quan sát số lượng tiến trình PHP-FPM hoặc FastCGI trong thời gian lưu lượng truy cập cao để xác nhận rằng tải trọng đã giảm xuống.

Một lưu ý thận trọng

Một số quản trị viên để DISABLE_WP_CRON là false vì họ dựa vào các trang web có lưu lượng truy cập thấp để kích hoạt cron một cách tự nhiên. Cách tiếp cận trên loại bỏ hoàn toàn sự phụ thuộc đó, nhưng nó sẽ thêm một bước bảo trì: bạn phải đảm bảo trình lập lịch hệ thống chạy một cách đáng tin cậy. Nếu cron daemon của máy chủ bị lỗi, các tác vụ đã lên lịch sẽ dừng lại. Hãy kết hợp việc thiết lập với việc giám sát dịch vụ cron của hệ thống để tránh sai lầm đó.

Tóm lại: việc đặt DISABLE_WP_CRON thành true chỉ ngăn WordPress tự ping chính nó; nó không đóng endpoint wp-cron.php công khai. Hãy chặn tệp này tại máy chủ web, thêm một mu-plugin dự phòng và điều hướng tất cả các công việc đã lên lịch thông qua trình lập lịch hệ thống bằng WP-CLI. Làm như vậy sẽ bảo mật trang web, giảm bớt các công việc PHP không cần thiết và giúp bạn kiểm soát chính xác thời điểm các tác vụ chạy ngầm được thực thi.