【问题标题】:Can't PURGE entire domain in Varnish, but can PURGE individual pages, do I have a misconfiguration?无法在 Varnish 中清除整个域,但可以清除单个页面,我是否配置错误?
【发布时间】:2021-03-08 20:20:13
【问题描述】:

我假设我在 Varnish 配置中一定犯了一个错误。 (我正在运行版本 6.0.7。)这是相关部分:

####----SECTION THREE: PURGE RULES----####
# Access Control List to define which IPs can purge content
acl purge {
        "localhost";
        "127.0.0.1";
        "<my home IP address>";
        "::1";
}

####----SECTION FOUR: PROCESSING RULES----####
sub vcl_recv {

# Do not allow purging from non-approved IPs
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return (synth(405, "This IP is not allowed to send PURGE requests."));
}
    return (purge);
}

# Allow banning regexes
    if (req.method == "BAN") {
        if (!client.ip ~ purge) {
            return (synth(405, "This IP is not allowed to send BAN requests."));
    }
        ban("req.http.host == " + req.http.host + " && req.url ~ ^" + req.url);
        return (synth(200, "Ban added"));
    }
# Allow purging regexes
        if (req.method == "PURGE") {
        if (req.http.X-Purge-Method == "regex") {
        ban("req.url ~ " + req.url + " && req.http.host ~ " + req.http.host);
        return (synth(200, "Banned"));
    } else {
    return (purge);
    }     

(注意:在我的设置中,Varnish 在端口 6081 上运行,前面有 HAProxy。)

使用此设置,无论是从我的家庭 IP 地址还是正在运行 Varnish 的服务器,我都可以通过运行从 Varnish 缓存中清除各个页面,例如:

curl -i -X PURGE https://example.com/page/

我还可以通过运行从 Varnish 缓存中清除整个域,例如:

curl -i -X BAN https://example.com

同样,我可以通过运行从 Varnish 缓存中清除单个页面,例如:

curl -i -X PURGE http://<IP of Varnish server>:6081/page/ -H "Host: example.com”

我还可以通过运行从 Varnish 缓存中清除整个域,例如:

curl -i -X BAN http://<IP of Varnish server>:6081 -H "Host: example.com”

但我注意到我无法通过运行以下任一方式清除整个域:

curl -i -X PURGE https://example.com

或:

curl -i -X PURGE http://<IP of Varnish server>:6081 -H "Host: example.com”

要清除整个域,我必须改用 BAN。我不知道这是问题还是配置错误,但似乎是,因为虽然我已经读过 PURGE 不用于清除所有内容,但我正在使用的 Wordpress 插件似乎正在尝试通过发送 PURGE 请求当我点击“清除所有清漆缓存”按钮时,domain.com/.*

坦率地说,这让我很困惑。因为它在插件本身或我从命令行尝试时都不起作用。我错过了什么?插件是不是已经过时了? Varnish 曾经能够以这种方式清除整个缓存吗?我会很感激任何指示。谢谢!

【问题讨论】:

    标签: varnish varnish-vcl varnish-4


    【解决方案1】:

    这是您的 VCL 中清除逻辑的清理版本:

    acl purge {
            "localhost";
            "127.0.0.1";
            "::1";
    }
    
    sub vcl_recv {
        if (req.method == "PURGE") {
            if (!client.ip ~ purge) {
                return (synth(405, "This IP is not allowed to send PURGE requests."));
            }
            if (req.http.X-Purge-Method == "regex") {
                ban("obj.http.x-url ~ " + req.url + " && obj.http.x-host ~ " + req.http.host);
                return (synth(200, "Banned"));
            }
            return (purge);
        }
    }
    
    sub vcl_backend_response {
        set beresp.http.x-url = bereq.url;
        set beresp.http.x-host = bereq.http.host;
    }
    
    sub vcl_deliver {
        unset resp.http.x-url;
        unset resp.http.x-host;
    }
    

    清除

    PURGE HTTP 方法是触发缓存失效的原因。没有任何标题 return(purge); 将被调用,这将使所使用的确切 URL 无效。

    如果添加了X-Purge-method 请求头,并设置为regex,则会发生正则表达式匹配。 return(purge); 无法使用正则表达式使多个对象无效,并且需要禁止。

    禁令

    ban() 函数将禁止表达式添加到禁止列表。此列表中的表达式与缓存中存储的所有对象匹配。匹配的将被删除。

    您可以在您的 Varnish 服务器上使用以下命令查询禁止列表:

    varnishadm ban.list
    

    对潜伏者友好的禁令

    ban lurker,一个处理禁止列表的特殊线程,无权访问请求上下文。如果您希望此线程根据 URL 或主机名等请求参数从缓存中删除对象,则需要应用一些技巧。

    如您所见,我建议的模式匹配 obj.http.x-urlobj.http.x-host。这些是通过 2 个自定义响应标头在 vcl_backend_response 中设置的。

    如果不这样做,ban lurker 无法匹配对象,责任将转移到下一个请求。即使没有这些所谓的对潜伏者友好的禁令,禁令仍然有效,但效率不高。

    测试它

    第一个示例将使缓存中的http://example.com/page 无效

    curl -i -XPURGE -H "Host: example.com" "http://localhost:6081/page/"
    

    下一个示例将使所有 URL 以 http://example.com/page 开头的对象无效:

    curl -i -XPURGE -H "Host: example.com" -H "X-Purge-Method: regex" "http://localhost:6081/page/"
    

    最后一个示例将使 example.com 域的缓存中的所有对象无效:

    curl -i -XPURGE -H "Host: example.com" -H "X-Purge-Method: regex" "http://localhost:6081/.*"
    

    这是最后一个示例的禁止列表项:

    root@varnish:/etc/varnish# varnishadm ban.list
    Present bans:
    1606393598.913178     0 -  obj.http.x-url ~ /.* && obj.http.x-host ~ example.com
    1606393484.785268     3 C
    

    如您所见,它匹配 example.com 主机的所有 URL。之后执行 HTTP 请求时,您将看到 Age: 0 响应标头。这表明此响应已在缓存中存储零秒。这意味着禁令成功了。

    【讨论】:

    • 这非常有帮助。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 2011-08-10
    • 2015-08-15
    • 1970-01-01
    相关资源
    最近更新 更多