Làm thế nào để Backend thấy được IP thật của Client khi dùng Firewall, Router + Nginx Proxy?

🧭 Tổng quan

Trong các hệ thống hạ tầng web có sử dụng firewall Fortigate kết hợp với proxy Nginx, một vấn đề rất phổ biến là:

Backend không nhìn thấy IP thật của client ngoài Internet, mà chỉ thấy IP nội bộ (ví dụ như IP LAN của firewall hoặc IP proxy).

Đây không chỉ là vấn đề nhỏ – nó ảnh hưởng đến:

  • Việc ghi log chính xác
  • Giới hạn truy cập theo IP
  • Bảo mật (chặn IP, phát hiện tấn công,…)
  • Phân tích hành vi người dùng

Trong bài viết này, mình sẽ phân tích:

  • Nguyên nhân vì sao mất IP thật
  • Cách khắc phục để backend có thể thấy IP 1.2.3.4 của client
  • Ưu và nhược điểm từng cách
  • Ví dụ cụ thể
  • Sơ đồ hoạt động
  • Và lời khuyên cho các hệ thống thực tế

🧱 Mô hình hệ thống ví dụ

Client (1.2.3.4)
     |
     v
Internet
     |
     v
WAN IP: 113.161.201.128
Fortigate Firewall (DNAT + SNAT)
LAN IP: 192.168.123.1
     |
     v
Nginx Proxy: 192.168.100.101
     |
     v
Backend App: 192.168.100.111

🎯 Mục tiêu:

Làm sao để backend thấy được IP 1.2.3.4, chứ không phải IP LAN như 192.168.123.1 hay 192.168.100.101.

🧨 Nguyên nhân backend không thấy IP thật

❗ Khi Fortigate bật Enable NAT (SNAT):

Fortigate sẽ thay đổi Source IP của gói tin để đảm bảo có thể trả về đúng. Tuy nhiên điều này khiến IP thật bị mất hoàn toàn.

Trạng tháiSource IPDestination IP
Trước Fortigate1.2.3.4113.161.201.128:80
Sau Fortigate (NAT)192.168.123.1192.168.100.101:80

Nginx proxy sẽ thấy IP là 192.168.123.1. Backend khi đọc X-Forwarded-For hoặc REMOTE_ADDR cũng sẽ thấy IP này – không đúng IP thật.

✅ Giải pháp: Tắt NAT (Disable SNAT) và đảm bảo định tuyến đúng

Khi Fortigate chỉ thực hiện DNAT mà không SNAT:

IP thật 1.2.3.4 được giữ nguyên và truyền thẳng đến Nginx.

Trạng tháiSource IPDestination IP
Trước Fortigate1.2.3.4113.161.201.128
Sau DNAT1.2.3.4192.168.100.101

Nginx sẽ thấy IP là 1.2.3.4 và backend khi đọc X-Forwarded-For sẽ thấy chính xác IP client thật.

🖼️ Sơ đồ hoạt động khi tắt NAT

Client (1.2.3.4)
     |
     v
Internet
     |
     v
Fortigate (DNAT)
 - WAN: 113.161.201.128
 - LAN: 192.168.123.1
     |
     v
Nginx Proxy (192.168.100.101)
     |
     v
Backend (192.168.100.111)

Nginx -> thêm header: X-Forwarded-For: 1.2.3.4
Backend -> đọc IP thật từ header

🛠️ Cấu hình chi tiết

Trên Fortigate:

  • Tạo Virtual IP (VIP) DNAT:
    • External IP: 113.161.201.128
    • Mapped IP: 192.168.100.101
    • Port: 80
  • Tạo Policy WAN → LAN:
    • Source: all
    • Destination: VIP
    • Action: Accept
    • Tắt NAT (Disable Enable NAT)
  • Tạo Policy LAN → WAN (để trả phản hồi):
    • Source: 192.168.100.0/24
    • Destination: all
    • Action: Accept
    • NAT: tuỳ chọn

Trên Proxy Nginx (192.168.100.101):

location / {
    proxy_pass http://192.168.100.111;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Trên Backend (PHP):

function getClientIP() {
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        return trim($ipList[0]);
    }
    return $_SERVER['REMOTE_ADDR'];
}

⚠️ Điều kiện bắt buộc để hệ thống hoạt động đúng khi tắt NAT

Yêu cầuGiải thích
Default gateway của Nginx proxy phải là FortigateĐể gói phản hồi đi ngược qua firewall
Fortigate có route quay về mạng 192.168.100.0/24Đảm bảo đường trả phản hồi đúng
Không có thiết bị nào khác làm NAT giữa proxy và backendTránh mất IP gốc giữa đường

🔍 So sánh các cách

Phương phápCó thấy IP thật?Dễ triển khaiƯu điểmNhược điểm
Giữ NAT (Enable NAT)❌ Không✅ Dễ cấu hìnhĐơn giản, ít lỗi định tuyếnMất IP thật
Tắt NAT + định tuyến đúng✅ Có⚠️ Phức tạp hơnThấy IP thật, chuẩnCần hiểu rõ routing
Dùng Proxy Protocol✅ Có❌ Phức tạpChuẩn kỹ thuật, chính xácYêu cầu phần mềm backend hỗ trợ
FortiWeb / WAF thêm IP header✅ Có⚠️ Tuỳ thiết bịThấy IP thậtPhụ thuộc thiết bị, bản quyền

💡 Lời khuyên

  • Nếu bạn kiểm soát được hệ thống mạng (default gateway, routing), hãy tắt NAT và cấu hình đúng tuyến.
  • Nếu không thể tắt NAT, hãy dùng X-Forwarded-For, nhưng chấp nhận IP sẽ là IP của firewall, không phải IP client thật.
  • Đừng quên kiểm tra định tuyếngateway ở proxy/nginx để đảm bảo gói tin đi và về đều qua Fortigate.
  • Trong môi trường lớn, nên cân nhắc sử dụng Proxy Protocol hoặc các WAF chuyên dụng (như FortiWeb, Cloudflare…).

📌 Kết luận

Việc giữ lại IP thật của client là rất quan trọng cho hệ thống backend. Nếu bạn đang dùng Fortigate và Nginx, cách hiệu quả và đơn giản nhất là:

  • Tắt NAT (Enable NAT) trên Fortigate
  • Đảm bảo định tuyến đúng
  • Đọc IP từ header X-Forwarded-For

Đây là cách phổ biến và an toàn được nhiều hệ thống sử dụng.

Hy vọng bài viết này giúp bạn hiểu rõ cách hoạt động của NAT, proxy và cách giữ lại IP thật của người dùng. Nếu có câu hỏi, đừng ngại để lại bình luận!

Bài viết gần đây

spot_img

Related Stories

Leave A Reply

Please enter your comment!
Please enter your name here

Đăng ký nhận thông tin bài viết qua email