Cấu hình chống DDoS cho Nginx

Chào bạn,

Tính đến thời điểm hiện tại (Thứ Ba, 22 tháng 4 năm 2025, 17:02 GMT+7 tại Việt Nam), việc cấu hình Nginx để chống lại các cuộc tấn công DDoS (Distributed Denial of Service) là một bước quan trọng để bảo vệ máy chủ và ứng dụng web của bạn. Nginx cung cấp một số cơ chế mạnh mẽ để giảm thiểu tác động của các cuộc tấn công, đặc biệt là các cuộc tấn công ở Lớp 7 (Layer 7 - lớp ứng dụng).

Tuy nhiên, cần lưu ý rằng Nginx không phải là giải pháp chống DDoS toàn diện. Nó hiệu quả với các cuộc tấn công dựa trên request HTTP/HTTPS, nhưng có thể không đủ sức chống lại các cuộc tấn công quy mô lớn ở Lớp 3/4 (Layer 3/4 - lớp mạng/vận chuyển). Một chiến lược phòng thủ tốt thường kết hợp Nginx với các giải pháp khác như tường lửa mạng, dịch vụ CDN có chống DDoS (như Cloudflare, Akamai, AWS Shield), và tinh chỉnh hệ điều hành.

Dưới đây là các cấu hình Nginx phổ biến để giúp giảm thiểu DDoS:

1. Giới hạn Tỷ lệ Yêu cầu (Rate Limiting)

Đây là biện pháp hiệu quả nhất trong Nginx để chống lại các cuộc tấn công brute-force, cào dữ liệu (scraping), hoặc tấn công làm cạn kiệt tài nguyên bằng cách gửi quá nhiều yêu cầu.

  • Định nghĩa Zone trong khối http:
    Nginx
    http {
       
    # ... các cài đặt khác ...

       
    # Định nghĩa một zone tên là 'req_limit_per_ip' dựa trên địa chỉ IP client ($binary_remote_addr)
       
    # Kích thước zone: 10m (khoảng 160,000 địa chỉ IP)
       
    # Tỷ lệ: 10 requests/giây (r=10r/s)
       
    limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;

       
    # (Tùy chọn) Zone khác cho các URL nhạy cảm (ví dụ: trang đăng nhập) với tỷ lệ thấp hơn
       
    limit_req_zone $binary_remote_addr zone=login_limit_per_ip:10m rate=5r/m; # 5 requests/phút

       
    # ... các cài đặt khác ...
    }
  • Áp dụng Zone trong khối server hoặc location:
    Nginx
    server {
       
    # ... listen, server_name ...

       
    # Áp dụng giới hạn chung cho toàn bộ server
       
    limit_req zone=req_limit_per_ip burst=20 nodelay;
       
    # burst=20: Cho phép vượt quá rate tối đa 20 requests (chúng sẽ được xử lý nhanh chóng nếu nodelay)
       
    # nodelay: Xử lý ngay các request trong burst thay vì trì hoãn chúng. Thích hợp cho web tương tác.
       
    # Nếu không có nodelay (mặc định là delay), các request vượt rate sẽ bị trì hoãn, có thể làm chậm trải nghiệm người dùng hợp lệ.

       
    location /login {
           
    # Áp dụng giới hạn chặt hơn cho trang đăng nhập
           
    limit_req zone=login_limit_per_ip burst=5 nodelay;
           
    # ... proxy_pass hoặc try_files ...
       }

       
    location /api/ {
           
    # Có thể áp dụng rate limit khác cho API
           
    limit_req zone=req_limit_per_ip burst=40 nodelay;
           
    # ... proxy_pass ...
       }

       
    # ... các location khác ...
    }

2. Giới hạn Số lượng Kết nối Đồng thời (Connection Limiting)

Hữu ích để ngăn chặn một địa chỉ IP mở quá nhiều kết nối đến máy chủ cùng lúc, làm cạn kiệt tài nguyên.

  • Định nghĩa Zone trong khối http:
    Nginx
    http {
       
    # ... các cài đặt khác ...

       
    # Định nghĩa zone tên 'conn_limit_per_ip' dựa trên IP client
       
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;

       
    # (Tùy chọn) Dựa trên server block (toàn bộ virtual host)
       
    # limit_conn_zone $server_name zone=conn_limit_per_server:10m;

       
    # ... các cài đặt khác ...
    }
  • Áp dụng Zone trong khối server hoặc location:
    Nginx
    server {
       
    # ... listen, server_name ...

       
    # Giới hạn 10 kết nối đồng thời từ mỗi IP tới server này
       
    limit_conn conn_limit_per_ip 10;

       
    # (Tùy chọn) Giới hạn tổng số kết nối tới server này là 1000
       
    # limit_conn conn_limit_per_server 1000;

       
    # ... các location ...
    }

3. Đặt Thời gian Chờ (Timeouts) Hợp Lý

Giảm thời gian chờ cho các kết nối không hoạt động hoặc chậm giúp giải phóng tài nguyên nhanh hơn, chống lại các cuộc tấn công Slowloris.

Nginx

server {
   
# ... listen, server_name ...

   
# Thời gian chờ tối đa để đọc client request header
   
client_header_timeout 10s;
   
# Thời gian chờ tối đa để đọc client request body
   
client_body_timeout 10s;
   
# Thời gian gửi phản hồi cho client
   
send_timeout 10s;
   
# Thời gian giữ kết nối keep-alive
   
keepalive_timeout 15s 10s; # Timeout 15s, header timeout 10s

   
# ... các location ...
}

Lưu ý: Giá trị timeout quá thấp có thể ảnh hưởng đến người dùng có kết nối chậm hoặc khi tải lên/xuống tệp lớn. Hãy điều chỉnh cẩn thận.

4. Giới hạn Kích thước Request Body (client_max_body_size)

Ngăn chặn các cuộc tấnň công bằng cách gửi dữ liệu lớn không cần thiết (ví dụ: tải lên tệp quá lớn).

Nginx

http {
   
# ... các cài đặt khác ...
   
client_max_body_size 10m; # Giới hạn chung là 10MB
   
# ...
}

server {
   
# ...
   
location /upload {
       
# Cho phép kích thước lớn hơn cho location cụ thể này
       
client_max_body_size 100m;
       
# ...
   }
   
# ...
}

5. Chặn các User Agent Độc hại (Bad Bots)

Bạn có thể chặn các bot tự động được biết đến là độc hại hoặc không mong muốn dựa trên chuỗi User-Agent của chúng.

Nginx

http {
   
# ...

   
# Sử dụng map để tránh dùng nhiều 'if' (hiệu năng tốt hơn)
   
# Tạo biến $block_ua, mặc định là 0
   
map $http_user_agent $block_ua {
       
default 0;
       
# Nếu User Agent rỗng hoặc chứa các chuỗi đáng ngờ thì đặt biến là 1
       "" 1;
       "~*(compatible|bot|scanner|spider|crawler|curl|wget)" 1;
# Ví dụ cơ bản
       
# Thêm các User Agent cụ thể bạn muốn chặn
       "~*Baiduspider" 1;
       "~*YandexBot" 1;
# Nếu bạn không cần bot từ Yandex
   }

   
# ...
}

server {
   
# ...

   
# Kiểm tra biến $block_ua trong server block
   
if ($block_ua) {
       
return 403; # Forbidden
       
# Hoặc return 444; # Đóng kết nối không trả lời (ít gây chú ý hơn)
   }

   
# ... các location ...
}

Lưu ý: Danh sách User Agent cần được cập nhật thường xuyên và cẩn thận để không chặn nhầm các bot hợp lệ (như Googlebot).

6. Hạn chế các phương thức HTTP không cần thiết

Nếu ứng dụng của bạn chỉ sử dụng GET, POST, HEAD, bạn có thể chặn các phương thức khác.

Nginx

server {
   
# ...
   
if ($request_method !~ ^(GET|POST|HEAD)$ ) {
       
return 405; # Method Not Allowed
   }
   
# ...
}

7. Sử dụng Fail2Ban

Fail2Ban là một công cụ bên ngoài có thể theo dõi log của Nginx (ví dụ: các lỗi 403, 404, 444 do rate limit) và tự động cập nhật tường lửa (iptables, firewalld) để chặn các địa chỉ IP có hành vi đáng ngờ trong một khoảng thời gian. Cần cài đặt và cấu hình Fail2Ban riêng.

8. Bật và Tận dụng Cache

Caching hiệu quả giúp giảm tải cho backend, giúp ứng dụng chịu đựng tốt hơn khi có lượng truy cập tăng đột biến (dù là hợp lệ hay tấn công). Cấu hình cache của bạn (proxy_cache_path, proxy_cache) đã có là một điểm tốt.

9. Cân nhắc Web Application Firewall (WAF)

Sử dụng các module WAF như ModSecurity (cần biên dịch Nginx với module này hoặc sử dụng phiên bản hỗ trợ) hoặc các giải pháp WAF chuyên dụng để phát hiện và chặn các kiểu tấn công phức tạp hơn dựa trên nội dung request (SQL injection, XSS,...).

10. Tinh chỉnh Hệ điều hành (OS Tuning)

Đối với các cuộc tấn công lớn, việc tinh chỉnh các tham số kernel của hệ điều hành (qua sysctl) có thể giúp ích:

  • net.core.somaxconn: Tăng kích thước hàng đợi kết nối chờ xử lý.
  • net.ipv4.tcp_max_syn_backlog: Tăng kích thước hàng đợi SYN.
  • net.ipv4.tcp_syncookies=1: Bật SYN cookies để chống tấn công SYN flood.
  • Điều chỉnh giới hạn file descriptors (ulimit -n).

Kết hợp các cấu hình:

Bạn nên kết hợp nhiều biện pháp trên. Ví dụ, áp dụng cả limit_req và limit_conn trong server block, điều chỉnh timeouts, và sử dụng map để chặn bad bots.

Quan trọng:

  • Kiểm tra kỹ lưỡng: Sau khi áp dụng cấu hình, hãy kiểm tra kỹ lưỡng xem có chặn nhầm người dùng hợp lệ hay không.
  • Theo dõi: Theo dõi chặt chẽ log Nginx và hiệu năng hệ thống để phát hiện sớm các dấu hiệu tấn công và điều chỉnh cấu hình khi cần.
  • Điều chỉnh: Các giá trị rate, burst, limit_conn, timeout cần được điều chỉnh dựa trên lưu lượng truy cập thực tế và tài nguyên máy chủ của bạn. Không có giá trị nào là hoàn hảo cho mọi trang web.
  • Giải pháp bên ngoài: Nhắc lại lần nữa, đối với các cuộc tấn công DDoS quy mô lớn, hãy xem xét mạnh mẽ việc sử dụng các dịch vụ chống DDoS chuyên nghiệp từ CDN hoặc nhà cung cấp đám mây.

Chúc bạn cấu hình thành công và bảo vệ tốt máy chủ của mình!