【发布时间】:2014-10-22 21:40:28
【问题描述】:
我的请求流程如下;
HAProxy --> Varnish (4.0.1) --> Apache web backends
当 HAProxy 收到新请求时,客户端的 IP 地址将被添加到 X-Forwarded-For 标头中(这很好!)。然而,看起来 Varnish 也在添加HAProxy IP。当请求到达我的vcl_recv 例程时,X-Forwarded-For 标头是:
X-Forwarded-For: end-user-ip, haproxy-ip
您可以在varnishlog 输出中看到:
* << Request >> 8
- Begin req 7 rxreq
- Timestamp Start: 1409262358.542659 0.000000 0.000000
- Timestamp Req: 1409262358.542659 0.000000 0.000000
- ReqStart 192.168.1.103 48193
- ReqMethod PURGE
- ReqURL /some/path
- ReqProtocol HTTP/1.1
- ReqHeader Authorization: Basic xxx
- ReqHeader User-Agent: curl/7.30.0
- ReqHeader Host: example.com
- ReqHeader Accept: */*
- ReqHeader X-Forwarded-For: 1.2.3.4
- ReqHeader Connection: close
- ReqUnset X-Forwarded-For: 1.2.3.4
- ReqHeader X-Forwarded-For: 1.2.3.4, 192.168.1.101
- VCL_call RECV
- ReqUnset X-Forwarded-For: 1.2.3.4, 192.168.1.101
- VCL_acl NO_MATCH purge_acl
- Debug "VCL_error(403, Not allowed.)"
- VCL_return synth
我需要准确的客户端 IP 地址的原因是,我可以根据 ACL 规则检查它是否符合 PURGE/BAN。由于X-Forwarded-For 标头中的最后一个 IP 是 HAProxy 的,因此所有 IP 的 ACL 检查都失败。这是我的配置的相关部分:
acl purge_acl {
"1.2.3.4";
}
sub vcl_recv {
set req.backend_hint = load_balancer.backend();
if (req.method == "PURGE") {
if (!std.ip(req.http.X-forwarded-for, "0.0.0.0") ~ purge_acl) {
return(synth(403, "Not allowed."));
}
ban("obj.http.x-url ~ " + req.url);
return(synth(200, "Ban added"));
}
}
有什么想法可以让我完全依赖 HAProxy 的 X-Forwarded-For 标头,而不用 Varnish 篡改它吗?
附带说明,Varnish 似乎正是这样做的(尽管这不在 mv VCL 配置中):
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;
}
}
【问题讨论】:
标签: varnish varnish-vcl