2016-12-17 34 views
0

我們目前在我們的服務器上配置Varnish。這是一團糟......如何從光油返回的響應中排除PHPSSID

我們遇到了一些與清漆的困難。事實上,當我們返回未緩存頁面的響應時,varnish會在響應中系統地包含當前用戶的PHPSSID。當另一個用戶問至極被緩存的頁面,他inherites外國用戶的PHPSSSID的...

vcl 4.0; 

include "includes/devicedetect.vcl"; 

import std; 

backend local { 
    .host = "127.0.0.1"; 
    .port = "80"; 
    .connect_timeout = 5s; 
    .first_byte_timeout = 300s; 
    .between_bytes_timeout = 300s; 
} 

acl purge { 
    # ACL we'll use later to allow purges 
    # web01 
    # web02 
    "localhost"; 
    "127.0.0.1"; 
} 


sub vcl_recv { 
    # Disable all 
    # return (pass); 

    # Allow purging 
    if (req.method == "PURGE") { 
     if (!std.ip(regsub(req.http.X-Forwarded-For, "[, ].*$", ""), client.ip) ~ purge) { 
      # Not from an allowed IP? Then die with an error. 
      return (synth(405, "This IP is not allowed to send PURGE requests.")); 
     } 
     # If you got this stage (and didn't error out above), purge the cached result 
     return (purge); 
    } 

    # Allow ban (global purge) 
    if (req.method == "BAN") { 
     if (!std.ip(regsub(req.http.X-Forwarded-For, "[, ].*$", ""), client.ip) ~ purge) { 
      # Not from an allowed IP? Then die with an error. 
      return (synth(405, "This IP is not allowed to send BAN requests.")); 
     } 
     # If you got this stage (and didn't error out above), purge the cached result 
     ban("obj.http.x-url ~ /"); 
     return (synth(200, "Ban added")); 
    } 

    # Only cache GET or HEAD requests. This makes sure the POST requests are always passed. 
    if (req.method != "GET" && req.method != "HEAD") { 
     return (pass); 
    } 

    if (req.http.Authorization) { 
     return (pass); 
    } 

    if (req.http.host ~ "(api\.domain\.com|api2\.domain\.com)") { 
     return (pass); 
    } 

    # Do not cache logout/login/forgot password url 
    if (req.url ~ "/(logout|forgotten-password|login|register|facebookLogin)") { 
    return (pass); 
    } 

    # Do not cache when Set-Cookie contain user[id] OR identity OR PHPSESSID OR PHPSERVERID 
    if (req.http.Set-Cookie ~ "(user\[id\]|identity|SERVERID)") { 
     return (pass); 
    } 

    # Do not cache customer french page 
    if (req.url ~ "/fr/(client|personnaliser|panier)") { 
     return (pass); 
    } 

    # Do not cache customer english page 
    if (req.url ~ "/en/(customer|personalize|cart)") { 
     return (pass); 
    } 

    # Do not cache checkout 
    if (req.url ~ "/checkout") { 
     return (pass); 
    } 

    # Normalize the header, remove the port (in case you're testing this on various TCP ports) 
    set req.http.Host = regsub(req.http.Host, ":[0-9]+", ""); 

    # Remove the proxy header (see https://httpoxy.org/#mitigate-varnish) 
    unset req.http.proxy; 

    # Strip hash, server doesn't need it. 
    if (req.url ~ "\#") { 
     set req.url = regsub(req.url, "\#.*$", ""); 
    }  

    # Strip a trailing ? if it exists 
    if (req.url ~ "\?$") { 
     set req.url = regsub(req.url, "\?$", ""); 
    } 

    # Normalize the query arguments 
    # set req.url = std.querysort(req.url); 

    # Remove the backend cache parameter for pagination 
    if (req.url ~ "(\&|\?)_=[0-9]+$") { 
     set req.url = regsub(req.url, "(\&|\?)_=[0-9]+$", ""); 
    } 

    # Cache 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|otf|ogg|ogm|opus|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.Cookie; 
     return (hash); 
    } 

    # Mobile Detection set req.http.X-UA-Device 
    call devicedetect; 

    # Normalize accept-encoding 
    if (req.http.Accept-Encoding) { 
     if (req.http.Accept-Encoding ~ "gzip") { 
      set req.http.Accept-Encoding = "gzip"; 
     } elsif (req.http.Accept-Encoding ~ "deflate") { 
      set req.http.Accept-Encoding = "deflate"; 
     } else { 
      unset req.http.Accept-Encoding; 
     } 
    } 

    # Send Surrogate-Capability headers to announce ESI support to backend 
    set req.http.Surrogate-Capability = "abc=ESI/1.0"; 

    if (req.http.cookie ~ "id_devise=") { 
     set req.http.Devise = regsuball(req.http.cookie, "(.*?)(id_devise=[^;]*)(.*)$", "\2"); 
    } 

    if (req.http.cookie ~ "id_mesure=") { 
     set req.http.Mesure = regsuball(req.http.cookie, "(.*?)(id_mesure=[^;]*)(.*)$", "\2"); 
    } 

    # Cache the rest 
    return (hash); 
} 

sub vcl_backend_response { 
    if (bereq.http.X-UA-Device) { 
     if (!beresp.http.Vary) { # no Vary at all 
      set beresp.http.Vary = "X-UA-Device"; 
     } elsif (beresp.http.Vary !~ "X-UA-Device") { # add to existing Vary 
      set beresp.http.Vary = beresp.http.Vary + ", X-UA-Device"; 
     } 
    } 

    if (bereq.url ~ "/esi/" || bereq.url ~ "checkout" || bereq.url ~ "/fr/(client|personnaliser)" || bereq.url ~ "/en/(customer|personalize)") { 
     unset beresp.http.Surrogate-Control; 
     set beresp.ttl = 0s; 
    } else { 
     set beresp.do_esi = true; 
     set beresp.ttl = 10m; 
    } 

    set beresp.grace = 6h; 

    return (deliver); 
} 

sub vcl_backend_error { 
    if (beresp.status == 503) { 
     set beresp.http.Content-Type = "text/html; charset=utf-8"; 
     synthetic(std.fileread("/home/domain/www/503.html")); 
     return(deliver); 
    } 
    if (beresp.status == 500) { 
     set beresp.http.Content-Type = "text/html; charset=utf-8"; 
     synthetic(std.fileread("/home/domain/www/500.html")); 
     return(deliver); 
    } 
} 

sub vcl_hash { 
    hash_data(req.url); 

    if (req.http.host) { 
     hash_data(req.http.host); 
    } else { 
     hash_data(server.ip); 
    } 

    if (req.http.Devise) { 
     hash_data(req.http.Devise); 
    } 

    if (req.http.Mesure) { 
     hash_data(req.http.Mesure); 
    } 

    if (req.http.X-Requested-With) { 
     hash_data(req.http.X-Requested-With); 
    } 

    hash_data(req.http.cookie); 

    return (lookup); 
} 

sub vcl_hit { 
    if (obj.ttl == 0s) { 
     return (fetch); 
    } else if (obj.ttl >= 0s) { 
     return (deliver); 
    } 

    if (!std.healthy(req.backend_hint)) { 
     # backend is sick - use full grace 
     if (obj.ttl + obj.grace > 0s) { 
      return (deliver); 
     } 
    } 

    return (fetch); 
} 

sub vcl_deliver { 
    if (obj.hits > 0) { 
     set resp.http.X-Cache = "HIT"; 
    } else { 
     set resp.http.X-Cache = "MISS"; 
    } 

    if ((req.http.X-UA-Device) && (resp.http.Vary)) { 
     set resp.http.Vary = regsub(resp.http.Vary, "X-UA-Device", "User-Agent"); 
    } 

    set resp.http.X-Cache-Hits = obj.hits; 

    unset resp.http.X-Powered-By; 
    unset resp.http.Server; 
    unset resp.http.X-Drupal-Cache; 
    unset resp.http.X-Varnish; 
    unset resp.http.Via; 
    unset resp.http.Link; 
    unset resp.http.X-Generator; 

    return (deliver); 
} 

sub vcl_pipe { 
    set bereq.http.Connection = "Close"; 

    return (pipe); 
} 

sub vcl_pass { 
    return (fetch); 
} 

sub vcl_purge { 
    # Only handle actual PURGE HTTP methods, everything else is discarded 
    if (req.method != "PURGE") { 
     # restart request 
     set req.http.X-Purge = "Yes"; 
     return(restart); 
    } 
} 

sub vcl_synth { 
    if (resp.status == 720) { 
     # We use this special error status 720 to force redirects with 301 (permanent) redirects 
     # To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html")); 
     set resp.http.Location = resp.reason; 
     set resp.status = 301; 
     return (deliver); 
    } elseif (resp.status == 721) { 
     # And we use error status 721 to force redirects with a 302 (temporary) redirect 
     # To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html")); 
     set resp.http.Location = resp.reason; 
     set resp.status = 302; 
     return (deliver); 
    } 

    return (deliver); 
} 

回答

0

1)默認情況下,清漆不緩存裏面設置一個cookie的任何響應:

sub vcl_backend_response { 
    if (beresp.ttl <= 0s || 
     beresp.http.Set-Cookie || 
     beresp.http.Surrogate-control ~ "no-store" || 
     (!beresp.http.Surrogate-Control && 
     beresp.http.Cache-Control ~ "no-cache|no-store|private") || 
     beresp.http.Vary == "*") { 
     /* 
     * Mark as "Hit-For-Pass" for the next 2 minutes 
     */ 
     set beresp.ttl = 120s; 
     set beresp.uncacheable = true; 
    } 
    return (deliver); 
} 

請參閱https://github.com/varnish/Varnish-Cache/blob/4.1/bin/varnishd/builtin.vcl

在您的「sub vcl_backend_response」中,您總是「返回(遞送)」。這意味着Vnish內置的VCL從未被執行。只要刪除「返回(交付)」;「從你自己的「sub vcl_backend_response」,事情應該會變得更好。

2)設置Cookie是respose頭,而不是一個請求頭所以這沒有意義,我

# Do not cache when Set-Cookie contain user[id] OR identity OR PHPSESSID OR PHPSERVERID 
if (req.http.Set-Cookie ~ "(user\[id\]|identity|SERVERID)") { 
    return (pass); 
} 

3)一般情況下,你不應該總是稱之爲「迴歸」在你自己的版本「vcl_ *」,因爲它總是會阻止內建的VCL(具有合理的默認行爲)被執行。例如,你不應該調用「return(hash)」;「在「vcl_receive」的末尾。如果你不這樣做,你就不需要這樣的東西

if (req.method != "GET" && req.method != "HEAD") { 
    return (pass); 
} 

if (req.http.Authorization) { 
    return (pass); 
} 
在「vcl_receive」

,因爲這也將在內置的版本進行處理。

4)另外你的「sub vcl_hash」對我來說看起來很狡猾。我永遠都不會喜歡你的cookies哈希做:

hash_data(req.http.cookie); 

默認情況下,清漆不緩存其中有一個Cookie的任何請求 - 也看到了builtin.vcl

if (req.http.Authorization || req.http.Cookie) { 
     /* Not cacheable by default */ 
     return (pass); 
} 

這就是爲什麼通常你刪除任何您自己的「vcl_receive」中的Cookie用於您希望Varnish緩存的請求,就像您對靜態文件所做的一樣。

所以是的 - 這是一個混亂。