我正在尝试解决 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
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
。