Varnish

清漆取消設置除最後一個 x-forwarded-for IP 地址之外的所有…錯誤?

  • March 9, 2017

在試圖弄清楚為什麼我們的 Varnish 4.1 安裝(通過 varnish-cache.org 儲存庫在 CentOS7 上)沒有遵循 vcl 規則,這些規則設置為在 X-Forwarded-For 標頭中記錄客戶端 IP 地址(請參閱:Varnish 4 logging proxy /load balancer 而不是客戶端 IP 地址)我在查看 varnishlog 文件時碰巧注意到了一些奇怪的事情:

- Begin        req 9353447 rxreq
- Timestamp    Start: 1488771709.337974 0.000000 0.000000
- Timestamp    Req: 1488771709.337974 0.000000 0.000000
- ReqStart     172.25.20.65 19903
- ReqMethod    GET
- ReqURL       /about-us/
- ReqProtocol  HTTP/1.1
- ReqHeader    host: www.<notreallythishost>.com
- ReqHeader    Accept: */*
- ReqHeader    Accept-Encoding: gzip, deflate
- ReqHeader    Cache-Control: no-cache
- ReqHeader    From: bingbot(at)microsoft.com
- ReqHeader    Pragma: no-cache
- ReqHeader    User-Agent: Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
- ReqHeader    X-Forwarded-For: 40.77.167.41
- ReqHeader    X-Forwarded-Port: 80
- ReqHeader    X-Forwarded-Proto: http
- ReqHeader    Connection: keep-alive
- ReqUnset     X-Forwarded-For: 40.77.167.41
- ReqHeader    X-Forwarded-For: 40.77.167.41, 172.25.20.65
- VCL_call     RECV
- ReqUnset     X-Forwarded-For: 40.77.167.41, 172.25.20.65
- ReqHeader    X-Forwarded-For: 172.25.20.65
- ReqUnset     Accept-Encoding: gzip, deflate
- ReqHeader    Accept-Encoding: gzip
- ReqUnset     User-Agent: Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
- VCL_return   hash
- VCL_call     HASH
- VCL_return   lookup
- VCL_call     MISS
- VCL_return   fetch
- Link         bereq 9353449 fetch
- Timestamp    Fetch: 1488771709.338395 0.000421 0.000421
- RespProtocol HTTP/1.1

這完全解釋了為什麼無論我們使用何種日誌記錄技術,我們在任何時候都無法獲得通過 varnishncsa 記錄的負載平衡器 IP 地址以外的任何內容。

看起來好像在請求處理中,它通過將 AWS 負載均衡器 IP 地址添加到標頭來建構 X-Forwarded-For 標頭,但由於呼叫 vc_call 會再次對其進行解構並刪除原始客戶端 IP 地址。那麼我該如何保持 X-Forwarded-For 的完整性,為什麼 Varnish 將 IP 從左側移開,而不是像應該的那樣將它們添加到 X-Forwarded-For 標頭中?漏洞?

所以解決這個問題(4.1.3-1.el7.x86_64 中的可能錯誤)是我在瀏覽其他清漆日誌記錄問題時發現的一個線索,特別是關於完全禁用 x-forwarded-for 標頭的問題。

雖然這不是我想要做的,但它提供了關於防止 varnish 將其自己的 vcl_recv 內容附加到我的 vcl_recv 函式定義的按鈕的提示。具體提供您自己的返回(查找)(儘管那是 varnish <= 3)或返回(雜湊)(varnish 4.x)。

所以現在我在 vcl_recv() 的頂部有這個:

# ensure proper logging of x-forwarded-for IP addresses
std.collect(req.http.x-forwarded-for);
set req.http.x-forwarded-for = regsub ( req.http.x-forwarded-for, "^(([0-9]{1,3}\.){3}[0-9]{1,3})(.*)", "\1" );
if (req.http.x-forwarded-for) {
   std.log("ip:" + req.http.x-forwarded-for);
} else {
   std.log("ip:" + client.ip);
}

然後在函式的最後,我當然提到了:

return (hash);

因此,它現在成功地僅記錄客戶端 IP 地址,因為它應該添加以下 varnishncsa 選項:

-F "%%{VCL_Log:ip}x %%l %%u %%t \"%%r\" %%s %%b \"%%{Referer}i\" \"%%{User-agent}i\""

希望其他人發現此資訊有用。

更新:正如我在這個 nginx 答案中發現關於欺騙的文章一樣,在清漆中也有一種real_ip_fromtrusted_ip_from標頭會很好,但目前它似乎不是本機的。在這種情況下,我最初的解決方案將挑選出欺騙地址。因此,最好刪除已知 IP 的正則表達式,然後選擇第一個未處理的客戶端 IP。像這樣的東西會起作用:

set req.http.x-forwarded-for = regsub ( req.http.x-forwarded-for, "(([0-9]{1,3}\.){3}[0-9]{1,3})(, (172.25.20.65|172.25.10.228),?)+$", "\1" );

其中 172.25.20.65 和 172.25.10.228 是我信任的 IP(代理或負載均衡器拾取並添加到 X-Forwarded-For 等)。根據您是否希望在其前面看到代理/LB,如果您希望在您的標頭中始終至少有一個負載均衡器/代理,您的正則表達式可以是這樣的:

(([0-9]{1,3}\.){3}[0-9]{1,3})(, (&lt;trustedip1&gt;|&lt;trustedip2&gt;|...),?)+$

或者如果允許在您的清漆伺服器之前沒有任何東西:

(([0-9]{1,3}\.){3}[0-9]{1,3})(, (&lt;trustedip1&gt;|&lt;trustedip2&gt;|...),?)*$

儘管如果是後者,您為什麼要查看 x-forwarded-for 標頭…

引用自:https://serverfault.com/questions/836671