【问题标题】:Varnish 4 + Pounds - Bypass cache for specific IP AddressVarnish 4 + Pounds - 绕过特定 IP 地址的缓存
【发布时间】:2020-07-05 03:24:20
【问题描述】:

我正在尝试将 Varnish 配置为不对特定 IP 使用缓存。

我在 Centos 上配置了 Varnish 4,使用 Pound 来管理 HTTPS 请求。 p>

我尝试过这种方法:

Varnish - Bypass Cache for IP Address

基于

https://zcentric.com/2012/03/16/varnish-acl-with-x-forwarded-for-header/

使用一些 C 代码来管理 IP。建议的代码适用于 Varnish3(例如“sp”不再存在,现在有一个 ctx 变量)

我尝试使用这种方法Inline C Varnish (VCL_deliver),但我得到一个 *"initialization from incompatible pointer type [-Werror] in struct sockaddr_storage client_ip_ss = VRT_r_client_ip(ctx); " 错误可能是因为类型也发生了变化。

我尝试使用的代码是:

struct sockaddr_storage *client_ip_ss = VRT_r_client_ip(ctx); 
struct sockaddr_in *client_ip_si = (struct sockaddr_in *) client_ip_ss; 
struct in_addr *client_ip_ia = &(client_ip_si->sin_addr); 
const struct gethdr_s hdr = { HDR_REQ, "20X-Forwarded-For:" }; 
char *xff_ip = VRT_GetHdr(ctx, &hdr);

但我做错了什么。

我现在有点迷茫,如何在 Varnish 4 上禁用特定 IP 的 varnish?

谢谢

【问题讨论】:

    标签: c centos varnish varnish-4 pound


    【解决方案1】:

    请不要在 Varnish 中编写内联 C:这是有风险的,而且您正在寻找的解决方案已经在 Varnish 中自动实现了。

    请记住,不再支持 Varnish v3 和 v4,请使用 Varnish 6

    Varnish 自动设置X-Forwarded-For 标头

    如果您想根据X-Forwarded-For 值从缓存中排除项目,您仍然可以使用client.ip 并将该值与acl 匹配。

    Varnish 会自动从其客户端获取 IP 并将其存储在 X-Forwarded-For 标头中。这意味着client.ip 的值与req.http.X-Forwarded-For 完全相同。

    多个代理和代理协议

    在到达 Varnish 之前使用其他代理时,您必须确保它们通过 PROXY 协议进行通信。 Varnish 支持 PROXY 协议,你的其他代理也应该支持。

    在您的情况下,它是英镑。 Varnish 社区建议 Hitch 终止 TLS。

    在 Varnish 中启用 PROXY 协议支持是通过打开一个特定的监听地址来完成的:

    varnishd -a :80 -a :8443,PROXY
    

    然后,Varnish 可以通过 PROXY 协议接受端口 8443 上的连接。

    使用 PROXY 协议的主要优点是原始客户端 IP 地址一直传输到 Varnish。无论 Varnish 前面有多少个代理,client.ip 的值始终是原始客户端的 IP 地址。

    如果 Pound 不支持 PROXY 协议,我建议你切换到Hitch

    定义 ACL

    一旦您设法使用 PROXY 协议支持设置 TLS 终止,您就可以编写一些 VCL 来从缓存中传递项目,如下所示:

    acl passem { "7x.xxx.xxx.xxx"; }
    sub vcl_recv {
      if (!(client.ip ~ passem)) {
        return (pass);
      }
    }
    

    【讨论】:

    • 您好,感谢您的回复。只是一个问题(可能很愚蠢,但我不习惯清漆):因为我想为特定的 IPS 禁用清漆,所以这个 if (!(client.ip ~ passem)) { return (pass); } 是 if ((client.ip ~ passem)) { return (pass); }(没有“!”)
    • 当然,取决于 IP 是在黑名单还是白名单中。但我猜由于 ACL 的名称是 passem,您可能希望传递这些 IP,这使您的评论有效。
    • 我尝试了上面的“varnishd -a”命令,但我得到“无效的监听地址代理(尝试将参数监听地址设置为:8443,代理)”错误。它应该只适用于 Varnish6 吗?我必须使用 Varnish 4
    • 通过一些调试,我注意到 req.http.X-Forwarded-For 的格式为 [VISITOR IP], 127.0.0.1 所以我使用了这个似乎有效的代码: if ((std.ip (regsub(req.http.X-Forwarded-For,", 127.0.0.1",""), "0.0.0.0") ~ passem)) { return(pass); }
    • 这是我的一篇旧博客文章,其中包含有关 Varnish 4.1 的信息(目前已停产)。请忽略 HAProxy 部分:feryn.eu/blog/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 2011-07-28
    相关资源
    最近更新 更多