
Bài 7: Cấu hình NGINX load balancing và duy trì phiên
Thiết lập upstream, kiểm tra lỗi thụ động và giới hạn retry; phân biệt định tuyến theo IP, cookie và lưu session tập trung trong cụm backend.

Ẩn phiên bản, đánh giá security headers và triển khai rate limiting theo endpoint. Giải thích giới hạn của chặn bot, CSP và bảo vệ theo IP.
Trước khi bắt đầu. Cấu hình bảo mật phải theo ngữ cảnh ứng dụng. Đặt giới hạn quá thấp hoặc sao chép CSP chưa kiểm tra có thể chặn người dùng hợp lệ và làm lỗi đăng nhập, thanh toán hoặc tài nguyên bên ngoài.

Trong quy trình rà quét lỗ hổng của kẻ tấn công, bước đầu tiên luôn là Reconnaissance (Thu thập thông tin mục tiêu). Bằng cách đọc response header Server (ví dụ: Server: nginx/1.18.0 (Ubuntu)), kẻ tấn công có thể xác định chính xác số hiệu phiên bản và phân phối hệ điều hành đang sử dụng, từ đó tra cứu các mã khai thác (Exploit/CVE) tương ứng.
Một hệ thống NGINX chuẩn Production cần áp dụng chiến lược phòng thủ nhiều lớp (Defense in Depth): ẩn định danh máy chủ, siết chặt chính sách trình duyệt thông qua các Security Headers, giới hạn tần suất gửi request để ngăn chặn brute-force và loại trừ nguy cơ rò rỉ dữ liệu từ các file cấu hình nhạy cảm.

Cách 1: Sử dụng directive gốc server_tokens off; (Khuyên dùng)
Đây là giải pháp đơn giản, hiệu quả và được tích hợp sẵn trong mọi bản phân phối NGINX mà không cần biên dịch lại mã nguồn hay cài đặt thêm module bên ngoài.
Mở file /etc/nginx/nginx.conf và thêm vào khối http:
http {
# Ẩn hoàn toàn số hiệu phiên bản NGINX trong response header và trang báo lỗi
server_tokens off;
...
}
Sau khi thiết lập, header Server sẽ chỉ trả về chuỗi Server: nginx mà không còn hiển thị số phiên bản cụ thể (ví dụ 1.25.4) hay tên hệ điều hành (Ubuntu/Debian).
Cách 2: Xóa hoàn toàn header Server bằng module headers-more-nginx-module
Nếu chính sách an ninh của doanh nghiệp yêu cầu xóa sạch hoàn toàn chuỗi Server trong mọi phản hồi HTTP, bạn có thể cài đặt module động headers-more:
# Trên Ubuntu / Debian:
sudo apt install -y libnginx-mod-http-headers-more-filter
Khai báo trong khối http hoặc từng khối server:
http {
# Xóa hoàn toàn header Server khỏi phản hồi HTTP
more_clear_headers Server;
}
Các Security Headers hướng dẫn trình duyệt người dùng áp dụng các biện pháp bảo vệ tích hợp sẵn, ngăn chặn các hình thức tấn công phổ biến như Cross-Site Scripting (XSS), Clickjacking và MIME Sniffing.
Tạo file /etc/nginx/snippets/security-headers.conf:
# 1. Chống Clickjacking: Không cho phép nhúng website vào iframe từ domain khác
add_header X-Frame-Options "SAMEORIGIN" always;
# 2. Chống MIME-type Sniffing: Bắt buộc trình duyệt tuân thủ MIME type từ server
add_header X-Content-Type-Options "nosniff" always;
# 3. Quản lý thông tin nguồn giới thiệu (Referrer Policy)
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 4. Giới hạn quyền truy cập thiết bị phần cứng của trình duyệt (Camera, Micro, Vị trí)
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;
# 5. CSP Report-Only: chi quan sat; can dieu chinh theo ung dung truoc enforce
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self' https:; frame-ancestors 'self';" always;
# 6. Ngăn chặn rò rỉ dữ liệu chéo nguồn (Cross-Origin isolation)
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;
Rate Limiting (Giới hạn tần suất request) là cơ chế hữu ích của NGINX để bảo vệ các cổng API đăng nhập hoặc các endpoint nặng khỏi bị spam request gây kiệt quệ tài nguyên CPU/RAM.
NGINX sử dụng thuật toán Leaky Bucket để điều tiết lưu lượng mượt mà:
http của /etc/nginx/nginx.confhttp {
# Vùng nhớ lưu trữ địa chỉ IP (10MB lưu được khoảng 160.000 địa chỉ IP)
# Giới hạn mỗi IP tối đa 10 request/giây cho toàn site
limit_req_zone $binary_remote_addr zone=general_limit:10m rate=10r/s;
# Giới hạn khắt khe hơn cho trang đăng nhập/API: tối đa 2 request/giây
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=2r/s;
# Giới hạn số lượng kết nối đồng thời từ một địa chỉ IP duy nhất
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
# Thiết lập mã lỗi trả về khi bị chặn (HTTP 429 Too Many Requests)
limit_req_status 429;
limit_conn_status 429;
}
server {
listen 443 ssl;
server_name example.com;
# Giới hạn tối đa 20 kết nối đồng thời từ một IP
limit_conn conn_limit 20;
# Áp dụng giới hạn chung cho toàn bộ website với bộ đệm burst=20
location / {
limit_req zone=general_limit burst=20 nodelay;
try_files $uri $uri/ =404;
}
# Bảo vệ nghiêm ngặt endpoint đăng nhập hoặc API nhạy cảm
location /api/login {
limit_req zone=login_limit burst=5 nodelay;
proxy_pass http://backend_upstream;
}
}
Rất nhiều sự cố rò rỉ dữ liệu xảy ra do quản trị viên vô tình đẩy file chứa biến môi trường (.env) hoặc thư mục quản lý phiên bản (.git) lên thư mục web root công khai.
Thêm đoạn chặn triệt để sau vào các Server Block:
# 1. Chặn toàn bộ file và thư mục ẩn bắt đầu bằng dấu chấm (trừ /.well-known dùng cho SSL Certbot)
location ~ /\.(?!well-known) {
deny all;
access_log off;
log_not_found off;
return 404;
}
# 2. Chặn các file sao lưu, cấu hình và dump cơ sở dữ liệu phổ biến
location ~* \.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist|env)$ {
deny all;
access_log off;
log_not_found off;
return 404;
}
Để ngăn chặn các công cụ quét tự động tiêu tốn băng thông và dò quét điểm yếu, bạn có thể tạo một danh sách lọc dựa trên chuỗi User-Agent:
# Khai báo trong khối http
map $http_user_agent $bad_bot {
default 0;
~*(nikto|sqlmap|acunetix|w3af|netsparker|dirbuster|pangolin|nmap) 1;
# Khong chan bot tim kiem theo danh sach mau neu chua co chinh sach.
}
# Khai báo trong khối server
server {
if ($bad_bot) {
return 403 "Access denied by local policy.";
}
}
Sau khi thiết lập hoàn tất, bạn chỉ cần include file security-headers.conf vào mọi Virtual Host trên hệ thống. Kiểm tra cú pháp và reload dịch vụ:
sudo nginx -t && sudo systemctl reload nginx
Kiểm tra phản hồi thực tế bằng curl:
curl -I https://example.com
Bạn sẽ thấy phản hồi trả về đầy đủ các header an toàn, không còn số hiệu phiên bản máy chủ và hệ thống đã được gia cố vững chắc trước các cuộc tấn công thăm dò.
Ở bài học tiếp theo, chúng ta sẽ tối ưu hóa tốc độ truyền tải tài nguyên lên mức tối đa bằng việc kích hoạt giao thức HTTP/2 và thế hệ mới HTTP/3 (QUIC).
server_tokens off ẩn số phiên bản, không vá lỗ hổng và không xóa tên sản phẩm khỏi mọi phản hồi. Module headers-more phải khớp ABI và nguồn gói NGINX; không trộn module của gói hệ điều hành với binary từ kho khác khi chưa xác minh. Với CSP Report-Only, kiểm tra console và báo cáo rồi mới cân nhắc enforce. Chặn theo User-Agent chỉ là một tín hiệu dễ giả mạo. Khi ở sau CDN/proxy, xác minh nguồn IP đáng tin cậy trước khi rate limit; dùng dry-run và theo dõi 429 để tránh chặn cả văn phòng dùng chung NAT. Rate limit tại web server không thay thế chống DDoS ở lớp mạng.
Các địa chỉ example.com, IP riêng và đường dẫn trong ví dụ cần thay theo môi trường thực tế. Các sơ đồ trong bài là minh họa khái niệm, không phải bằng chứng thử nghiệm trên hệ thống của bạn.
Trước khi áp dụng: sao lưu file cấu hình bị đổi, chạy sudo nginx -t, chỉ reload khi kiểm tra thành công, rồi xác nhận endpoint, error log và chức năng ứng dụng. Nếu lỗi xuất hiện, phục hồi file đã sao lưu, kiểm tra cú pháp và reload lại; không xóa hàng loạt cấu hình để thử.

Thiết lập upstream, kiểm tra lỗi thụ động và giới hạn retry; phân biệt định tuyến theo IP, cookie và lưu session tập trung trong cụm backend.

Dựng máy chủ mới, kiểm tra cấu hình và SELinux, thử lưu lượng trước cutover; chuẩn bị rollback khi chuyển NGINX từ CentOS Linux đã hết hỗ trợ.

Định tuyến dịch vụ gRPC qua NGINX, phân biệt kết nối TLS đến upstream, cấu hình timeout cho streaming và kiểm tra bằng grpcurl.

Chọn kho gói phù hợp, cài NGINX, mở cổng web và kiểm tra dịch vụ trên Ubuntu 24.04 hoặc Rocky Linux 9. Có lưu ý riêng cho Debian và SELinux.