【问题标题】:varnish purge allowed only from a public ip仅允许从公共 IP 清除清漆
【发布时间】:2021-07-02 14:12:24
【问题描述】:

我的设置如下: Nginx(443 https) -> Varnish(端口 6081) -> Nginx(端口 83 - 应用程序本身)

#nginx https 配置:

location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 1800;
        proxy_request_buffering off;
        proxy_buffering off;
        proxy_pass http://127.0.0.1:6081;
}

#part of default.vlc conf:

backend default {
    .host = "127.0.0.1";
    .port = "83";
}

当然,83 端口还有另一个 nginx 配置,即应用程序本身。 我是这样配置的,所以我可以在 HTTPS 后面运行 varnish。

尝试设置清除以使特定端点的缓存无效,我在 default.vcl 中配置了以下内容:

acl purge {
    "127.0.0.1";
    "some_public_ip"
  }

sub vcl_recv {
    if (req.method == "PURGE") {
      if (!client.ip ~ purge) { 
         return (synth(405, "This IP is not allowed to send PURGE requests."));
      }
      return (purge);
    }
}

一切正常,我可以执行了:

curl -X PURGE -I "https://web_server/index.php".

问题是,如果我从 acl 列表中删除“127.0.0.1”,只让“some_public_ip”,它将不再起作用。它将返回“不允许此 IP 发送 PURGE 请求”。 我只希望清除仅适用于“some_public_ip”。 有可能吗?

【问题讨论】:

    标签: varnish


    【解决方案1】:

    因为 Nginx 位于 Varnish 前面,所以 client.ip 变量总是通过 localhost 引用它。实际的客户端 IP 地址存储在 X-Forwarded-For 标头中。

    您可以通过调用std.ip(req.http.X-Forwarded-For,client.ip) 来提取它。这会将X-Forwarded-For 的值从字符串转换为IP 地址,并且在出现错误时仍会使用client.ip 作为备用。

    由于 Nginx 已经设置了X-Forwarded-For 标头,Varnish 会将其客户端的 IP 地址添加到其中。

    我的varnishlog 输出显示以下日志行:

    -   ReqUnset       X-Forwarded-For: 178.118.13.77
    -   ReqHeader      X-Forwarded-For: 178.118.13.77, 127.0.0.1
    

    我们必须删除第二部分才能获得正确的 IP 地址。我们可以使用以下 VCL sn-p 来做到这一点:

    set req.http.X-Forwarded-For = regsub(req.http.X-Forwarded-For,"^([^,]+),.*$","\1");
    

    最后,这是我们完成这项工作所需的 VCL 代码:

    vcl 4.0;
    
    import std;
    
    acl purge {
        "127.0.0.1";
        "some_public_ip"
      }
    
    sub vcl_recv {
        if(req.http.X-Forwarded-For ~ ","){
            set req.http.X-Forwarded-For = regsub(req.http.X-Forwarded-For,"^([^,]+),.*$","\1");
        }
        if (req.method == "PURGE") {
          if (!std.ip(req.http.X-Forwarded-For,client.ip) ~ purge) {
             return (synth(405, "This IP is not allowed to send PURGE requests."));
          }
          return (purge);
        }
    }
    

    【讨论】:

    • 试过了,还是一样的。如果我将 127.0.0.1 和我的公共 ip 留在 acl 中,它将从任何公共 ip 工作,而不仅仅是我的,因为如果会像你说的那样从那个 127.0.0.1 获得请求。如果我从 acl 中删除 127.0.0.1 并只留下我的公共 IP,它将向我发送“不允许此 IP 发送 PURGE 请求”错误。
    • @catalin 我更新了我的答案:显然 Varnish 将 127.0.0.1 添加到 X-Forwarded-For 标头。我们需要去掉这部分才能让这个例子工作。
    • 感谢朋友。有用。我真的很感激。
    猜你喜欢
    • 2018-03-28
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 2012-06-22
    • 2013-03-04
    • 2022-11-28
    • 2023-03-17
    相关资源
    最近更新 更多