Varnish 取消设置除最后一个 x-forwarded-for IP 地址之外的所有内容...有错误吗?

Varnish 取消设置除最后一个 x-forwarded-for IP 地址之外的所有内容...有错误吗?

在尝试弄清楚为什么我们的 Varnish 4.1 安装(在 CentOS7 上通过 varnish-cache.org repo)没有遵循 vcl 规则,该规则规定在 X-Forwarded-For 标头中记录客户端 IP 地址(请参阅:Varnish 4 记录代理/负载均衡器而不是客户端 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 标头上?错误?

答案1

因此,解决这个问题(4.1.3-1.el7.x86_64 中可能存在的错误)的方法是,我在浏览其他 varnish 日志问题时找到的线索,特别是完全禁用 x-warded-for 标头

虽然这不是我想要做的,但它提供了关于防止 varnish 将其自己的 vcl_recv 内容附加到我的 vcl_recv 函数定义的底部的提示。具体提供你自己的返回(查找)(尽管清漆 <= 3)或返回(哈希)(清漆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 答案如果有某种真实 IP 地址受信任的 IP 地址varnish 中的 headers 也是如此,但目前似乎不是原生的。在这种情况下,我的初始解决方案将挑选出欺骗地址。因此,最好使用删除已知 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})(, (<trustedip1>|<trustedip2>|...),?)+$

或者如果允许在 varnish 服务器之前没有任何内容,则这样做:

(([0-9]{1,3}\.){3}[0-9]{1,3})(, (<trustedip1>|<trustedip2>|...),?)*$

尽管如果是后者,那么您为什么要查看 x-forwarded-for 标头......

相关内容