差異處
這裏顯示兩個版本的差異處。
| 兩邊的前次修訂版 前次修改 下次修改 | 前次修改 | ||
| tech:http_realip [2025/10/03 19:56] – [3. Backend Service 內的 Nginx Config 設定] jonathan | tech:http_realip [2025/10/03 22:57] (目前版本) – [以下透過一個實驗環境(Cloudflare Tunnel、NPM 與 Docker Swarm 架構)的架構案例進行說明] jonathan | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| ====== 網站取得用戶真實 IP 的方法 ====== | ====== 網站取得用戶真實 IP 的方法 ====== | ||
| - | * 目前網站的網路架構愈來愈複雜, | + | * 目前網站的網路架構愈來愈複雜, |
| + | |||
| + | ==== 通用原則:掌握 HTTP Real IP 標頭 ==== | ||
| + | * 取得真實 IP 的核心在於: | ||
| + | - 識別上游代理伺服器傳來的 真實 IP 標頭(例如:**X-Forwarded-For、CF-Connecting-IP、X-Real-IP**)。 | ||
| + | - 使用 **set_real_ip_from** 信任該標頭的來源 IP 範圍。 | ||
| + | - 使用 **real_ip_header** 指定要讀取的標頭名稱。 | ||
| + | |||
| + | ==== 以下透過一個實驗環境(Cloudflare Tunnel、NPM 與 Docker Swarm 的架構)案例進行說明 | ||
| < | < | ||
| 行 7: | 行 15: | ||
| A[Client - 1.2.3.4] | A[Client - 1.2.3.4] | ||
| B{Cloudflare CDN} | B{Cloudflare CDN} | ||
| - | C[Host A - Cloudflared] | + | C[Host A - 192.168.1.254 |
| D[Host B - 192.168.1.100: | D[Host B - 192.168.1.100: | ||
| - | E[Backend Service - dokuwiki_dokuwiki: | + | E[Docker Swarm Overlay Network - rproxy-net] |
| - | R([Response]) | + | F[Backend Service - dokuwiki_dokuwiki: |
| - | F[Docker Swarm Overlay Network - rproxy-net] | + | |
| | | ||
| %% 2. 結構化 - 邏輯分區 | %% 2. 結構化 - 邏輯分區 | ||
| 行 21: | 行 28: | ||
| subgraph Host B Docker Swarm & NPM | subgraph Host B Docker Swarm & NPM | ||
| %% Host A 到 Host B 的連線 | %% Host A 到 Host B 的連線 | ||
| - | C -- HTTP - LAN 192.168.1.x --> D | + | C -- HTTP - LAN 192.168.1.x |
| %% NPM 經由 Overlay Network 到後端 | %% NPM 經由 Overlay Network 到後端 | ||
| - | D -- HTTP --> E | + | D -- HTTP - rproxy-net 10.0.8.x |
| end | end | ||
| | | ||
| subgraph Backend Service | subgraph Backend Service | ||
| - | E -- dokuwiki-net 接入 --> F | + | E -- rproxy-net 接入 --> F |
| end | end | ||
| - | |||
| - | |||
| - | %% 3. 主要流程連線 | ||
| - | A --> B | ||
| - | B --> C | ||
| - | C --> D | ||
| - | D --> E | ||
| - | E --> R | ||
| | | ||
| %% 4. 補充細節/ | %% 4. 補充細節/ | ||
| - | D -- 連線使用 rproxy-net --> F | ||
| F -- 服務名稱解析 --> E | F -- 服務名稱解析 --> E | ||
| </ | </ | ||
| - | 如果沒有特別設定, | + | 如果沒有特別設定, |
| ===== 1. NPM 必須要將 Port Mode 改成 Host ====== | ===== 1. NPM 必須要將 Port Mode 改成 Host ====== | ||
| 行 115: | 行 113: | ||
| : | : | ||
| </ | </ | ||
| + | < | ||
| + | 當設定 real_ip_recursive on 時,Nginx 會從 X-Forwarded-For 列表的最右邊開始,依序移除屬於 set_real_ip_from 信任範圍內的 IP,直到遇到第一個非信任 IP。由於我們這裡直接使用 real_ip_header CF-Connecting-IP,因此它會被視為真實 IP 並覆蓋 $remote_addr。」 | ||
| + | </ | ||
| ===== 3. Backend Service 內的 Nginx Config 設定 ===== | ===== 3. Backend Service 內的 Nginx Config 設定 ===== | ||
| * 因為這 Backend Service 是 dokuwiki 使用的 image 為 lscr.io/ | * 因為這 Backend Service 是 dokuwiki 使用的 image 為 lscr.io/ | ||
| 行 135: | 行 135: | ||
| # Real IP 設定 - 信任 Docker Overlay 網路 (NPM IP) | # Real IP 設定 - 信任 Docker Overlay 網路 (NPM IP) | ||
| # | # | ||
| - | set_real_ip_from 10.0.0.0/8; | + | set_real_ip_from 10.0.8.0/24; |
| # 讀取 NPM 傳來的 X-Real-IP 標頭 | # 讀取 NPM 傳來的 X-Real-IP 標頭 | ||
| 行 144: | 行 144: | ||
| # 檢查配置是否已經存在 | # 檢查配置是否已經存在 | ||
| - | if grep -q " | + | if grep -q " |
| echo ">> | echo ">> | ||
| else | else | ||
| 行 165: | 行 165: | ||
| chmod +x " | chmod +x " | ||
| </ | </ | ||
| - | * 需要將這個 script 檔案設唯執行權限 chmod a+x 10-nginx-realip.sh | + | * 需要將這個 script 檔案設定執行權限 |
| * 重新啟動 dokuwiki 這個 stack | * 重新啟動 dokuwiki 這個 stack | ||
| * 查看 dokuwiki 啟動的容器 log 應該就會出現類似以下的訊息 < | * 查看 dokuwiki 啟動的容器 log 應該就會出現類似以下的訊息 < | ||
| 行 190: | 行 190: | ||
| </ | </ | ||
| + | {{tag> | ||