Chống DDoS & Rate Limiting Nginx Trên VPS - Bảo Vệ Website Khỏi Bot Xấu & Brute Force
Website WordPress của bạn bị bot Trung Quốc, Nga, Mỹ quét xmlrpc.php 5 lần/giây? Có ai đó đang brute force wp-login.php với 1000 request/phút? Server load lên 100% vì 1 con bot? Rate limiting trong Nginx chính là firewall layer 7 — chặn đứng kiểu tấn công này mà không cần CloudFlare, không tốn thêm 1 đồng nào. Chỉ cần vài dòng config trên VPS TrumVPS của bạn.
Tại Sao Cần Rate Limiting?
Hầu hết các cuộc tấn công vào website nhỏ/medium không phải DDoS 100Gbps từ botnet lớn. Đó là các "DDoS mini" — 1-2 script tự động spam request vào endpoint yếu:
- Brute force
/wp-login.php— thử hàng ngàn mật khẩu - Spam
/xmlrpc.php— lợi dụng pingback/pingback DDoS - Quét API endpoint — gọi API liên tục, ăn hết tài nguyên
- Bot crawl quá đà — Google thì tốt, nhưng bot AI scraper thì không
- HTTP Flood — 1 IP gửi 50+ request/giây, làm CPU 100%
Các Module Rate Limiting Trong Nginx
Nginx có 2 module chính để giới hạn request:
| Module | Công Dụng | Khi Nào Dùng |
|---|---|---|
limit_req_zone | Giới hạn số request/giây từ 1 IP | Chống burst traffic, HTTP flood |
limit_conn_zone | Giới hạn số kết nối đồng thời từ 1 IP | Chống connection flooding |
Bước 1: Cấu Hình Rate Limiting Cơ Bản
Mở file cấu hình Nginx chính:
sudo nano /etc/nginx/nginx.conf
Thêm vào trong block http {}:
http {
# Định nghĩa zone rate limiting
# $binary_remote_addr = key theo IP client (4 bytes thay vì 7-15 bytes của $remote_addr)
# zone=mylimit:10m = tên zone, 10MB bộ nhớ (đủ cho ~160K IP)
# rate=10r/s = tối đa 10 request/giây/IP
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
# Zone riêng cho login (nghiêm ngặt hơn)
limit_req_zone $binary_remote_addr zone=loginlimit:10m rate=3r/m;
# Giới hạn kết nối đồng thời
limit_conn_zone $binary_remote_addr zone=connlimit:10m;
... # các config còn lại
}
rate=1r/s cho toàn bộ site, 1 trang HTML tải 5 file CSS/JS/ảnh cùng lúc sẽ bị chặn. Luôn kiểm tra thực tế trước khi áp dụng!Bước 2: Áp Dụng Rate Limit Vào Website
Mở file config site của bạn:
sudo nano /etc/nginx/sites-available/yoursite.com
Giới hạn toàn bộ site:
server {
listen 80;
server_name yoursite.com;
# Áp dụng rate limit cho tất cả request
location / {
limit_req zone=mylimit burst=20 nodelay;
limit_conn connlimit 10;
# ... proxy_pass hoặc root config
}
}
Giải thích:
zone=mylimit: Dùng zone đã định nghĩa ở trênburst=20: Cho phép "dồn" tối đa 20 request vượt rate, xếp hàng chờnodelay: Xử lý ngay các request trong burst (không delay), nhưng vẫn giới hạn tổng sốlimit_conn connlimit 10: Tối đa 10 kết nối đồng thời/IP
Giới hạn nghiêm ngặt cho WordPress login:
# Chặn brute force wp-login.php - chỉ 3 request/phút
location = /wp-login.php {
limit_req zone=loginlimit burst=2 nodelay;
limit_conn connlimit 2;
include fastcgi_params;
# ... fastcgi pass config
}
Chặn spam xmlrpc.php:
# Chặn hoàn toàn xmlrpc.php nếu không dùng
location = /xmlrpc.php {
deny all;
return 403;
}
# Hoặc rate limit nếu vẫn cần dùng
location = /xmlrpc.php {
limit_req zone=loginlimit burst=1 nodelay;
include fastcgi_params;
}
Bước 3: Chặn Bot & User-Agent Xấu
Nhiều bot không dùng IP cố định — chúng thay IP liên tục. Rate limiting theo IP không đủ. Cần chặn theo User-Agent:
Thêm vào /etc/nginx/conf.d/block-bots.conf:
# Map user-agent xấu → block
map $http_user_agent $bad_bot {
default 0;
~*scrapy 1;
~*curl 1;
~*wget 1;
~*python-requests 1;
~*go-http-client 1;
~*zgrab 1;
~*masscan 1;
~*nmap 1;
~*sqlmap 1;
~*nikto 1;
~*acunetix 1;
~*nessus 1;
~*openvas 1;
~*MJ12bot 1;
~*DotBot 1; # AI scraper
~*GPTBot 1; # OpenAI scraper
~*Claude 1; # Anthropic scraper
~*Bytespider 1; # ByteDance scraper
~*PetalBot 1;
}
Trong server block:
server {
# Từ chối bot xấu trước khi xử lý bất kỳ request nào
if ($bad_bot) {
return 403;
}
# ... config
}
Bước 4: Giới Hạn Request Body Size
Chặn upload file quá lớn làm đầy ổ cứng:
server {
# Giới hạn upload 10MB
client_max_body_size 10M;
# Giới hạn body timeout
client_body_timeout 12;
client_header_timeout 12;
# ... config
}
Bước 5: Cấu Hình Fail2Ban — Tự Động Ban IP
Rate limiting trong Nginx chỉ từ chối request (trả 503). Fail2Ban đọc log Nginx, phát hiện IP vi phạm, và ban hoàn toàn IP đó bằng firewall trong X phút.
Cài Fail2Ban:
sudo apt update sudo apt install -y fail2ban
Tạo filter cho Nginx rate limiting:
sudo nano /etc/fail2ban/filter.d/nginx-req-limit.conf
[Definition] failregex = ^.* limiting requests, excess:.*$ ignoreregex =
Tạo jail:
sudo nano /etc/fail2ban/jail.local
[nginx-req-limit] enabled = true port = http,https filter = nginx-req-limit logpath = /var/log/nginx/error.log findtime = 60 # Khoảng thời gian 60 giây maxretry = 10 # 10 lần vi phạm trong 60s → ban bantime = 3600 # Ban 1 giờ action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp]
Thêm Fail2Ban cho WordPress:
[wp-login] enabled = true port = http,https filter = wp-login logpath = /var/log/nginx/access.log findtime = 300 maxretry = 5 # 5 lần thử login thất bại trong 5 phút → ban bantime = 7200 # Ban 2 giờ
Khởi động lại:
sudo systemctl enable fail2ban --now sudo fail2ban-client status nginx-req-limit
Bước 6: Chặn Truy Cập File Nhạy Cảm
Thêm các rule chặn truy cập file cấu hình, backup, git:
# Trong server block
location ~ /\.git {
deny all;
return 404;
}
location ~ \.(env|sql|log|backup|bak|old|swp|save)$ {
deny all;
return 404;
}
location ~ /\.well-known {
# Cho phép Let's Encrypt
allow all;
}
# Ẩn header Nginx version
server_tokens off;
# Chặn clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;
# Chặn MIME sniffing
add_header X-Content-Type-Options "nosniff" always;
# Enable HSTS (nếu đã có SSL)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Bước 7: Giám Sát & Kiểm Tra
Xem IP nào đang bị rate limit:
sudo tail -f /var/log/nginx/error.log | grep "limiting requests"
Xem IP nào đang bị Fail2Ban ban:
sudo fail2ban-client status nginx-req-limit sudo iptables -L -n | grep ReqLimit
Unban 1 IP (nếu lỡ ban nhầm):
sudo fail2ban-client set nginx-req-limit unbanip 1.2.3.4
Kiểm tra rate limit có hoạt động không:
# Gửi 20 request trong 1 giây để test
for i in {1..20}; do curl -s -o /dev/null -w "%{http_code}\n" https://yoursite.com & done; wait
Nếu thấy xen kẽ 200 và 503 → rate limiting đang hoạt động!
sudo nano /etc/fail2ban/jail.local → thêm dòng ignoreip = 127.0.0.1/8 ::1 YOUR-IPTổng Hợp Cấu Hình Chuẩn Cho WordPress Trên VPS
Đây là template hoàn chỉnh cho 1 WordPress site đã được bảo vệ:
# /etc/nginx/sites-available/yoursite.com
server {
listen 443 ssl http2;
server_name yoursite.com www.yoursite.com;
# === SECURITY HEADERS ===
server_tokens off;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000" always;
# === RATE LIMITING ===
# Toàn trang: 10 req/s, burst 20
location / {
limit_req zone=mylimit burst=20 nodelay;
limit_conn connlimit 10;
try_files $uri $uri/ /index.php?$args;
}
# Login: 3 req/phút
location = /wp-login.php {
limit_req zone=loginlimit burst=2 nodelay;
limit_conn connlimit 2;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
# Chặn xmlrpc hoàn toàn
location = /xmlrpc.php {
deny all;
return 403;
}
# Chặn file nhạy cảm
location ~ /\.git { deny all; }
location ~ \.(env|sql|backup|bak|save)$ { deny all; }
# Giới hạn upload
client_max_body_size 10M;
client_body_timeout 12;
# === FASTCGI ===
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
# === SSL ===
ssl_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem;
}
# Redirect HTTP → HTTPS
server {
listen 80;
server_name yoursite.com www.yoursite.com;
return 301 https://$server_name$request_uri;
}
Nginx Rate Limiting vs CloudFlare: Khi Nào Dùng Cái Nào?
| Lớp bảo vệ | Công Cụ | Phù Hợp Khi |
|---|---|---|
| Lớp 1 (Edge) | CloudFlare Free | Giấu IP thật, chống DDoS volumetric, CDN cache |
| Lớp 2 (Server) | Nginx Rate Limit | Biết IP thật (bot bypass CloudFlare), bảo vệ endpoint cụ thể |
| Lớp 3 (Server) | Fail2Ban | Khi cần ban cả IP bằng firewall, không chỉ chặn HTTP |
| Lớp 4 (App) | WordPress plugin | Bảo vệ logic ứng dụng, captcha, 2FA |
Kết Luận
Rate limiting trong Nginx là 1 kỹ năng bảo mật cơ bản mà mọi chủ VPS nên biết. Chỉ cần copy-paste vài dòng config trong bài này, website WordPress của bạn đã được bảo vệ khỏi 80% các cuộc tấn công layer 7 phổ biến nhất.
Với VPS TrumVPS từ 40K/tháng, bạn hoàn toàn có thể cấu hình Nginx + Fail2Ban + CloudFlare tạo thành "pháo đài" bảo mật website mà không tốn thêm bất kỳ chi phí nào cho dịch vụ bảo mật bên ngoài.
Cần VPS để thực hành bảo mật ngay?
VPS TrumVPS từ 40K/tháng - NVMe SSD - IP sạch - Thoải mái test rate limiting
Mã giảm giá: 42089QPI03TI (-9%)
🚀 THUÊ VPS NGAY