Hướng dẫn Nginx Reverse Proxy: cấu hình và tối ưu hiệu năng

Trong hạ tầng web hiện đại, Nginx Reverse Proxy đóng vai trò trung gian đón request từ client rồi chuyển tiếp tới backend, giúp ẩn cấu trúc nội bộ, phân tải, cache và tăng cường bảo mật. Bài viết này tổng hợp cách cấu hình, các chỉ thị quan trọng và mẹo tối ưu Nginx như một reverse proxy phục vụ môi trường production.

Trung tâm dữ liệu server rack, môi trường triển khai Nginx
Trung tâm dữ liệu server rack, môi trường triển khai Nginx

Nginx Reverse Proxy là gì và khi nào nên dùng

Reverse proxy là máy chủ đứng trước một hoặc nhiều backend (Apache, Node.js, Python, Go…), nhận mọi request từ Internet rồi chuyển tiếp tới backend phù hợp. Khác với forward proxy đại diện cho client, reverse proxy đại diện cho server, giúp:

  • Ẩn IP và cổng thật của backend, giảm bề mặt tấn công.
  • Cân bằng tải giữa nhiều backend (load balancing).
  • Kết thúc TLS (SSL termination) để backend xử lý HTTP thuần, tiết kiệm CPU.
  • Cache nội dung tĩnh, giảm tải cho backend.
  • Nén response, buffer, nén gzip hoặc brotli.

So sánh với forward proxy

Trong khi forward proxy được cấu hình phía client để truy cập Internet gián tiếp (VPN, bypass geo-block), reverse proxy đứng phía server để kiểm soát traffic đến từ bên ngoài. Điểm mấu chốt là reverse proxy ẩn hoàn toàn cấu trúc backend bên trong, nên attacker không thể trực tiếp quét hay exploit port của từng service.

Theo tài liệu chính thức từ NGINX Admin Guide, đây là use case phổ biến nhất khi vận hành Nginx ở production. Nếu hệ thống có từ 2 backend trở lên hoặc cần tách biệt SSL, việc đặt Nginx làm lớp reverse proxy gần như là mặc định.

Sơ đồ Reverse Proxy: client gửi request qua proxy tới backend
Sơ đồ Reverse Proxy: client gửi request qua proxy tới backend

Cài đặt Nginx chuẩn bị cho Reverse Proxy

Trên Ubuntu hoặc Debian, cài đặt từ repo chính thức của Nginx để có phiên bản mới nhất (không dùng bản cũ trong repo mặc định của distro):

sudo apt install curl gnupg2 ca-certificates lsb-release
echo "deb http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" 
  | sudo tee /etc/apt/sources.list.d/nginx.list
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor 
  -o /usr/share/keyrings/nginx-archive-keyring.gpg
sudo apt update && sudo apt install nginx

Sau khi cài, file cấu hình chính nằm ở /etc/nginx/nginx.conf. Thông thường các vhost được tách vào /etc/nginx/conf.d/ hoặc /etc/nginx/sites-enabled/. Trước khi sửa, luôn kiểm tra cú pháp bằng sudo nginx -t để tránh cấu hình lỗi làm sập dịch vụ.

Cấu hình Reverse Proxy cơ bản với proxy_pass

Một block server đơn giản chuyển tiếp mọi request từ cổng 80 sang backend Node.js ở 127.0.0.1:3000:

server {
    listen 80;
    server_name example.com www.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Các chỉ thị proxy_set_header rất quan trọng: backend cần biết IP thật của client, scheme và host gốc để sinh URL chính xác (ví dụ redirect, log). Thiếu những header này, các ứng dụng như Express, Django, Laravel sẽ gặp lỗi khi sinh absolute URL hoặc phát hiện HTTPS.

Một mẹo nhỏ: nên đặt proxy_http_version 1.1; để dùng được keep-alive giữa Nginx và backend, giảm overhead TCP handshake. Tham khảo thêm module ngx_http_proxy_module cho danh sách chỉ thị đầy đủ.

Cân bằng tải với upstream block

Khi có nhiều backend, khai báo upstream rồi trỏ proxy_pass vào tên upstream. Nginx hỗ trợ 3 thuật toán mặc định: round-robin, least_conn và ip_hash. Cấu hình ví dụ:

upstream backend_pool {
    least_conn;
    server 10.0.0.11:3000 weight=3;
    server 10.0.0.12:3000 weight=2;
    server 10.0.0.13:3000 backup;
    keepalive 32;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend_pool;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

weight điều chỉnh tỉ lệ phân phối request, backup đánh dấu node dự phòng chỉ nhận traffic khi toàn bộ node chính sập. Nếu cần sticky session (client luôn rơi vào cùng một backend), dùng ip_hash; hoặc hash $cookie_session_id consistent; trong phiên bản Nginx Plus. Tài liệu chi tiết tại NGINX HTTP Load Balancer.

SSL Termination và HTTP/2

Đặt Nginx xử lý TLS giúp backend tập trung vào logic nghiệp vụ. Với Let’s Encrypt, dùng certbot hoặc certbot DNS challenge cho wildcard. Cấu hình mẫu:

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 1d;

    add_header Strict-Transport-Security "max-age=31536000" always;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-Content-Type-Options nosniff;

    location / {
        proxy_pass http://backend_pool;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

http2 trên cùng dòng listen bật HTTP/2, cải thiện đáng kể hiệu năng tải asset. Nhớ bật HSTS để buộc client dùng HTTPS, kết hợp redirect 301 từ HTTP sang HTTPS. Từ Nginx 1.25 trở đi, http2 on; đã tách thành chỉ thị riêng nên cần đọc release notes trước khi áp dụng.

Nginx đang chạy trong terminal, cấu hình reverse proxy
Nginx đang chạy trong terminal, cấu hình reverse proxy

Cache tĩnh, nén response và tối ưu buffer

Một trong những lợi thế lớn nhất của Nginx là khả năng phục vụ file tĩnh cực nhanh và cache proxy. Thêm block sau để cache các response có header thân thiện từ backend:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
                 max_size=10g inactive=60m use_temp_path=off;

server {
    # ... block ở trên ...
    location / {
        proxy_pass http://backend_pool;
        proxy_cache my_cache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_bypass $http_cache_control;
        add_header X-Cache-Status $upstream_cache_status;
    }
}

$upstream_cache_status trả về HIT, MISS, EXPIRED, BYPASS, giúp debug cache dễ dàng. Kết hợp nén gzip hoặc brotli để giảm băng thông:

gzip on;
gzip_types text/plain text/css application/json application/javascript
           application/xml image/svg+xml;
gzip_min_length 1024;
gzip_vary on;

Cuối cùng, tinh chỉnh buffer để tránh Nginx ghi đĩa khi response lớn: proxy_buffer_size 16k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k;. Những tham số này ảnh hưởng trực tiếp đến throughput và được tổng hợp trong bài viết tối ưu hiệu năng Nginx của đội ngũ phát triển.

Giám sát, log và bảo mật nâng cao

Log access và error mặc định đủ dùng cho debug, nhưng ở production nên đẩy về hệ thống tập trung (ELK, Loki). Tách log theo server_name giúp lọc nhanh:

http {
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time uct=$upstream_connect_time '
                    'urt=$upstream_response_time';
    access_log /var/log/nginx/access.log main;
}

Về bảo mật, hãy giới hạn kích thước body, khoá IP nếu bị abuse, dùng limit_req_zone chống brute-force, và đặt Nginx chạy với worker process tối ưu theo số core CPU: worker_processes auto;. Kết hợp tường lửa chỉ mở cổng 80/443 từ Internet, mọi cổng backend đặt trong private subnet, đó là lớp bảo mật quan trọng không kém gì WAF.

Kết luận

Nginx Reverse Proxy là lớp trung gian không thể thiếu trong hạ tầng web hiện đại: cân bằng tải, kết thúc TLS, cache, nén và bảo vệ backend. Bắt đầu với cấu hình proxy_pass đơn giản, sau đó mở rộng dần sang upstream, SSL Termination, caching và giám sát. Với mỗi bước, đừng quên nginx -t trước khi reload và đo lường bằng $request_time để biết tối ưu có thực sự hiệu quả hay không.

Tham khảo thêm: Tài liệu chính thức Nginx, DigitalOcean – Understanding Nginx HTTP Proxying.

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Minh họa Tmux pane layout editor bên trái terminal chạy server bên phải logs dưới cùng

Tmux + sessionizer Quản lý terminal workflow như pro

Tmux: Terminal multiplexer bất kỳ developer nào cũng nên biết Tmux cho phép chia cửa sổ terminal thành nhiều pane, tạo nhiều session, detach/attach bất cứ lúc nào. Khi kết…

Xem thêm

HTMX + Alpine.js: Xây Dựng Web Động Không Cần React Hay Vue

Trong thế giới web hiện đại, không còn nhiều ai chọn React hay Vue cho một trang web đơn giản – vì chúng tốn hàng chục MB bundle, require build…

Xem thêm

SQLite Streaming Replication: Litestream và libSQL Cho Production

SQLite Streaming Replication là gì? SQLite streaming replication là kỹ thuật sao chép dữ liệu SQLite liên tục từ source đến destination trong thời gian thực. Khác với backup định…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất