bảo mật WordPress production không chỉ là cài thêm một plugin bảo mật rồi để đó. Với một website chạy thật ngoài Internet, sysadmin cần nhìn WordPress như một ứng dụng production: có bề mặt tấn công, có tài khoản đặc quyền, có file upload, có database, có log, có backup và có quy trình khôi phục.
Bài này đi theo hướng thực chiến: giả sử bạn đang quản trị một website WordPress cho doanh nghiệp nhỏ hoặc blog kỹ thuật có traffic thật. Mục tiêu là giảm rủi ro phổ biến như brute force, plugin lỗi thời, lộ file cấu hình, quyền file quá rộng, thiếu backup, thiếu giám sát và cấu hình HTTPS chưa sạch.
Vì sao bảo mật WordPress production phải bắt đầu từ tư duy vận hành?
WordPress rất dễ triển khai, nhưng cũng vì vậy nhiều site production bị đối xử như môi trường thử nghiệm. Một tài khoản admin dùng chung, plugin cài thử không xoá, theme cũ vẫn nằm trên server, quyền thư mục 777, backup không kiểm tra restore — tất cả đều là điểm yếu.
Trong production, bảo mật WordPress production nên được hiểu là một chuỗi kiểm soát liên tục: phòng ngừa, phát hiện, phản ứng và phục hồi. Bạn không thể đảm bảo “không bao giờ bị tấn công”, nhưng có thể khiến việc tấn công khó hơn, phát hiện nhanh hơn và khôi phục ít đau hơn.
Kiến trúc lab/production mẫu
Mô hình tham chiếu trong bài:
- Ubuntu Server hoặc Debian chạy Nginx/Apache + PHP-FPM.
- MariaDB/MySQL tách user riêng cho WordPress.
- HTTPS qua Let’s Encrypt hoặc CDN/WAF như Cloudflare.
- WordPress đặt tại
/var/www/example.com. - Backup lưu ra object storage hoặc máy khác, không chỉ lưu cùng server.
Nếu bạn dùng hosting panel, các nguyên tắc vẫn áp dụng: cập nhật, phân quyền, tài khoản tối thiểu, backup, log và WAF.
Checklist hardening WordPress theo lớp
1. Cập nhật core, plugin và theme có kiểm soát
Plugin lỗi thời là nguyên nhân rất phổ biến của sự cố WordPress. Trước khi cập nhật, hãy có backup và môi trường staging nếu site quan trọng.
wp core version
wp plugin list --status=active
wp theme list
Lệnh trên dùng WP-CLI để kiểm tra phiên bản core, plugin đang bật và theme đang có. Output mẫu:
+----------------------+----------+-----------+---------+
| name | status | update | version |
+----------------------+----------+-----------+---------+
| wordpress-seo | active | none | 27.7 |
| contact-form-7 | active | available | 6.0.1 |
+----------------------+----------+-----------+---------+
Nếu có update, ưu tiên cập nhật plugin bảo mật, SEO, form, page builder và plugin có quyền upload/file manager. Không giữ theme/plugin không dùng:
wp plugin delete plugin-khong-dung
wp theme delete theme-cu-khong-dung
2. Phân quyền file đúng, tránh 777
Quyền file quá rộng khiến mã độc dễ ghi vào source. Một baseline thường dùng:
cd /var/www/example.com
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod 640 wp-config.php
Thư mục cần ghi như wp-content/uploads vẫn nên được kiểm soát bởi user web/PHP-FPM phù hợp, không dùng chmod -R 777. Nếu deploy qua Git/CI, hãy tách user deploy và user runtime.
3. Bảo vệ wp-config.php và thông tin nhạy cảm
wp-config.php chứa credential database, salt và cấu hình quan trọng. Với Nginx, chặn truy cập file nhạy cảm:
location ~* /(wp-config\.php|readme\.html|license\.txt) {
deny all;
}
Với Apache, có thể dùng rule trong virtual host hoặc .htaccess. Ngoài ra, bật salt mạnh từ trang chính thức của WordPress: WordPress.org secret-key service.
4. Giới hạn đăng nhập và giảm brute force
Đổi tên tài khoản admin mặc định nếu còn dùng, bật mật khẩu mạnh và 2FA cho tài khoản quản trị. Có thể giới hạn truy cập wp-login.php theo IP nếu đội vận hành có IP cố định.
location = /wp-login.php {
allow 203.0.113.10;
deny all;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
Nếu không có IP cố định, dùng WAF/rate limit. Tham khảo tài liệu chính thống của Nginx về rate limiting: ngx_http_limit_req_module.
5. Tắt sửa file từ dashboard
Không nên cho phép sửa theme/plugin trực tiếp từ WordPress admin trên production. Thêm vào wp-config.php:
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', false);
DISALLOW_FILE_EDIT tắt editor trong dashboard. DISALLOW_FILE_MODS nếu đặt true sẽ chặn cài/cập nhật plugin qua admin; chỉ bật khi bạn có quy trình deploy riêng.
6. Database user theo nguyên tắc least privilege
Không dùng tài khoản root MySQL cho WordPress. Tạo user riêng:
CREATE DATABASE wp_prod CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_prod'@'localhost' IDENTIFIED BY 'mat-khau-manh';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON wp_prod.* TO 'wp_prod'@'localhost';
FLUSH PRIVILEGES;
Trong nhiều môi trường, WordPress cần ALTER khi plugin cập nhật schema. Tuy nhiên không nên cấp quyền global hoặc dùng user có quyền quản trị toàn server.
Giám sát log và dấu hiệu bất thường
Bảo mật không chỉ là cấu hình ban đầu. Bạn cần xem log định kỳ để phát hiện brute force, scan plugin, upload bất thường hoặc lỗi PHP lặp lại.
tail -f /var/log/nginx/access.log | grep -E "wp-login|xmlrpc|wp-admin|wp-content/plugins"
tail -f /var/log/nginx/error.log
tail -f /var/log/php8.3-fpm.log
Dấu hiệu cần chú ý:
- Nhiều request POST tới
wp-login.phptừ nhiều IP. - Scan đường dẫn plugin cũ như
/wp-content/plugins/.... - File PHP xuất hiện trong
uploads. - CPU tăng bất thường do PHP-FPM hoặc MySQL.
Backup và restore: phần hay bị làm qua loa
Một backup chưa từng restore thử chưa phải backup đáng tin. Tối thiểu cần có:
- Backup database hằng ngày.
- Backup
wp-contenthằng ngày hoặc theo tần suất cập nhật. - Lưu bản backup ngoài server chính.
- Retention rõ ràng: ví dụ 7 bản ngày, 4 bản tuần, 3 bản tháng.
mysqldump --single-transaction --quick --lock-tables=false wp_prod | gzip > wp_prod_$(date +%F).sql.gz
tar -czf wp-content_$(date +%F).tar.gz /var/www/example.com/wp-content
Khôi phục thử trên máy lab:
gunzip -c wp_prod_2026-06-01.sql.gz | mysql wp_restore
tar -xzf wp-content_2026-06-01.tar.gz -C /tmp/restore-test
Troubleshooting lỗi thường gặp sau hardening
Lỗi 403 khi vào wp-admin
Thường do rule Nginx/Apache chặn quá tay hoặc allow IP sai. Kiểm tra access/error log trước, sau đó tạm nới rule theo từng phần thay vì xoá toàn bộ cấu hình bảo mật.
Không upload được ảnh
Kiểm tra quyền thư mục wp-content/uploads, owner của PHP-FPM và giới hạn upload trong PHP:
php -i | grep -E "upload_max_filesize|post_max_size"
ls -ld wp-content/uploads
Plugin cập nhật thất bại
Có thể do DISALLOW_FILE_MODS, quyền file hoặc thiếu disk space. Kiểm tra:
df -h
wp plugin update --all --dry-run
Checklist nghiệm thu bảo mật WordPress production
- Không còn tài khoản admin mặc định dùng mật khẩu yếu.
- 2FA bật cho tài khoản quản trị.
- Core/plugin/theme cập nhật và xoá phần không dùng.
- Không có quyền
777trong thư mục WordPress. wp-config.phpkhông truy cập được từ web.- Dashboard file editor đã tắt.
- Backup database và
wp-contentcó lịch chạy tự động. - Đã restore thử ít nhất một bản backup.
- Log web/PHP được theo dõi và có cảnh báo cơ bản.
- HTTPS hợp lệ, không mixed content.
Lab cuối bài
- Dựng một WordPress lab trên VPS hoặc máy ảo nội bộ.
- Tạo một plugin/theme thử nghiệm rồi xoá khi không dùng.
- Áp dụng quyền file 755/644 và kiểm tra upload ảnh.
- Thêm rule chặn
wp-config.php, xác minh bằng trình duyệt. - Tạo backup database +
wp-content, restore sang database lab khác. - Ghi lại các lỗi gặp phải và cách xử lý vào runbook vận hành.
Kết luận
Bảo mật WordPress production không phải một checklist làm một lần rồi quên. Sysadmin cần biến nó thành thói quen vận hành: cập nhật có kiểm soát, phân quyền chặt, backup kiểm chứng, log rõ ràng và phản ứng nhanh khi có dấu hiệu bất thường. Khi làm đều các lớp này, WordPress vẫn có thể là một nền tảng ổn định, dễ quản trị và đủ an toàn cho nhiều nhu cầu production.
