Apache-2.2
使用 Nginx/Varnish/Apache 記錄客戶端 IP
我讓 Nginx 監聽埠 443 作為 SSL 終結器,並將未加密的流量代理到同一伺服器上的 Varnish。Varnish 3 正在處理此流量,並且流量直接進入埠 80。所有流量都未經加密地傳遞到集群中其他伺服器上的 Apache 實例。Apache 實例使用 mod_rpaf 將記錄的客戶端 IP 替換為 X-Forwarded-For 標頭的內容。
我的問題是,如果流量來自 Nginx,而“正確”客戶端 IP 正在記錄在 VarnishNCSA 日誌中,看起來 Varnish (可以理解)用 127.0.0.1 下游替換 Nginx 的 X-Forwarded-For 標頭,這是用 Apache 記錄的。如果已經填充了 X-Forwarded-For,是否有一種很好的簡單方法來阻止 Varnish 重寫 X-Forwarded-For?
絕對地; Varnish 的處理
X-Forwarded-For
實際上只是在預設vcl_recv
函式中定義。if (req.restarts == 0) { if (req.http.x-forwarded-for) { set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } }
函式的預設定義始終附加到您在活動 VCL 文件中定義的定義,但如果您定義的函式始終處理請求,則預設邏輯將永遠不會執行。
vcl_recv
沿著這些構想設置 a :sub vcl_recv { /* Your existing logic goes here */ /* After that, we'll insert the default logic, with the X-Forwarded-For handling removed */ /* The return (lookup); at the end ensures that the default append behavior won't have an impact */ if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.request != "GET" && req.request != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } return (lookup); }
編輯:
由於 Varnish 也直接處理一些連接,因此更好的方法可能是讓它有選擇地設置標頭。您仍然希望包含完整的
vcl_recv
,以便預設不應用其自己的標題,但在頂部包含此:if (req.restarts == 0) { if (!req.http.x-forwarded-for) { set req.http.X-Forwarded-For = client.ip; } }