Secure Ubuntu server cho website WordPress: Nginx, PHP-FPM, SSL, quyền file
Một site WordPress nhanh chưa đủ. Site phải khó bị chiếm quyền, dễ khôi phục, ít lộ thông tin, đúng quyền file, có SSL chuẩn, Nginx/PHP-FPM tách bạch. Phần lớn sự cố WordPress không đến từ “hacker quá giỏi”, mà từ cấu hình ẩu: SSH mở rộng, user dùng chung, file 777, PHP execute trong uploads, SSL yếu, plugin lỗi thời, backup không test.
Bài này tập trung vào hardening Ubuntu server chạy WordPress với stack: Ubuntu + Nginx + PHP-FPM + MariaDB/MySQL + SSL.
1. Nền tảng server: cập nhật, user, SSH
Trước WordPress → khóa nền OS.
Cập nhật hệ thống
sudo apt update && sudo apt upgrade -y
sudo apt install unattended-upgrades ufw fail2ban curl unzip -y
sudo dpkg-reconfigure unattended-upgradesTạo user deploy, hạn chế root
adduser deploy
usermod -aG sudo deploySSH bằng root → rủi ro cao. Tắt root login:
sudo nano /etc/ssh/sshd_configKhuyến nghị:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yesRestart:
sudo systemctl restart ssh2. Firewall: chỉ mở cổng cần thiết
UFW đơn giản, đủ dùng.
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw statusPort cần: 22, 80, 443. Nếu đổi SSH port, mở port mới trước khi đóng port cũ.
Ví dụ:
sudo ufw allow 2222/tcpSau đó chỉnh SSH config.
3. Cài Nginx, PHP-FPM, extension WordPress
sudo apt install nginx php-fpm php-mysql php-cli php-curl php-gd php-mbstring php-xml php-zip php-imagick -yKiểm tra PHP-FPM:
systemctl status php8.3-fpmPhiên bản có thể khác: php8.1-fpm, php8.2-fpm, php8.3-fpm.
4. Cấu hình Nginx an toàn cho WordPress
Tạo server block:
sudo nano /etc/nginx/sites-available/example.comMẫu cấu hình:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.php index.html;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
client_max_body_size 64M;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /(?:uploads|files)/..php$ {
deny all;
}
location ~ /.(?!well-known).* {
deny all;
}
location ~* .(?:bak|conf|sql|ini|log|sh|inc|swp|dist)$ {
deny all;
}
location = /xmlrpc.php {
deny all;
}
}
Kích hoạt:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxGiải thích nhanh
– try_files → permalink WordPress chạy đúng.
– Chặn PHP trong uploads → ngăn upload shell.
– Chặn dotfile → bảo vệ .env, .git.
– Chặn file backup/config/log → giảm rò rỉ.
– Chặn xmlrpc.php nếu không dùng Jetpack/app mobile → giảm brute force/DDoS.
Nếu cần XML-RPC, không deny toàn bộ; giới hạn IP hoặc dùng plugin bảo vệ.
5. PHP-FPM hardening
Mở pool config:
sudo nano /etc/php/8.3/fpm/php.iniKhuyến nghị:
expose_php = Off
display_errors = Off
log_errors = On
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 120
cgi.fix_pathinfo = 0Restart:
sudo systemctl restart php8.3-fpmTách pool theo site
Nhiều website trên cùng server → nên tách user/pool. Một site bị lỗi → không lan toàn server.
Tạo user riêng:
sudo adduser --system --group --home /var/www/example.com wp-examplePool riêng:
sudo cp /etc/php/8.3/fpm/pool.d/www.conf /etc/php/8.3/fpm/pool.d/example.com.confChỉnh:
[example.com]
user = wp-example
group = wp-example
listen = /run/php/php8.3-fpm-example.com.sock
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 20Nginx:
fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock;Kết quả: site isolation tốt hơn.
6. SSL/TLS với Let’s Encrypt
Cài Certbot:
sudo apt install certbot python3-certbot-nginx -yCấp cert:
sudo certbot --nginx -d example.com -d www.example.comTest renew:
sudo certbot renew --dry-runTăng bảo mật HTTPS
Certbot thường tự thêm redirect HTTP → HTTPS. Kiểm tra Nginx có dòng:
return 301 https://$host$request_uri;Có thể thêm header:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;HSTS chỉ bật khi chắc chắn HTTPS ổn lâu dài:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;7. Quyền file WordPress: điểm sống còn
Sai quyền file → hậu quả nặng. 777 → gần như mời tấn công.
Giả sử source ở:
/var/www/example.com/publicOwner nên là user site, group là web server:
sudo chown -R wp-example:www-data /var/www/example.com/publicQuyền thư mục:
sudo find /var/www/example.com/public -type d -exec chmod 755 {} ;Quyền file:
sudo find /var/www/example.com/public -type f -exec chmod 644 {} ;wp-config.php nhạy cảm:
sudo chmod 640 /var/www/example.com/public/wp-config.phpNếu muốn chặt hơn:
sudo chmod 600 /var/www/example.com/public/wp-config.phpNhưng phải đảm bảo PHP-FPM user đọc được.
Không cho chỉnh theme/plugin từ admin
Trong wp-config.php:
define('DISALLOW_FILE_EDIT', true);Nếu muốn chặn cài/update từ admin, dùng:
define('DISALLOW_FILE_MODS', true);Đổi lại: update phải qua SSH/WP-CLI/deploy pipeline.
8. Bảo vệ database
Tạo DB/user riêng, không dùng root DB cho WordPress.
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;Không cấp GRANT ALL nếu không cần. Không mở MySQL ra Internet. Kiểm tra bind:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnfNên có:
bind-address = 127.0.0.19. WordPress hardening bên trong
Salt keys
Tạo salt mới:
https://api.wordpress.org/secret-key/1.1/salt/Dán vào wp-config.php.
Prefix table
Không dùng wp_ nếu cài mới. Ví dụ:
$table_prefix = 'x7p_';Không phải lớp bảo vệ mạnh, nhưng giảm bot scan cơ bản.
Giới hạn login
Dùng plugin uy tín: Wordfence, Solid Security, Limit Login Attempts Reloaded. Nhưng đừng cài quá nhiều plugin bảo mật chồng chéo → lỗi, chậm, false positive.
Update đều
Core, plugin, theme lỗi thời → nguyên nhân phổ biến nhất.
wp core update
wp plugin update --all
wp theme update --allNên test staging trước site lớn.
10. Backup, log, giám sát
Không backup → không secure. Backup là tuyến phòng thủ cuối.
Nên có
– Backup DB hằng ngày.
– Backup file wp-content.
– Lưu ngoài server: S3, Backblaze, rsync server khác.
– Mã hóa backup.
– Test restore định kỳ.
Dump DB:
mysqldump -u wpuser -p wordpress > wordpress.sqlLog cần xem
/var/log/nginx/example.com.access.log
/var/log/nginx/example.com.error.log
/var/log/auth.log
/var/log/fail2ban.logTìm request đáng ngờ:
grep "wp-login.php" /var/log/nginx/example.com.access.log
grep "xmlrpc.php" /var/log/nginx/example.com.access.log11. Fail2ban cho SSH, Nginx, WordPress
Fail2ban → chặn brute force.
SSH jail thường có sẵn. Kiểm tra:
sudo fail2ban-client status
sudo fail2ban-client status sshdCó thể thêm jail cho Nginx login flood, nhưng cần regex đúng. Sai regex → chặn nhầm user thật. Với WordPress, plugin login limit thường dễ triển khai hơn.
12. Checklist nhanh sau triển khai
– SSH root login: off.
– Password SSH: off, dùng key.
– UFW: chỉ mở 22/80/443.
– Nginx: chặn PHP trong uploads.
– SSL: Let’s Encrypt auto-renew OK.
– PHP: expose_php=Off, display_errors=Off.
– File perms: dir 755, file 644, wp-config.php 640/600.
– DB user: riêng, quyền tối thiểu.
– WordPress: update, salt mới, không edit file từ admin.
– Backup: offsite, test restore.
– Logs: theo dõi định kỳ.
Kết luận thực tế
Secure WordPress trên Ubuntu không phải một lệnh cài plugin. Nó là chuỗi lớp bảo vệ: OS an toàn → SSH khóa chặt → firewall tối giản → Nginx chặn đường nguy hiểm → PHP-FPM tách quyền → SSL chuẩn → file permission đúng → DB least privilege → backup phục hồi được.
Nếu chỉ làm 5 việc quan trọng nhất: tắt SSH password/root, bật UFW, chặn PHP trong uploads, sửa quyền file, backup offsite. Làm thêm SSL header, PHP-FPM pool riêng, DB quyền tối thiểu → site WordPress vững hơn rõ rệt, ít phụ thuộc may mắn, dễ vận hành lâu dài.
Bình luận (0)
Chưa có bình luận. Hãy là người đầu tiên!