【问题标题】:Varnish 6's VCL not stripping out cookies as expectedVarnish 6 的 VCL 没有按预期剥离 cookie
【发布时间】:2022-01-07 06:06:35
【问题描述】:

我无法使用 Varnish (v6.0.8) 删除我不想使用的 cookie。我认为这是有效的,但我认为它是基于 URL 的过滤在起作用,我只是没有注意到,因为它重叠了。

我的配置文件的相关部分如下:

sub vcl_recv {

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

    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);
}
    if (req.url ~ "(wp-admin|post\.php|edit\.php|wp-login|wp-json)") {
    return(pass);
}
    if (req.http.Cookie ~ "wordpress_logged_in_|resetpass|wp-postpass_") {
    return(pass);
}

# Remove cookies
    set req.http.Cookie = regsuball(req.http.Cookie, "comment_author_[a-zA-Z0-9_]+", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "PHPSESSID=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "wp_woocommerce_session_[^;]+(;)", "");
# Remove proxy header (see https://httpoxy.org/#mitigate-varnish)
    unset req.http.proxy;
# Normalize query arguments (sort alphabetically)
    set req.url = std.querysort(req.url);
# Strip trailing ? if it exists
    if (req.url ~ "\?$") {
    set req.url = regsub(req.url, "\?$", "");
}
# Limit requests to the following types
    if (req.method !~ "^GET|HEAD|PUT|POST|TRACE|OPTIONS|PATCH|DELETE$") {
    return (pipe);
}
# Only cache GET or HEAD requests to ensure that POST requests are always passed through, along with their cookies
    if (req.method != "GET" && req.method != "HEAD") {
    return (pass);
}
# Don't cache AJAX requests
    if (req.http.X-Requested-With == "XMLHttpRequest") {
    return(pass);
}
# Don't cache images and PDFs
    if (req.url ~ "\.(gif|jpg|jpeg|bmp|png|pdf)$") {
    return(pass);
}
# Don't cache large files (zip, audio, video, etc.)
    if (req.url ~ "^[^?]*\.(7z|avi|bz2|flac|flv|gz|mka|mkv|mov|mp3|mp4|mpeg|mpg|ogg|ogm|opus|rar|tar|tgz|tbz|txz|wav|webm|wmv|xz|zip)(\?.*)?$") {
    return (pipe);
}
# Add support for ESI
    if (req.http.Authorization) {
    return (pass);
}
# Wordpress: don't cache WooCommerce pages
    if (req.url ~ "(cart|my-account|checkout|addons|checkouts|product)") {
    return (pass);
}
    if ( req.url ~ "(\?|&)add-to-cart=" ) {
    return (pass);
}
    if ( req.url ~ "(\?|&)wc-ajax=" ) {
    return (pass);
}
# Wordpress: don't cache associated requests if the referer is a WooCommerce page
    if (req.http.referer ~ "(cart|my-account|checkout|addons|checkouts|product)") {
    return(pass);
}
# Are there cookies left with only spaces or that are empty?
    if (req.http.cookie ~ "^\s*$") {
    unset req.http.cookie;
}
# Remove all cookies to enable caching
    unset req.http.Cookie;
    return (hash);
}

据我了解,#Remove cookies 部分中的正则表达式应该删除那些 cookie。但他们没有。我做错了什么?

谢谢!

更新:这是 Varnish 的输出代码。我认为它没有执行,但我不明白为什么。我已经尝试将它移到 sub vcl_recv 部分的顶部,但这没有任何区别:

*   << Request  >> 3007535
-   Begin          req 3007534 rxreq
-   Timestamp      Start: 1638408710.214334 0.000000 0.000000
-   Timestamp      Req: 1638408710.214334 0.000000 0.000000
-   ReqStart       <REDACTED IP> a1
-   ReqMethod      HEAD
-   ReqURL         /example-page/
-   ReqProtocol    HTTP/1.1
-   ReqHeader      host: example.com
-   ReqHeader      user-agent: curl/7.77.0
-   ReqHeader      accept: */*
-   ReqHeader      x-forwarded-port: 443
-   ReqHeader      x-forwarded-proto: https
-   ReqHeader      x-forwarded-for: <REDACTED IP>
-   ReqUnset       x-forwarded-for: <REDACTED IP>
-   ReqHeader      X-Forwarded-For: <REDACTED IP>, <REDACTED IP>
-   VCL_call       RECV
-   ReqUnset       X-Forwarded-For: <REDACTED IP>, <REDACTED IP>
-   ReqHeader      X-Forwarded-For: <REDACTED IP>
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqUnset       Cookie:
-   ReqHeader      Cookie:
-   ReqURL         /example-page/
-   ReqUnset       Cookie:
-   VCL_return     hash
-   VCL_call       HASH
-   ReqHeader      newUrl: /example-page/
-   VCL_return     lookup
-   HitMiss        3617921 98.252548
-   VCL_call       MISS
-   VCL_return     fetch
-   Link           bereq 3007536 fetch
-   Timestamp      Fetch: 1638408711.615163 1.400829 1.400829
-   RespProtocol   HTTP/1.1
-   RespStatus     200
-   RespReason     OK
-   RespHeader     Server: nginx
-   RespHeader     Date: Thu, 02 Dec 2021 01:31:51 GMT
-   RespHeader     Content-Type: text/html; charset=UTF-8
-   RespHeader     Vary: Accept-Encoding
-   RespHeader     Set-Cookie: wp_woocommerce_session_7006ef9ea65e2d5e1a330b658a34667c=e005d432498b0dc461295d782d2bc59c%7C%7C1638581510%7C%7C1638577910%7C%7C13a8cdc105250d841e0fef56a1255d03; expires=Sat, 04-Dec-2021 01:31:50 GMT; Max-Age=172800; path=/; secure; HttpOnly
-   RespHeader     Set-Cookie: wl_current_page_id=20387; expires=Thu, 02-Dec-2021 02:31:50 GMT; Max-Age=3600; path=/
-   RespHeader     Link: <https://example.com/wp-json/>; rel="https://api.w.org/"
-   RespHeader     Link: <https://example.com/wp-json/wp/v2/posts/20387>; rel="alternate"; type="application/json"
-   RespHeader     Link: <https://example.com/?p=20387>; rel=shortlink
-   RespHeader     X-Content-Type-Options: nosniff
-   RespHeader     X-XSS-Protection: 1; mode=block
-   RespHeader     X-UA-Compatible: IE=Edge
-   RespHeader     Content-Security-Policy: frame-ancestors 'self'
-   RespHeader     X-Frame-Options: SAMEORIGIN
-   RespHeader     Content-Encoding: gzip
-   RespHeader     x-url: /example-page/
-   RespHeader     x-host: example.com
-   RespHeader     X-Varnish: 3007535
-   RespHeader     Age: 0
-   RespHeader     Via: 1.1 varnish (Varnish/6.0)
-   VCL_call       DELIVER
-   RespUnset      x-url: /example-page/
-   RespUnset      x-host: example.com
-   RespHeader     X-Cache: MISS
-   RespHeader     X-Cache-Hits: 0
-   RespUnset      X-Varnish: 3007535
-   RespUnset      Via: 1.1 varnish (Varnish/6.0)
-   RespUnset      Server: nginx
-   VCL_return     deliver
-   Timestamp      Process: 1638408711.615227 1.400893 0.000064
-   RespUnset      Content-Encoding: gzip
-   RespHeader     Accept-Ranges: bytes
-   RespHeader     Connection: keep-alive
-   Gzip           U D - 0 0 0 0 0
-   Timestamp      Resp: 1638408711.615536 1.401202 0.000309
-   ReqAcct        239 0 239 947 0 947
-   End
**  << BeReq    >> 3007536
--  Begin          bereq 3007535 fetch
--  VCL_use        reload_20211202_013110_5534
--  Timestamp      Start: 1638408710.214561 0.000000 0.000000
--  BereqMethod    HEAD
--  BereqURL       /example-page/
--  BereqProtocol  HTTP/1.1
--  BereqHeader    host: example.com
--  BereqHeader    user-agent: curl/7.77.0
--  BereqHeader    accept: */*
--  BereqHeader    x-forwarded-port: 443
--  BereqHeader    x-forwarded-proto: https
--  BereqHeader    X-Forwarded-For: <REDACTED IP>
--  BereqHeader    newUrl: /example-page/
--  BereqMethod    GET
--  BereqHeader    Accept-Encoding: gzip
--  BereqHeader    X-Varnish: 3007536
--  VCL_call       BACKEND_FETCH
--  VCL_return     fetch
--  BackendOpen    66 reload_20211202_013110_5534.planet-a 10.0.55.20 80 10.0.55.10 43206
--  BackendStart   <REDACTED> 80
--  Timestamp      Bereq: 1638408710.214709 0.000147 0.000147
--  Timestamp      Beresp: 1638408711.614969 1.400408 1.400261
--  BerespProtocol HTTP/1.1
--  BerespStatus   200
--  BerespReason   OK
--  BerespHeader   Server: nginx
--  BerespHeader   Date: Thu, 02 Dec 2021 01:31:51 GMT
--  BerespHeader   Content-Type: text/html; charset=UTF-8
--  BerespHeader   Transfer-Encoding: chunked
--  BerespHeader   Connection: keep-alive
--  BerespHeader   Vary: Accept-Encoding
--  BerespHeader   Set-Cookie: wp_woocommerce_session_7006ef9ea65e2d5e1a330b658a34667c=e005d432498b0dc461295d782d2bc59c%7C%7C1638581510%7C%7C1638577910%7C%7C13a8cdc105250d841e0fef56a1255d03; expires=Sat, 04-Dec-2021 01:31:50 GMT; Max-Age=172800; path=/; secure; HttpOnly
--  BerespHeader   Set-Cookie: wl_current_page_id=20387; expires=Thu, 02-Dec-2021 02:31:50 GMT; Max-Age=3600; path=/
--  BerespHeader   Link: <https://example.com/wp-json/>; rel="https://api.w.org/"
--  BerespHeader   Link: <https://example.com/wp-json/wp/v2/posts/20387>; rel="alternate"; type="application/json"
--  BerespHeader   Link: <https://example.com/?p=20387>; rel=shortlink
--  BerespHeader   X-Content-Type-Options: nosniff
--  BerespHeader   X-XSS-Protection: 1; mode=block
--  BerespHeader   X-UA-Compatible: IE=Edge
--  BerespHeader   Content-Security-Policy: frame-ancestors 'self'
--  BerespHeader   X-Frame-Options: SAMEORIGIN
--  BerespHeader   Content-Encoding: gzip
--  TTL            RFC 120 10 0 1638408712 1638408712 1638408711 0 0 cacheable
--  VCL_call       BACKEND_RESPONSE
--  BerespHeader   x-url: /example-page/
--  BerespHeader   x-host: example.com
--  TTL            VCL 2592000 10 0 1638408712 cacheable
--  TTL            VCL 2592000 86400 0 1638408712 cacheable
--  TTL            VCL 120 86400 0 1638408712 cacheable
--  TTL            VCL 120 86400 0 1638408712 uncacheable
--  VCL_return     deliver
--  Storage        malloc Transient
--  Fetch_Body     2 chunked stream
--  Debug          "Fetch: Pass delivery abandoned%00"
--  Gzip           u F - 13522 65516 80 80 0
--  BackendClose   66 reload_20211202_013110_5534.planet-a
--  Timestamp      BerespBody: 1638408711.616261 1.401700 0.001292
--  Length         13522
--  BereqAcct      347 0 347 952 13522 14474
--  End

【问题讨论】:

    标签: varnish varnish-vcl


    【解决方案1】:

    cookie删除VCL代码是否执行?

    你能检查一下你是否真的达到了删除这些 cookie 的程度吗?

    在删除 cookie 之前执行的以下代码可能会影响这一点:

    if (req.http.Cookie ~ "wordpress_logged_in_|resetpass|wp-postpass_") {
        return(pass);
    }
    

    例如,如果设置了wordpress_logged_in_ cookie,缓存将被绕过并且不会执行任何 cookie 删除代码。

    您可以通过运行以下varnishlog 命令对此进行测试:

    sudo varnishlog -g request -q "ReqUrl eq '/'"
    

    仅供参考:此varnishlog 命令仅过滤掉对主页的请求。如果您想过滤掉对其他 URL 的请求,请将 / 更改为相应的页面。

    输出将显示请求发生了什么以及 Varnish 对这个特定请求的行为方式。如果您需要帮助,只需将 varnishlog 输出粘贴到您的原始问题中,我会帮助您进行调查。

    保留必要的 cookie,而不是删除不需要的 cookie

    跟踪您要删除的所有 cookie 是一项乏味的工作。

    您还可以删除所有 cookie,只保留重要的 cookie。下面是一些示例代码,仅保留 wordpress_logged_in_[hash] cookie 将删除所有其他 cookie:

    sub vcl_recv {
        if (req.http.Cookie) {
        set req.http.Cookie = ";" + req.http.Cookie;
        set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
        set req.http.Cookie = regsuball(req.http.Cookie, ";(wordpress_logged_in_[A-Za-z0-9]+)=", "; \1=");
        set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
        
        if (req.http.cookie ~ "^\s*$") {
            unset req.http.cookie;
        }
    }
    

    官方 Varnish WordPress VCL 文件

    如果您对我们在 Varnish Software 推荐的 WordPress 的 VCL 文件感兴趣,请查看https://www.varnish-software.com/developers/tutorials/configuring-varnish-wordpress/

    更新:我对您的 VSL 输出的反应

    我注意到在您的 VSL 输出中,客户端没有为向 /example-page/ 的请求传递任何 cookie。

    cookie 查找和替换逻辑启动,但没有任何影响,因为没有要删除的 cookie。

    您可以通过以下所有行在 VSL 输出中注意到这一点:

    -   ReqHeader      Cookie:
    -   ReqUnset       Cookie:
    

    内容被认为是可缓存的,并在vcl_hash 子例程中进行缓存查找。

    已找到对象,但标记为 Hit-For-Miss,由以下日志行指示:

    -   HitMiss        3617921 98.252548
    

    这意味着内容在之前的请求/响应事务中被标记为不可缓存。

    然后我们继续获取内容,该内容再次被标记为不可缓存。

    如果您熟悉 Varnish's built-in VCL,您会立即在响应中发现导致此问题的 Set-Cookie 标头:

    -   RespHeader     Set-Cookie: wp_woocommerce_session_7006ef9ea65e2d5e1a330b658a34667c=e005d432498b0dc461295d782d2bc59c%7C%7C1638581510%7C%7C1638577910%7C%7C13a8cdc105250d841e0fef56a1255d03; expires=Sat, 04-Dec-2021 01:31:50 GMT; Max-Age=172800; path=/; secure; HttpOnly
    -   RespHeader     Set-Cookie: wl_current_page_id=20387; expires=Thu, 02-Dec-2021 02:31:50 GMT; Max-Age=3600; path=/
    

    结论是您的 WooCommerce/WordPress 设置会在第一次请求时发出 Set-Cookie 标头。如果客户端在后续请求中未传递这些会话 cookie,WooCommerce/WordPress 将继续设置它们。

    这就是内容无法缓存的原因。

    请确保仅在需要状态数据的情况下设置会话 cookie(例如:向购物车添加内容、执行结帐)。

    对于产品页面的常规浏览,不需要会话 cookie。但是,如果您认为页面的某些部分确实需要它们,请确保此逻辑包含在通过 AJAX 或 ESI 的单独 HTTP 调用中。

    【讨论】:

    • 谢谢。我已将输出添加到我原来的问题中。
    • @EnfantTerrible 我对我的原始回复添加了广泛的更新。
    • 谢谢。一如既往,这非常有帮助!
    猜你喜欢
    • 1970-01-01
    • 2014-12-04
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    相关资源
    最近更新 更多