我让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记录的.是否有一个很好的简单方法来阻止Varnish重写X-Forwarded-For如果已经填充了?
最佳答案
绝对; X-Forwarded-For的Varnish处理实际上只是在默认的vcl_recv函数中定义的.
原文链接:https://www.f2er.com/nginx/435270.htmlif (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:
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;
}
}