Skip to content
Snippets Groups Projects
Commit 25896eee authored by jurgenhaas's avatar jurgenhaas
Browse files

ansible-inventories/gentner#2471 Update Varnish configuration

parent 6dfb991e
No related branches found
No related tags found
No related merge requests found
# See Users Guide at https://www.varnish-cache.org/docs/
# See Examples at https://www.varnish-cache.org/trac/wiki/VCLExamples
# Based on: https://github.com/mattiasgeniar/varnish-4.0-configuration-templates/blob/master/default.vcl
vcl 4.0;
# Based on: https://github.com/mattiasgeniar/varnish-6.0-configuration-templates/blob/master/default.vcl
vcl 4.0; # breaks with 4.1
import std;
import directors;
......@@ -28,7 +28,7 @@ backend {{ host }} {
}
{% endfor %}
// Clients that are allowed to purge cache content
// Clients that are allowed to purge cache content.
acl purge {
"localhost";
"127.0.0.1";
......@@ -44,19 +44,31 @@ sub vcl_recv {
}
{% endfor %}
# 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]+", "");
# Called at the beginning of a request, after the complete request has been received and parsed.
# Its purpose is to decide whether or not to serve the request, how to do it, and, if applicable,
# which backend to use.
# also used to modify the request
# Normalize the query arguments
set req.url = std.querysort(req.url);
# Force miss if restarted (sent from vcl_hit).
if (req.restarts > 0) {
set req.hash_always_miss = true;
}
# Normalize the header if it exists, remove the port (in case you're testing this on various TCP ports)
if (req.http.Host) {
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
}
# Remove the proxy header (see https://httpoxy.org/#mitigate-varnish)
unset req.http.proxy;
# Normalize the query arguments
set req.url = std.querysort(req.url);
# Allow purging
if (req.method == "PURGE" || req.method == "BAN") {
# Make sure that HaProxy has been setting the header value x-real-ip properly
if (!std.ip(req.http.x-real-ip, "0.0.0.0") ~ purge) { # purge is the ACL defined at the beginning
if (!client.ip ~ purge) { # purge is the ACL defined at the beginning.
# Not from an allowed IP? Then die with an error.
return (synth(405, "This IP is not allowed to send PURGE or BAN requests."));
}
......@@ -112,16 +124,6 @@ sub vcl_recv {
return (pass);
}
# Health Check
if (req.url == "/varnishcheck") {
return(synth(751, "OK!"));
if (std.healthy(req.backend_hint)) {
return(synth(751, "OK!"));
} else {
return(synth(752, "FAILED!"));
}
}
# Some generic URL manipulation, useful for all templates that follow
# First remove the Google Analytics added parameters, useless for our backend
if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") {
......@@ -142,59 +144,65 @@ sub vcl_recv {
}
# Some generic cookie manipulation, useful for all templates that follow
# Remove the "has_js" cookie
set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
# Don't manipulate empty cookies
if (req.http.Cookie !~ "^\s*$") {
# Remove the "has_js" cookie
set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
# Remove any Google Analytics based cookies
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, "_gat=[^;]+(; )?", "");
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.=[^;]+(; )?", "");
# Remove any Google Analytics based cookies
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, "_gat=[^;]+(; )?", "");
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.=[^;]+(; )?", "");
# Remove DoubleClick offensive cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", "");
# Remove DoubleClick offensive cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", "");
# Remove the Quant Capital cookies (added by some plugin, all __qca)
set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
# Remove the Quant Capital cookies (added by some plugin, all __qca)
set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
# Remove the AddThis cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", "");
# Remove the AddThis cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", "");
# Remove a ";" prefix in the cookie if present
set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
# Remove a ";" prefix in the cookie if present
set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
}
# Are there cookies left with only spaces or that are empty?
if (req.http.cookie ~ "^\s*$") {
unset req.http.cookie;
}
if (req.http.Cache-Control ~ "(?i)no-cache") {
#if (req.http.Cache-Control ~ "(?i)no-cache" && client.ip ~ editors) { # create the acl editors if you want to restrict the Ctrl-F5
# http://varnish.projects.linpro.no/wiki/VCLExampleEnableForceRefresh
# Ignore requests via proxy caches and badly behaved crawlers
# like msnbot that send no-cache with every request.
if (! (req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge)) {
#set req.hash_always_miss = true; # Doesn't seems to refresh the object in the cache
return(purge); # Couple this with restart in vcl_purge and X-Purge header to avoid loops
}
}
#if (req.http.Cache-Control ~ "(?i)no-cache") {
#if (client.ip ~ purge) {
# Ignore requests via proxy caches and badly behaved crawlers
# like msnbot that send no-cache with every request.
#if (! (req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge)) {
#set req.hash_always_miss = true; # Doesn't seems to refresh the object in the cache
#return(purge); # Couple this with restart in vcl_purge and X-Purge header to avoid loops
#}
#}
#}
# Large static files are delivered directly to the end-user without
# waiting for Varnish to fully read the file first.
# Varnish 4 fully supports Streaming, so set do_stream in vcl_backend_response()
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|xz|zip)(\?.*)?$") {
unset req.http.Cookie;
return (hash);
set req.http.X-Static-File = "true";
return (pipe); # Actually do not cache.
}
# Remove all cookies for static files
# A valid discussion could be held on this line: do you really need to cache static files that don't cause load? Only if you have memory left.
# Sure, there's disk I/O, but chances are your OS will already have these files in their buffers (thus memory).
# Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-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)(\?.*)?$") {
# ... we do not want filetypes in this list that we consider to be big.
if (req.url ~ "^[^?]*\.(map|bmp|css|csv|doc|docx|eot|gif|ico|jpeg|jpg|js|less|odt|otf|pdf|png|ppt|pptx|rtf|svg|ttf|txt|txz|webm|webp|woff|woff2|xls|xlsx|xml|xz)(\?.*)?$") {
unset req.http.Cookie;
set req.http.X-Static-File = "true";
return (hash);
}
......@@ -206,7 +214,7 @@ sub vcl_recv {
return (pass);
}
return (hash);
return (pass);
}
sub vcl_pipe {
......@@ -258,6 +266,11 @@ sub vcl_hash {
if (req.http.Cookie) {
hash_data(req.http.Cookie);
}
# Cache the HTTP vs HTTPs separately
if (req.http.X-Forwarded-Proto) {
hash_data(req.http.X-Forwarded-Proto);
}
}
sub vcl_hit {
......@@ -268,29 +281,29 @@ sub vcl_hit {
return (deliver);
}
# https://www.varnish-cache.org/docs/trunk/users-guide/vcl-grace.html
# When several clients are requesting the same page Varnish will send one request to the backend and place the others
# on hold while fetching one copy from the backend. In some products this is called request coalescing and Varnish does
# this automatically.
# If you are serving thousands of hits per second the queue of waiting requests can get huge. There are two potential
# problems - one is a thundering herd problem - suddenly releasing a thousand threads to serve content might send the
# load sky high. Secondly - nobody likes to wait. To deal with this we can instruct Varnish to keep the objects in cache
# beyond their TTL and to serve the waiting requests somewhat stale content.
# We have no fresh fish. Lets look at the stale ones.
if (std.healthy(req.backend_hint)) {
# Backend is healthy. Limit age to 10s.
if (obj.ttl + 10s > 0s) {
#set req.http.grace = "normal(limited)";
return (deliver);
} else {
# No candidate for grace. Fetch a fresh object.
return(miss);
}
} else {
# backend is sick - use full grace
if (obj.ttl + obj.grace > 0s) {
if (obj.ttl + obj.grace > 0s) {
#set req.http.grace = "full";
return (deliver);
} else {
# no graced object.
return (miss);
}
}
# fetch & deliver once we get the result
return (miss); # Dead code, keep as a safeguard
}
sub vcl_miss {
......@@ -337,6 +350,7 @@ sub vcl_backend_response {
}
# Disable buffering only for BigPipe responses
# https://www.drupal.org/docs/8/core/modules/big-pipe/bigpipe-environment-requirements
if (beresp.http.Surrogate-Control ~ "BigPipe/1.0") {
set beresp.grace = 6h;
set beresp.do_stream = true;
......@@ -400,10 +414,8 @@ sub vcl_deliver {
sub vcl_purge {
# Only handle actual PURGE HTTP methods, everything else is discarded
if (req.method != "PURGE") {
# restart request
if (req.method == "PURGE") {
set req.http.X-Purge = "Yes";
return(restart);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment