代理時如何讓 nginx 不覆蓋 x-forwarded-for?
我在負載均衡器後面有一個 nginx 伺服器,nginx 伺服器將請求傳遞給各種服務,但在本例中是一個執行 apache 的 docker 容器。負載均衡器正確設置了 X-Forwarded-For,但是當它到達 docker 容器時,X-Forwarded-For 已設置為 LB IP。
我在 nginx 配置中有這個:
/etc/nginx/conf.d/real_ip.conf set_real_ip_from {{LB IP}}; real_ip_header X-Real-IP; real_ip_recursive on;
這是虛擬主機:
server { listen 443 ssl; listen [::]:443 ssl; server_name *.domain domain; include /etc/nginx/snippets/domain_ssl.conf; add_header X-Nginx-Debug "hi"; proxy_pass_request_headers on; location / { proxy_pass_request_headers on; proxy_pass http://container-php; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Remote-Addr $remote_addr; proxy_set_header X-Real-IP $http_x_real_ip; proxy_set_header X-Header-Test "Hello World - $http_x_forwarded_for"; proxy_set_header X-Forwarded-Proto $scheme; } }
但我從容器中得到的是:
array(19) { ["Connection"]=> string(7) "upgrade" ["Host"]=> string(19) "domain" ["X-Forwarded-For"]=> string(12) "{{LB IP}}" ["X-Header-Test"]=> string(13) "Hello World -" ["X-Forwarded-Proto"]=> string(5) "https" ["cache-control"]=> string(9) "max-age=0" ["sec-ch-ua"]=> string(64) "" Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"" ["sec-ch-ua-mobile"]=> string(2) "?0" ["sec-ch-ua-platform"]=> string(9) ""Windows"" ["upgrade-insecure-requests"]=> string(1) "1" ["user-agent"]=> string(114) "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" ["accept"]=> string(135) "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" ["sec-fetch-site"]=> string(4) "none" ["sec-fetch-mode"]=> string(8) "navigate" ["sec-fetch-user"]=> string(2) "?1" ["sec-fetch-dest"]=> string(8) "document" ["accept-encoding"]=> string(17) "gzip, deflate, br" ["accept-language"]=> string(26) "en-GB,en-US;q=0.9,en;q=0.8" }
值得注意的是 X-Real-IP、X-Fowarded-For 似乎沒有設置,remote_addr 也沒有。直接從 nginx 提供的文件已正確設置 x-forwarded-for,因此 LB 正在發送正確的標頭。
我錯過了一步嗎?
我認為問題出在您的真實IP配置中。
set_real_ip_from {{LB IP}};
real_ip_header X-Real-IP;
real_ip_recursive on;
當 real_ip_header 應該(在你的情況下)設置為 X-Forwarded-For。我假設您的 LB 中的 X-Forwarded-For 標頭如下所示:
X-Forwarded-For: {{Original client ip}}, {{LB ip}}
因此,當您將 real_ip_header(用於替換客戶端 ip 的標頭)設置為 X-Forwarded-For 時,它將匹配原始客戶端 ip。原始客戶端現在應該位於變數 $realip_remote_addr 下,您可以將其定址到 proxy_set_header X-Forwarded-For :
proxy_set_header X-Forwarded-For $realip_remote_addr
如果我有任何幫助,請告訴我!
這是覆蓋 X-Forwarded-For 標頭的語句:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
假設您想在該標頭中保留原始客戶端 IP,您應該編寫:
proxy_set_header X-Forwarded-For $remote_addr;