Việc hạn chế request từ một client vào server sẽ giảm được việc ddos vào trang xử lý, giảm việc crawl dữ liệu từ các machine. Tôi sẽ hướng dẫn các bạn sử dụng module limit_req của nginx để thực hiện việc này


Ví dụ config limit_req
http {
    limit_req_zone  $binary_remote_addr  zone=fap:10m   rate=1r/s;
 
    ...
 
    server {
 
        ...
 
        location /search/ {
            limit_req   zone=fap burst=5;
        }

Step 1: Khai báo zone trong http {}
Cấu hình trong file nginx.conf
 
 limit_req_zone  $binary_remote_addr  zone=fap:10m   rate=1r/s;

*Giải thích:

zone=fap:10m Phân bổ 10m cho việc lưu trữ địa chỉ kết nối tại vùng "fap". Vì ở đây sử dụng $binary_remote_addr thay cho $remote_addr nên kích thước trạng thái giảm còn 64B. 1MB lưu được 16000 trạng thái kết nối. 10MB thì 160000 kết nối. Nếu quá thì sẽ bắn ra lỗi 503: Service Temporarily Unavailable  
rate=1r/s cường độ request trung bình 1 request trên 1 giây. Có thể dùng đơn vị thời gian khác, ví dụ 30r/m
  
Step 2: Khai báo trong location {}
Bạn có thể dùng trong / hay chỉ mục bạn muốn giới hạn
limit_req   zone=fap burst=2;
Ở đây mình dùng zone fap đã được thiết lập ở trên, thêm cái burst=2 tức nếu trong vòng 1s có nhiều hơn 2 request liên tục (burst mode) thì sẽ báo lỗi 503

Step 3: Tạo trang báo lỗi 503:

error_page 503 /forbid.html;
....
location /forbid.html {
    root /usr/share/nginx/html/50x ;
    expires 7d;
}

Việc chặn này hiện tại chặn hết cả bot, mà mình không muốn bot lại bị chặn. Thêm thắt tí cho nó chạy ngon hơn nhể?
trong html {} thêm cái zone freebot:
limit_req_zone $freebots zone=bots:10m rate=1r/s;
Trong location / thì cấu hình dư vầy. Muốn whitelist thêm IP cũng xử lý tương tự.
set $bot ";
if ($http_user_agent !~* (google|bing|yandex|msnbot) ) {
    set $freebots $binary_remote_addr;
}
limit_req zone=bots burst=2 nodelay;

Xong. Ngon chưa?

Leave a Reply