3 cách xử lý SSL/TLS traffic tại Loadbalancer hoặc Reverse Proxy
Trong quá trình triển khai hệ thống, đặc biệt là khi làm việc với Load Balancer hay Reverse Proxy như Nginx, việc xử lý traffic TLS/SSL (HTTPS) luôn là một bài toán khiến nhiều anh em đau đầu. Chúng ta nên giải mã (decrypt) ngay tại Proxy để giảm tải cho backend, hay cứ để traffic đi thẳng đến backend cho an toàn tuyệt đối?
Hôm nay, mình sẽ cùng các bạn "mổ xẻ" 3 phương pháp phổ biến nhất: TLS Termination, TLS Passthrough và TLS Re-encrypt. Chúng ta sẽ xem cách chúng hoạt động, cấu hình Nginx thực tế và khi nào thì nên dùng phương pháp nào nhé.
1. TLS Termination (SSL Offloading)
Đây là phương pháp phổ biến nhất mà mình thấy hay được sử dụng trong thực tế. Tại đây, Load Balancer/Proxy sẽ đóng vai trò là điểm kết thúc của kết nối SSL. Nó nhận traffic HTTPS từ client, giải mã, sau đó gửi traffic dưới dạng HTTP (không mã hóa) tới backend qua mạng nội bộ.
Sơ đồ hoạt động
Client (HTTPS) ----> [ Proxy (SSL Cert) ] ----> Backend (HTTP)
(Mã hóa) (Giải mã) (Không mã hóa)
Ví dụ cấu hình TLS Termination (SSL Offloading) cho Nginx:
http {
upstream my_app {
server 10.0.0.10:80; # Backend chạy HTTP
}
server {
listen 443 ssl;
server_name example.com;
# 1. Cấu hình Certificate
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
location / {
# 2. Forward tới backend bằng HTTP
proxy_pass http://my_app;
# 3. Truyền thông tin protocol gốc cho backend
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Giải thích cấu hình:
- listen 443 ssl: Nginx lắng nghe cổng 443 và sẵn sàng thực hiện bắt tay (handshake) SSL với client.
- ssl_certificate: Đường dẫn đến chứng chỉ SSL. Mọi quá trình mã hóa/giải mã diễn ra tại đây.
- proxy_pass http://my_app: Lưu ý là http. Traffic sau khi giải mã sẽ được đẩy đi dưới dạng plain text.
- X-Forwarded-Proto $scheme: Cực kỳ quan trọng để backend biết client gốc dùng https, tránh việc backend tự ý redirect vòng lặp về lại http.
Đánh giá
Ưu điểm:
- Giảm tải CPU cho backend (không tốn tài nguyên giải mã)
- Quản lý chứng chỉ tập trung tại 1 nơi
- Proxy có thể đọc/ghi đè Header (Cookie, Caching, WAF).
Nhược điểm:
- Traffic trong mạng nội bộ không được mã hóa. Nếu kẻ tấn công xâm nhập được LAN, họ có thể "sniff" dữ liệu.
Use Case thực tế:
- Hầu hết các ứng dụng Web thông thường nằm trong mạng nội bộ an toàn (VPC).
- Những ứng dụng ưu tiên hiệu năng cũng thường sử dụng phương pháp này.
2. TLS Passthrough
Phương pháp này coi Proxy như một "đường ống" thuần túy. Nginx sẽ không can thiệp, không giải mã dữ liệu mà chỉ chuyển tiếp nguyên văn các gói tin đã mã hóa từ client xuống thẳng backend. Theo mô hình OSI, bạn hiểu đơn giản package khi được gửi đến thì chỉ bóc tách đến layer 4 (TCP) rồi được xử lý tiếp chứ không cần bóc đến Layer 7 (HTTP).
Sơ đồ hoạt động
Client (HTTPS) ----> [ Proxy (L4) ] ----> Backend (SSL Cert)
(Mã hóa) (Chuyển tiếp) (Giải mã tại đây)
Để dùng Passthrough, chúng ta phải dùng module stream (Layer 4) thay vì module http (Layer 7). Sau đây là cấu hình nginx mẫu:
stream {
upstream backend_ssl {
server 10.0.0.10:443; # Backend tự cầm Cert và chạy HTTPS
}
server {
listen 443;
proxy_pass backend_ssl;
# Không cấu hình ssl_certificate ở đây vì Nginx không giải mã
}
}
Giải thích cấu hình:
- stream { ... }: Chạy ở tầng TCP (Layer 4). Nginx chỉ nhìn thấy IP và Port, không nhìn thấy URL hay Header.
- proxy_pass backend_ssl: Các gói tin TCP được forward nguyên trạng.
Lưu ý: Bạn không thể dùng các tính năng như proxy_set_header hay server_name (dựa trên tên miền) trong block này vì Nginx không đọc được nội dung gói tin.
Đánh giá
Ưu điểm:
- Bảo mật tối đa (End-to-End Encryption),
- Proxy không biết gì về dữ liệu khách hàng.
Nhược điểm:
- Backend sẽ phải tốn tài nguyên CPU để xử lý giải mã thay vì ở proxy.
- Proxy không thể thực hiện các tính năng Layer 7 (như Routing theo URL, chèn Header)
- Không thể lấy, xử lý được log liên quan đến Layer 7 (HTTP)
Use Case:
- Các ứng dụng yêu cầu chứng chỉ client (mTLS) hoặc các dịch vụ tài chính, ngân hàng cực kỳ nhạy cảm.
- Các database có certificate riêng. Mình rất hay áp dụng cách này cho các Database nằm trên Cloud mà sử dụng domain để kết nối.
3. TLS Re-encryption
Đây là "best of both worlds". Proxy nhận traffic HTTPS (mã hóa lần 1), giải mã để xử lý (WAF, Header, Routing), sau đó lại mã hóa lần 2 bằng một chứng chỉ khác trước khi gửi tới backend.
Sơ đồ hoạt động
Client (HTTPS) ----> [ Proxy (Decrypt & Encrypt) ] ----> Backend (HTTPS)
(Mã hóa lần 1) (Giải mã và Mã hóa lần 2) (Giải mã lần cuối)
Cấu hình Nginx
http {
upstream secure_backend {
server 10.0.0.10:443; # Backend cũng chạy HTTPS
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/certs/public.pem;
ssl_certificate_key /etc/nginx/certs/public.key;
location / {
# 1. Forward tới backend bằng HTTPS
proxy_pass https://secure_backend;
# 2. Cấu hình kiểm tra chứng chỉ của backend
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/nginx/certs/backend_ca.crt;
proxy_ssl_server_name on; # Hỗ trợ SNI cho backend
}
}
}
Giải thích cấu hình:
- listen 443 ssl: Giải mã kết nối từ Client.
- proxy_pass https://...: Điểm khác biệt là https. Nginx đóng vai trò là một "client" tạo kết nối mã hóa mới tới backend.
- proxy_ssl_verify on: Đảm bảo Nginx kiểm tra tính hợp lệ của chứng chỉ phía backend, tránh tấn công Man-in-the-middle ngay trong mạng nội bộ.
- proxy_ssl_trusted_certificate /etc/nginx/certs/backend_ca.crt: Yêu cầu proxy tin tưởng certificate của backend. Certficate này có thể là public hoặc internal certificates.
- proxy_ssl_server_name on: Gửi SNI (Server Name Indication) để backend biết đang phục vụ cho domain nào.
Đánh giá
Ưu điểm:
- Bảo mật toàn diện trên mọi chặng đường packge đi qua
- Giữ được khả năng can thiệp Layer 7 của Proxy.
Nhược điểm:
- Tốn tài nguyên CPU nhất (mã hóa/giải mã 2 lần)
- Thời gian xử lý request (latency) sẽ cao hơn đáng kể
- Cấu hình và quản lý certificate ở cả 2 đầu rất phức tạp.
Use Case:
- Các hệ thống tuân thủ tiêu chuẩn PCI-DSS, HIPAA hoặc các hệ thống Zero-trust.
- Hệ thống yêu cầu khả năng mã hóa end-to-end mà vẫn có thể extract được dữ liệu ở các layer giữa.
Chốt lại
| Tiêu chí | TLS Termination | TLS Passthrough | TLS Re-encryption |
|---|---|---|---|
| Vị trí giải mã | Tại Proxy | Tại Backend | Cả Proxy và Backend |
| Mức độ bảo mật | Trung bình (Package trong nội bộ không được mã hóa) | Rất cao (End-to-End) | Cao |
| Hiệu năng (CPU) | Tốn tài nguyên xử lý tại proxy | Tốn tài nguyên xử lý tại Backend | Tốn tài nguyên xử lý tại cả Proxy và Backend |
| Khả năng can thiệp Layer 7 | Có | Không | Có |
| Quản lý Cert | Tập trung tại Proxy | Phân tán tại Backend | Phức tạp (quản lý cả 2) |
| Độ khó cấu hình | Bình thường | Dễ | Phức tạp |
Kết luận
Lựa chọn phương pháp nào phụ thuộc hoàn toàn vào yêu cầu bảo mật và kiến trúc hạ tầng của bạn. Nếu bạn ưu tiên sự đơn giản và tốc độ, Termination là số 1. Nếu cần bảo mật tuyệt đối, hãy cân nhắc Passthrough. Còn nếu cần cả sự linh hoạt lẫn bảo mật trong mạng LAN, hãy chọn Re-encryption.
Hy vọng bài viết này giúp anh em có cái nhìn rõ nét hơn về cách xử lý traffic TLS. Nếu có thắc mắc gì, đừng ngần ngại để lại comment bên dưới nhé! Chúc anh em xây dựng hệ thống mượt mà!
Nếu như bạn đang gặp khó khăn trong vấn đề chuyên môn, cần người hỗ trợ về mặt hệ thống, DevOps tools hay cần định hướng trong công việc thì mình tự tin có thể hỗ trợ được bạn. Liên hệ với mình để trao đổi thêm nhé https://hoangviet.io.vn/, mình rất vui khi được trao đổi và cộng tác với bạn.
All rights reserved