Varnish 缓存在索引页面或其他页面上显示相同图像/css/txt 文件的奇怪问题

问题描述 投票:0回答:1

我正在尝试解决 WordPress 网站上的 Varnish Cache + Nginx 设置之一的问题。我正在运行以下服务器堆栈

Nginx( HTTPS - 443 ) -> Varnish ( HTTP - 80 ) -> Nginx (HTTP - 8080 )

我使用 vhost 方法进行 Varnish 缓存,以便我可以在同一个 Varnish 服务器上托管多个站点。目前,该服务器仅托管 WordPress 上的一个网站。

问题? 清漆在访问网站时向所有页面提供随机图像/CSS 文件甚至 robots.txt。 我在default.vcl中包含了以下vcl文件

mydomain.com.vcl

# Auto Generated Varnish Configuration
# Wordpress Varnish  Optimizations
# Build time : 2024-03-15 14:19:11.575844
# Domain : mydomain.com
import proxy;
sub vcl_recv {
    if (req.http.host=="mydomain.com" || req.http.host=="www.mydomain.com") { 
        # Set the backend 
        set req.backend_hint = ip_3a355ffbe92e19d4c646b0943e689d609954ef7d; 
        
        # Remove empty query string parameters    
        if (req.url ~ "\?$") {
            set req.url = regsub(req.url, "\?$", "");
        }

        # Sorts query string parameters alphabetically for cache normalization purposes
        set req.url = std.querysort(req.url);

        # Remove the proxy header to mitigate the httpoxy vulnerability    
        unset req.http.proxy;

        # Add X-Forwarded-Proto header when using https
        if (!req.http.X-Forwarded-Proto) {
            if(std.port(server.ip) == 443 || proxy.is_ssl()) {
                set req.http.X-Forwarded-Proto = "https";
            } else {
                set req.http.X-Forwarded-Proto = "http";
            }
        }
        # Only handle relevant HTTP request methods
        if (
            req.method != "GET" &&
            req.method != "HEAD" &&
            req.method != "PUT" &&
            req.method != "POST" &&
            req.method != "PATCH" &&
            req.method != "TRACE" &&
            req.method != "OPTIONS" &&
            req.method != "DELETE"
        ) {
            return (pipe);
        }
        # Only cache GET and HEAD requests
        if (req.method != "GET" && req.method != "HEAD") {
            set req.http.X-Cacheable = "NO:REQUEST-METHOD";
            return(pass);
        }
        # Mark static files with the X-Static-File header, and remove any cookies
        # X-Static-File is also used in vcl_backend_response to identify static files
        if (req.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
           set req.http.X-Static-File = "true";
         #   unset req.http.Cookie;
         #   return(hash);
         #   return(pass);     #=> If I pass the image the site works fine
        }
        # No caching of special URLs, logged in users and some plugins
        if (
            req.http.Cookie ~ "wordpress_(?!test_)[a-zA-Z0-9_]+|wp-postpass|comment_author_[a-zA-Z0-9_]+|woocommerce_cart_hash|woocommerce_items_in_cart|wp_woocommerce_session_[a-zA-Z0-9]+|wordpress_logged_in_|comment_author|PHPSESSID" ||
            req.http.Authorization ||
            req.url ~ "add_to_cart" ||
            req.url ~ "edd_action" ||
            req.url ~ "nocache" ||
            req.url ~ "^/addons" ||
            req.url ~ "^/bb-admin" ||
            req.url ~ "^/bb-login.php" ||
            req.url ~ "^/bb-reset-password.php" ||
            req.url ~ "^/cart" ||
            req.url ~ "^/checkout" ||
            req.url ~ "^/control.php" ||
            req.url ~ "^/login" ||
            req.url ~ "^/logout" ||
            req.url ~ "^/lost-password" ||
            req.url ~ "^/my-account" ||
            req.url ~ "^/product" ||
            req.url ~ "^/register" ||
            req.url ~ "^/register.php" ||
            req.url ~ "^/server-status" ||
            req.url ~ "^/signin" ||
            req.url ~ "^/signup" ||
            req.url ~ "^/stats" ||
            req.url ~ "^/wc-api" ||
            req.url ~ "^/wp-admin" ||
            req.url ~ "^/wp-comments-post.php" ||
            req.url ~ "^/wp-cron.php" ||
            req.url ~ "^/wp-login.php" ||
            req.url ~ "^/wp-activate.php" ||
            req.url ~ "^/wp-mail.php" ||
            req.url ~ "^/wp-login.php" ||
            req.url ~ "^\?add-to-cart=" ||
            req.url ~ "^\?wc-api=" ||
            req.url ~ "^/preview=" ||
            req.url ~ "^/\.well-known/acme-challenge/"
        ) {
            set req.http.X-Cacheable = "NO:Logged in/Got Sessions";
            if(req.http.X-Requested-With == "XMLHttpRequest") {
                set req.http.X-Cacheable = "NO:Ajax";
            }
            return(pass);
        }
        # Enable GZIP compression
        if (req.http.Accept-Encoding) {
            if (req.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
                unset req.http.Accept-Encoding;
            } elsif (req.http.Accept-Encoding ~ "gzip") {
                set req.http.Accept-Encoding = "gzip";
            } elsif (req.http.Accept-Encoding ~ "deflate" &&
                req.http.user-agent !~ "MSIE") {
                set req.http.Accept-Encoding = "deflate";
            } else {
                unset req.http.Accept-Encoding;
            }
        }
        
        # Remove any cookies left
        unset req.http.Cookie;
        return(hash);
    }   
}
    
sub vcl_hash {
    if (req.http.host=="mydomain.com" || req.http.host=="www.mydomain.com") { 
        if(req.http.X-Forwarded-Proto) {
            # Create cache variations depending on the request protocol       
            hash_data(req.http.X-Forwarded-Proto);
        }
        return (lookup);
    }
}

sub vcl_backend_response {
    if (bereq.http.host=="mydomain.com" || bereq.http.host=="www.mydomain.com") {
    # Do not cache 404 error
    if ( beresp.status >= 301 ) {
      set beresp.ttl = 30s;
      set beresp.uncacheable = true;
      return (deliver);
    }
   
        # Inject URL & Host header into the object for asynchronous banning purposes
        set beresp.http.x-url = bereq.url;
        set beresp.http.x-host = bereq.http.host;

        # If we dont get a Cache-Control header from the backend
        # we default to 1h cache for all objects
        if (!beresp.http.Cache-Control) {
            set beresp.ttl = 1h;
            set beresp.http.X-Cacheable = "YES:Forced";
        }

        # If the file is marked as static we cache it for 1 day
        if (bereq.http.X-Static-File == "true") {
            unset beresp.http.Set-Cookie;
            set beresp.http.X-Cacheable = "YES:Forced";
            set beresp.ttl = 1d;
        }

        # Remove the Set-Cookie header when a specific Wordfence cookie is set
        if (beresp.http.Set-Cookie ~ "wfvt_|wordfence_verifiedHuman") {
            unset beresp.http.Set-Cookie;
            }
        
        if (beresp.http.Set-Cookie) {
            set beresp.http.X-Cacheable = "NO:Got Cookies";
        } elseif(beresp.http.Cache-Control ~ "private") {
            set beresp.http.X-Cacheable = "NO:Cache-Control=private";
        
        } elseif (beresp.http.Cache-Control ~ "must-revalidate") {
            set beresp.grace = 0s;
        }

        # Removice cookies on static files
        if (bereq.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
            unset beresp.http.cookie;
        }


        # Gzip compression
        if (beresp.http.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
             set beresp.do_gzip = false;
        }
        else {
            set beresp.do_gzip = true;
            set beresp.http.X-Cache = "ZIP";
        }
        # Do not cache  301, 302, 404, 403, 502 .etc.  error
    
        return (deliver);
    }   
}

sub vcl_deliver {
    if (req.http.host=="mydomain.com" || req.http.host=="www.mydomain.com") {
        # You can do accounting or modifying the final object here.
        if (obj.hits) { # Add debug header to see if it's a HIT/MISS and the number of hits, disable when not needed
            set resp.http.X-Cache = "HIT";
        } else {
            set resp.http.X-Cache = "MISS";
        }
        # Cleanup of headers
        unset resp.http.x-url;
        unset resp.http.x-host;   
        unset resp.http.x-powered-by;        
        unset resp.http.X-Powered-By;        
        return (deliver);
    }
}
# Bypass webmail , eenos etc,.
# Domain : mail.mydomain.com
sub vcl_recv {
    # Set the backend 
    if (req.http.host=="mail.mydomain.com" || req.http.host=="www.mail.mydomain.com" || req.http.host=="eenos.mydomain.com"){
        set req.backend_hint = ip_3a355ffbe92e19d4c646b0943e689d609954ef7d; 
        return (pass);
    }
}

如您所见,这与其网站上提供的官方 varnish Wordpress 设置相同,但有一些细微的更改。

以下是我在 Nginx 上的 Varnish SSL 终止

#.......... HTTPS VHOST .................................. # Varnish ssl termination server { listen 10.0.0.79:443 ssl ; http2 on; server_name mydomain.com www.mydomain.com; ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; ssl_protocols TLSv1.3 TLSv1.2; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA; # Browser control ssl ciphers ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:20m; ssl_session_timeout 60m; # All access logs will be handled by proxy access_log off; # Disable direct access to .ht files and folders location ~ /\.(ht|ini|log|conf)$ { deny all; } keepalive_requests 100; keepalive_timeout 60s; # Directory listing disabled autoindex off; # External Alias location / { proxy_pass http://10.0.0.79:80; proxy_set_header Host $host; proxy_set_header X-Forwarded-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 https; proxy_set_header X-Forwarded-Port 443; proxy_set_header HTTPS "on"; proxy_buffering on; proxy_send_timeout 600s; proxy_read_timeout 600s; proxy_buffer_size 256k; proxy_buffers 128 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_connect_timeout 300s; proxy_http_version 1.1; } }

Nginx Wordpress 虚拟主机

server { listen 10.0.0.79:8080; server_name mydomain.com www.mydomain.com; # lets encrypt auto ssl acme validation location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; root /var/www/html; } root /home/site/public_html; index index.php index.perl index.pl index.cgi index.phtml index.shtml index.xhtml index.html index.htm index.wml Default.html Default.htm default.html default.htm home.html home.htm eenos.html; location = /favicon.ico { log_not_found off; } # All access logs access_log /var/log/domlogs/mydomain.com main; access_log /var/log/domlogs/mydomain.com-bytes_log bytes_log; referer_hash_bucket_size 512; # Run static file directly from nginx location ~* ^.+.(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|iso|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|mp3|ogv|ogg|flv|swf|mpeg|mpg|mpeg4|mp4|avi|wmv|js|css|3gp|sis|sisx|nth)$ { expires 30d; } # Disable direct access to .ht files and folders location ~ /\.(ht|ini|log|conf)$ { deny all; } keepalive_requests 100; keepalive_timeout 60s; # Directory listing disabled autoindex off; #phpfiles location ~ \.php$ { try_files $uri =404; fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/3446b18857ef807e294d091515955c3666797768.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include /etc/nginx/fastcgi_params; } # Disable direct access to .php files in the following on a wordpress site location ~* /(?:uploads|files)/.*\.php$ { deny all; } location / { client_max_body_size 2000m; client_body_buffer_size 512k; try_files $uri $uri/ /index.php?$args; } }
如果我在 vcl 文件 

X-Static-File 部分添加 return(pass); ,网站可以正常工作,但清漆不会缓存静态文件。有没有人遇到过这个问题。我正在运行 Varnish 7.4

wordpress nginx varnish varnish-vcl varnish-4
1个回答
0
投票
只需从

return (lookup);

 中删除 
vcl_hash
,您的问题就应该得到解决。

通过执行返回,您基本上绕过了 Varnish 对此 VCL 子例程的标准行为。

对于

vcl_hash

,重要的是使用 
req.url
req.http.Host
 作为标识缓存中对象的值。

对于

mydomain.com

www.mydomain.com
,您使用 
X-Forwarded-Proto
 标头值来标识缓存中的对象,但通过执行 
return(lookup)
,URL 和 
Host
 标头值将丢失。

长话短说:从 return(lookup)

 中删除 
vcl_hash

© www.soinside.com 2019 - 2024. All rights reserved.