Nginx cung cấp nhiều cơ chế mạnh mẽ để kiểm soát truy cập, bảo vệ máy chủ khỏi các cuộc tấn công và quản lý tài nguyên hiệu quả.
1. Giới hạn Kết nối và Yêu cầu
HTTP hoạt động dựa trên TCP. Mỗi yêu cầu HTTP ban đầu yêu cầu một kết nối TCP, bao gồm cả quá trình "bắt tay ba bước" (three-way handshake). Mặc dù HTTP/1.0 yêu cầu kết nối TCP mới cho mỗi yêu cầu, các phiên bản HTTP/1.1 và HTTP/2 đã cải thiện điều này bằng cách cho phép tái sử dụng kết nối (TCP reuse) và đa luồng hóa (multiplexing), giúp tăng hiệu quả truyền tải.
1.1 Các Module Liên quan
Nginx tích hợp các module limit_conn_module (giới hạn tần suất kết nối TCP) và limit_req_module (giới hạn tần suất yêu cầu HTTP) để quản lý lưu lượng truy cập và phòng chống tấn công DDoS.
Cú pháp cấu hình:
limit_conn_zone tên_vùng:kích_thước_vùng;(trong khốihttp): Khai báo một vùng lưu trữ trạng thái kết nối.limit_conn tên_vùng số_lượng_giới_hạn;(tronghttp,server,location): Giới hạn số lượng kết nối đồng thời cho một vùng.limit_req_zone khóa zone=tên_vùng:kích_thước_vùng rate=số_yêu_cầu_mỗi_giây;(trong khốihttp): Khai báo vùng lưu trữ trạng thái yêu cầu và tốc độ cho phép.limit_req zone=tên_vùng [burst=số_yêu_cầu_thêm] [nodelay];(tronghttp,server,location): Áp dụng giới hạn yêu cầu, có tùy chọn bộ đệm (burst) và xử lý không chờ (nodelay).
1.2 Cơ chế Hoạt động
Các lệnh limit_conn_zone và limit_req_zone tạo ra các "vùng" (zone) để theo dõi trạng thái. Thông thường, địa chỉ IP của client ($binary_remote_addr) được sử dụng làm khóa để theo dõi từng client riêng lẻ. Khi vùng lưu trữ bị đầy, Nginx sẽ trả về lỗi 503 Service Temporarily Unavailable cho các yêu cầu tiếp theo.
1.3 Các Chiến lược Phổ biến
Ví dụ cấu hình tốc độ yêu cầu:
http {
limit_req_zone $binary_remote_addr zone=request_limits:1m rate=10r/s;
}
Cấu hình này định nghĩa một vùng request_limits với bộ nhớ 1MB, cho phép tối đa 10 yêu cầu mỗi giây từ mỗi địa chỉ IP.
Kịch bản:
- Chỉ
limit_req zone=request_limits;: Nếu client gửi 13 yêu cầu trong 1 giây, 10 yêu cầu đầu tiên được xử lý, 3 yêu cầu còn lại sẽ bị từ chối (lỗi 503). limit_req zone=request_limits burst=5;: Nếu client gửi 13 yêu cầu, 10 yêu cầu đầu tiên được xử lý, 3 yêu cầu tiếp theo được đưa vào bộ đệmburst(dung lượng 5). Nếu gửi 20 yêu cầu, 10 yêu cầu đầu tiên được xử lý, 5 yêu cầu tiếp theo vào bộ đệm, 5 yêu cầu cuối cùng bị từ chối. Các yêu cầu trong bộ đệm sẽ được xử lý ở giây tiếp theo.limit_req zone=request_limits burst=5 nodelay;: Với 13 yêu cầu, tất cả đều được xử lý vì bộ đệmburstcho phép xử lý thêm. Nếu gửi 20 yêu cầu, 15 yêu cầu (10 + 5 từburst) được xử lý, 5 yêu cầu còn lại bị từ chối (lỗi 503).
1.4 Cấu hình Giới hạn Kết nối và Yêu cầu
Tạo thư mục và file HTML mẫu:
[root@nginx01 ~]# mkdir /usr/share/nginx/limit/
[root@nginx01 ~]# echo '<h1>Limit Test</h1>' > /usr/share/nginx/limit/index.html
Cấu hình trong nginx.conf:
http {
# Vùng giới hạn kết nối, 10MB, theo IP
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
# Vùng giới hạn yêu cầu, 10MB, 1 yêu cầu/giây
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
}
Tạo file cấu hình /etc/nginx/conf.d/limit.conf:
server {
server_name limit.linuxds.com;
location / {
root /usr/share/nginx/limit;
index index.html;
# Giới hạn chỉ 1 kết nối đồng thời từ một client
limit_conn conn_zone 1;
# Áp dụng giới hạn yêu cầu đã định nghĩa
limit_req zone=req_zone;
}
}
Kiểm tra và tải lại cấu hình Nginx:
[root@nginx01 ~]# nginx -t -c /etc/nginx/nginx.conf
[root@nginx01 ~]# nginx -s reload
Lưu ý: Sử dụng $binary_remote_addr thay vì $remote_addr giúp tiết kiệm bộ nhớ khi lưu trữ địa chỉ IP.
Giới hạn yêu cầu (limit_req) thường hiệu quả hơn giới hạn kết nối (limit_conn) vì nhiều yêu cầu có thể được thực hiện trên một kết nối TCP duy nhất.
1.5 Kiểm tra
Sử dụng công cụ ab (ApacheBench) để kiểm tra:
[root@client ~]# yum -y install httpd-tools
[root@client ~]# ab -n 50 -c 10 http://limit.linuxds.com/index.html
2. Giới hạn Truy cập theo Địa chỉ IP
2.1 Module Hỗ trợ
Module http_access_module cho phép kiểm soát truy cập dựa trên địa chỉ IP. Tuy nhiên, phương pháp này có thể bị vượt qua nếu có các proxy ở phía trước.
Cú pháp:
allow địa_chỉ_IP | mạng_CIDR | all;: Cho phép truy cập.deny địa_chỉ_IP | mạng_CIDR | all;: Từ chối truy cập.
Quan trọng: Các quy tắc allow và deny được kiểm tra theo thứ tự từ trên xuống. Quy tắc all nên được đặt ở cuối cùng.
2.2 Cấu hình Kiểm soát IP
Tạo thư mục và file HTML mẫu:
[root@nginx01 ~]# mkdir /usr/share/nginx/ipaccess/
[root@nginx01 ~]# echo '<h1>IP Access Control</h1>' > /usr/share/nginx/ipaccess/index.html
Tạo file cấu hình /etc/nginx/conf.d/ipaccess.conf:
server {
server_name ipaccess.linuxds.com;
location / {
root /usr/share/nginx/ipaccess;
index index.html;
# Từ chối IP cụ thể
deny 115.205.87.7;
# Cho phép tất cả các IP khác
allow all;
}
}
Kiểm tra và tải lại cấu hình Nginx.
2.3 Kiểm tra
Truy cập http://ipaccess.linuxds.com từ trình duyệt. IP bị từ chối sẽ nhận được lỗi 403 Forbidden.
Hạn chế: Kiểm soát IP dựa trên $remote_addr chỉ là IP giao tiếp trực tiếp với Nginx. Nếu có proxy, Nginx không biết IP thật của client. Để khắc phục, có thể sử dụng header X-Forwarded-For, module geo hoặc biến tùy chỉnh.
3. Giới hạn Truy cập theo Tài khoản
3.1 Module Hỗ trợ
Module http_auth_basic_module cho phép xác thực người dùng dựa trên tên người dùng và mật khẩu được lưu trong một tệp.
Cú pháp:
auth_basic thông_báo | off;: Hiển thị thông báo yêu cầu đăng nhập.auth_basic_user_file đường_dẫn_tệp_tài_khoản;: Chỉ định tệp chứa thông tin tài khoản và mật khẩu.
Để tạo tệp mật khẩu, bạn cần cài đặt httpd-tools và sử dụng lệnh htpasswd.
3.2 Cấu hình Xác thực Tài khoản
Tạo thư mục và file HTML mẫu:
[root@nginx01 ~]# mkdir /usr/share/nginx/account/
[root@nginx01 ~]# mkdir /etc/nginx/passwd/
[root@nginx01 ~]# echo '<h1>Account Access</h1>' > /usr/share/nginx/account/index.html
Tạo file cấu hình /etc/nginx/conf.d/account.conf:
server {
server_name account.linuxds.com;
location / {
root /usr/share/nginx/account;
index index.html;
auth_basic "Authentication required!";
auth_basic_user_file /etc/nginx/passwd/auth_conf;
}
}
Tạo tệp mật khẩu và kiểm tra cấu hình Nginx:
[root@nginx01 ~]# yum -y install httpd-tools
# Tạo người dùng 'testuser' với mật khẩu
[root@nginx01 ~]# htpasswd -c /etc/nginx/passwd/auth_conf testuser
# Nhập mật khẩu khi được hỏi
[root@nginx01 ~]# nginx -t -c /etc/nginx/nginx.conf
[root@nginx01 ~]# nginx -s reload
3.3 Kiểm tra
Truy cập http://account.linuxds.com từ trình duyệt. Bạn sẽ được yêu cầu nhập tên người dùng và mật khẩu.
Hạn chế: Quản lý tệp tài khoản thủ công kém hiệu quả. Các giải pháp tối ưu bao gồm tích hợp Nginx với Lua hoặc sử dụng module nginx-auth-ldap để kết nối với LDAP.
4. Giới hạn Băng thông (Tốc độ Truyền Dữ liệu)
4.1 Module Hỗ trợ
Module http_core_module cung cấp các lệnh để giới hạn tốc độ truyền dữ liệu phản hồi đến client.
Cú pháp:
limit_rate tốc_độ;: Đặt tốc độ truyền tối đa (bytes/giây). Giá trị0(mặc định) là không giới hạn.limit_rate_after kích_thước;: Đặt dung lượng dữ liệu được truyền không giới hạn trước khi áp dụnglimit_rate. Giá trị0(mặc định) là không giới hạn.
Lưu ý: Nginx giới hạn tốc độ trên mỗi kết nối. Nếu một client mở nhiều kết nối, tốc độ tổng thể có thể cao hơn giá trị cài đặt.
4.2 Cấu hình Giới hạn Tốc độ
Ví dụ cấu hình giới hạn tốc độ tải xuống cho một trang tải file:
server {
# ... các cấu hình khác
location /download/ {
root /path/to/your/downloads;
# Sau khi truyền 3MB, áp dụng giới hạn tốc độ
limit_rate_after 3m;
# Giới hạn tốc độ truyền là 20KB/giây
limit_rate 20k;
}
# ...
}
Kiểm tra và tải lại cấu hình Nginx.
4.3 Kiểm tra
Truy cập vào đường dẫn tải xuống đã cấu hình và kiểm tra tốc độ tải xuống của tệp.