這是本文件的舊版!
網站取得用戶真實 IP 的方法
- 目前網站的網路架構愈來愈複雜, 要取得用戶真實的 IP 需要透過特別指定與層層的傳遞才有機會取得, 以下透過一個實驗環境的架構案例進行說明
graph TD
%% 1. 定義主要節點 - 移除括號
A[Client - 1.2.3.4]
B{Cloudflare CDN}
C[Host A - Cloudflared]
D[Host B - 192.168.1.100:80 - NPM]
E[Backend Service - dokuwiki_dokuwiki:80]
R([Response])
F[Docker Swarm Overlay Network - rproxy-net]
%% 2. 結構化 - 邏輯分區
subgraph Edge & Host A
A -- HTTPS --> B
B -- Encrypted Tunnel --> C
end
subgraph Host B Docker Swarm & NPM
%% Host A 到 Host B 的連線
C -- HTTP - LAN 192.168.1.x --> D
%% NPM 經由 Overlay Network 到後端
D -- HTTP --> E
end
subgraph Backend Service
E -- dokuwiki-net 接入 --> F
end
%% 3. 主要流程連線
A --> B
B --> C
C --> D
D --> E
E --> R
%% 4. 補充細節/網絡連線
D -- 連線使用 rproxy-net --> F
F -- 服務名稱解析 --> E
如果沒有特別設定, 因為 Docker Swarm 預設 Port Mode:Ingress 所以在 Backend Service 看到的用戶 IP 就會是 docker networks 的 ingress overlay 的 IP 網段 Exp. 10.0.0.0/24
NPM 必須要將 Port Mode 改成 Host
- NPM 的 Stack 部署設定, 要特別處理, 只能在特定 Host 上面, 以下是範例
services: nginx-proxy-manager: image: jc21/nginx-proxy-manager:latest ports: - target: 80 published: 80 mode: host # 重要:使用 host mode - target: 443 published: 443 mode: host - target: 81 published: 81 mode: host volumes: - npm-data:/data - npm-letsencrypt:/etc/letsencrypt networks: - rproxy-net deploy: replicas: 1 # NPM 本身不適合多副本 placement: constraints: - node.labels.rproxy == true # 只部署在有 rproxy label 的節點