在以下设置中:
Client -> LB -> Varnish
我想configurationVarnish acls根据客户的IP采取一定的行动。 LB发送客户端IP到名为“ClientIP”的variables中,该variables可以通过req.httpd.ClientIP.读取req.httpd.ClientIP. 我试过这个:
acl admin_net { "10.10.1.160"/27; } sub vcl_deliever { if (req.http.ClientIP ~ admin_net) { // do something ... } }
但VCL编译失败,“预期的CSTR得到'admin_net'”(Cstring?)。 我可以通过req.http.ClientIP ~ "10.10.1.*")来解决这个问题,但是我必须注释掉ACL行。
有没有另外一种方法来使用ACL的这个工作? 我也查看了client.ip ,这是一个只读variables。 在上面的设置中,它包含LB的IP而不是客户的IP。
事实上,Varnish将client.ip作为一种不同的数据types来处理,所以你可以使用ACL来对付这个值。 这不适用于像req.http.ClientIP(或所有req.http。*参数)的文本值。 所以具有这个文本值的正则expression式似乎是一个很好的解决scheme。
或者,您可以使用特定的模块来设置client.ip。 我发现这个例子: http : //lassekarstensen.wordpress.com/2013/07/22/setting-client-ip-in-varnish-vcl-with-libvmod-ipcast/
这可以使用std.ip完成,假设ClientIP头已经在vcl_recv()中设置。 例如:
vcl 4.0; import std; acl admin_net { "10.10.1.160/27"; } sub vcl_deliver { if (std.ip(req.http.ClientIP,"0.0.0.0") ~ admin_net) { // do something ... } }
如果你的Loadbalancer支持“PROXY”协议,这个答案来自alexus,实际上是正确的答案: https ://info.varnish-software.com/blog/topic/proxy-protocol
使用PROXY协议,Loadbalancer将通知Varnish真实的客户端IP地址,并相应地设置client.ip。
Alexus的代码有效:
acl e410 { "5.9.0.0"/16; } sub vcl_recv { ... if (client.ip ~ e410) { error 410; } ... }
上面的代码示例将完成你想要的。 支持PROXY协议的负载均衡包括:
.. 仅举几个。 这是一个更完整的列表: https : //www.haproxy.com/blog/haproxy/proxy-protocol/
以下是我如何在我的清漆中实现acl:
acl e410 { "5.9.0.0"/16; } sub vcl_recv { ... if (client.ip ~ e410) { error 410; } ... }
尝试在varnishlog里面varnishlog并输出结果,找出错误会更容易…