Add HAProxy and Varnbish config files
This commit is contained in:
parent
317f313394
commit
d3c04a31ea
17 changed files with 1122 additions and 0 deletions
268
etc/haproxy/haproxy.cfg
Normal file
268
etc/haproxy/haproxy.cfg
Normal file
|
@ -0,0 +1,268 @@
|
|||
# Inspired by https://gist.github.com/haproxytechblog/dc5c3b5e2801d36b79e00f07b2309c14
|
||||
|
||||
global
|
||||
log /dev/log local0
|
||||
log /dev/log local1 notice
|
||||
chroot /var/lib/haproxy
|
||||
stats socket /run/haproxy/admin.sock mode 660 level admin
|
||||
stats timeout 30s
|
||||
user haproxy
|
||||
group haproxy
|
||||
daemon
|
||||
|
||||
node my-hostname
|
||||
|
||||
server-state-file /var/lib/haproxy/server_state.txt
|
||||
|
||||
maxconn 60000
|
||||
|
||||
# Default SSL material locations
|
||||
ca-base /etc/ssl/certs
|
||||
crt-base /etc/ssl/private
|
||||
|
||||
# generated 2021-05-03, Mozilla Guideline v5.6, HAProxy 2.2, OpenSSL 1.1.1d, intermediate configuration
|
||||
# https://ssl-config.mozilla.org/#server=haproxy&version=2.2&config=intermediate&openssl=1.1.1d&guideline=5.6
|
||||
ssl-default-bind-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
|
||||
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
|
||||
ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
|
||||
|
||||
ssl-default-server-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
|
||||
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
|
||||
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
|
||||
|
||||
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/ssl/dhparam-haproxy
|
||||
ssl-dh-param-file /etc/ssl/dhparam-haproxy
|
||||
|
||||
defaults
|
||||
log global
|
||||
|
||||
mode http
|
||||
|
||||
option httplog
|
||||
option dontlognull
|
||||
option log-separate-errors
|
||||
option httpclose
|
||||
option abortonclose
|
||||
option http-server-close
|
||||
option redispatch
|
||||
|
||||
timeout connect 5s
|
||||
|
||||
timeout client 300s
|
||||
timeout server 300s
|
||||
|
||||
timeout queue 60s
|
||||
timeout http-request 15s
|
||||
|
||||
load-server-state-from-file global
|
||||
|
||||
maxconn 50000
|
||||
|
||||
# Default options for "server" directive in backends
|
||||
default-server maxconn 2000 on-error fail-check slowstart 60s inter 5s fastinter 1s downinter 1s weight 100 fall 3 rise 2
|
||||
|
||||
http-errors boost-default-errors
|
||||
errorfile 400 /etc/haproxy/errors/400.http
|
||||
errorfile 403 /etc/haproxy/errors/403.http
|
||||
errorfile 408 /etc/haproxy/errors/408.http
|
||||
errorfile 500 /etc/haproxy/errors/500.http
|
||||
errorfile 502 /etc/haproxy/errors/502.http
|
||||
errorfile 503 /etc/haproxy/errors/503.http
|
||||
errorfile 504 /etc/haproxy/errors/504.http
|
||||
|
||||
resolvers local_dns
|
||||
parse-resolv-conf
|
||||
resolve_retries 3
|
||||
timeout resolve 1s
|
||||
timeout retry 1s
|
||||
hold other 30s
|
||||
hold refused 30s
|
||||
hold nx 30s
|
||||
hold timeout 30s
|
||||
hold valid 10s
|
||||
hold obsolete 30s
|
||||
|
||||
userlist example-dev_team
|
||||
user dev1 insecure-password ItyecpotHeHagAcukfoGrynPeawdEyb2
|
||||
user dev2 insecure-password 8owEkecharhiedyarOwcebcheimeObBa
|
||||
|
||||
listen stats
|
||||
mode http
|
||||
bind *:8080 ssl crt /etc/haproxy/ssl/
|
||||
bind 127.0.0.1:8081
|
||||
|
||||
acl stats_access_ips src -f /etc/haproxy/stats_access_ips
|
||||
acl stats_admin_ips src -f /etc/haproxy/stats_admin_ips
|
||||
|
||||
stats enable
|
||||
stats refresh 10s
|
||||
stats uri /
|
||||
stats show-legends
|
||||
stats show-node
|
||||
stats admin if stats_admin_ips
|
||||
|
||||
stats http-request deny if !stats_access_ips
|
||||
|
||||
http-request set-log-level silent
|
||||
|
||||
frontend external
|
||||
bind 0.0.0.0:80,:::80
|
||||
bind 0.0.0.0:443,:::443 ssl strict-sni alpn h2,http/1.1 crt /etc/haproxy/ssl
|
||||
|
||||
capture request header Host len 32
|
||||
|
||||
option forwardfor
|
||||
|
||||
errorfiles boost-default-errors
|
||||
|
||||
# Is the request coming for the server itself (stats…)
|
||||
acl server_hostname hdr(host) -i my-hostname
|
||||
acl munin hdr(host) -i munin
|
||||
|
||||
# List of IP that will not go the maintenance backend
|
||||
acl maintenance_ips src -f /etc/haproxy/maintenance_ips
|
||||
|
||||
# Detect Let's Encrypt challenge requests
|
||||
acl letsencrypt path_dir -i /.well-known/acme-challenge
|
||||
|
||||
# Determine if the request is routable to Varnish
|
||||
acl varnish_available nbsrv(varnish) gt 0
|
||||
acl varnish_detected res.hdr(X-Varnish) -m found
|
||||
acl varnish_http_verb method GET HEAD PURGE
|
||||
|
||||
# Reject the request at the TCP level if source is in the denylist
|
||||
tcp-request connection reject if { src -f /etc/haproxy/deny_ips }
|
||||
|
||||
http-request set-header X-Forwarded-Port %[dst_port]
|
||||
# Set header if not coming from Varnish
|
||||
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
|
||||
http-request set-header X-Forwarded-Proto https if { ssl_fc }
|
||||
|
||||
# BEGIN HTTP tagging
|
||||
http-request set-header X-Unique-ID %[uuid()] unless { hdr(X-Unique-ID) -m found }
|
||||
http-request add-header X-Boost-Step1 haproxy-external
|
||||
|
||||
http-response add-header X-Boost-Step1 "haproxy-external; client-https" if { ssl_fc }
|
||||
http-response add-header X-Boost-Step1 "haproxy-external; client-http" if !{ ssl_fc }
|
||||
http-response set-header X-Boost-Server {{ ansible_hostname }}
|
||||
|
||||
# Debug: Enable this to add a full log line in the response
|
||||
### http-response add-header X-Haproxy-Log-external "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
|
||||
# END HTTP tagging
|
||||
|
||||
# Global maintenance mode (### -> uncomment)
|
||||
### use_backend maintenance unless maintenance_ips
|
||||
|
||||
use_backend local if server_hostname
|
||||
use_backend local if munin
|
||||
|
||||
# "letsencrypt" must stay after "local"
|
||||
use_backend letsencrypt if letsencrypt
|
||||
|
||||
# BEGIN frontend_external section for site 'example'
|
||||
acl example_domains hdr(host) -i example.com
|
||||
acl example_domains2 hdr(host) -i example.org www.example.org
|
||||
### acl example_maintenance_ips src -f /etc/haproxy/example/maintenance_ips
|
||||
|
||||
# Redirect to HTTPS without Let's Encrypt certificate
|
||||
### redirect scheme https code 301 if example_domains !{ ssl_fc }
|
||||
|
||||
# Redirect to HTTPS with Let's Encrypt certificate (exclude LE challenge from redirection)
|
||||
### redirect scheme https code 301 if example_domains !{ ssl_fc } !letsencrypt
|
||||
|
||||
# Redirect a domain to another without Let's encrypt certificate
|
||||
### redirect prefix https://example-to.org code 301 if { hdr(host) -i example-from.org }
|
||||
|
||||
# Redirect a domain to another with a Let's encrypt certificate (exclude Let's Enrypt challenge from redirection)
|
||||
### redirect prefix https://example-to.org code 301 if { hdr(host) -i example-from.org } !letsencrypt
|
||||
|
||||
# HSTS (31536000 seconds = 1 year)
|
||||
### http-response set-header Strict-Transport-Security max-age=31536000 if example_domains
|
||||
|
||||
# custom directives, all conditionned by at least the "example_domains" ACL
|
||||
### http-request deny if example_domains { src 1.2.3.4 }
|
||||
|
||||
# routing directives, all conditionned by (at least) the "example_domains" ACL
|
||||
# Maintenance mode (### -> uncomment BUT define example_maintenance_ips acl before)
|
||||
### use_backend example_maintenance if example_domains !example_maintenance_ips !maintenance_ips
|
||||
|
||||
# Use Varnish if available
|
||||
use_backend varnish if example_domains varnish_available varnish_http_verb
|
||||
|
||||
# … or use normal backend
|
||||
use_backend example if example_domains
|
||||
# END frontend_external section for site 'example'
|
||||
|
||||
default_backend goto_internal
|
||||
|
||||
# This is used as a fallback to go to the internal frontend
|
||||
# This is not supposed to happen
|
||||
backend goto_internal
|
||||
server haproxy-internal /run/haproxy-frontend-default.sock send-proxy-v2
|
||||
|
||||
# This frontend is only used when returning from varnish
|
||||
frontend internal
|
||||
bind /run/haproxy-frontend-default.sock user root mode 666 accept-proxy
|
||||
|
||||
capture request header Host len 32
|
||||
|
||||
option forwardfor
|
||||
|
||||
# Check URL (used by Varnish)
|
||||
monitor-uri /haproxycheck
|
||||
|
||||
acl varnish_from hdr(X-Varnish) -m found
|
||||
acl forwarded_proto hdr(x-forwarded-proto) -m found
|
||||
|
||||
# Keep header if present and coming from Varnish
|
||||
http-request set-header X-Forwarded-Proto %[hdr(x-forwarded-proto)] if forwarded_proto varnish_from
|
||||
|
||||
# BEGIN HTTP tagging
|
||||
http-request add-header X-Boost-Step3 haproxy-internal
|
||||
|
||||
http-response add-header X-Boost-Step3 "haproxy-internal; SSL to backend" if { ssl_bc }
|
||||
http-response add-header X-Boost-Step3 "haproxy-internal; no SSL to backend" if !{ ssl_bc }
|
||||
|
||||
# Debug: Enable this to add a full log line in the response
|
||||
### http-response add-header X-Haproxy-Log-Internal "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
|
||||
# END HTTP tagging
|
||||
|
||||
# BEGIN frontend_internal section for site 'example'
|
||||
acl example_domains hdr(host) -i example.com
|
||||
|
||||
# routing directives, all conditionned by (at least) the "example_domains" ACL
|
||||
use_backend example if example_domains
|
||||
# END frontend_internal section for site 'example'
|
||||
|
||||
|
||||
backend varnish
|
||||
option httpchk HEAD /varnishcheck
|
||||
server varnish_sock /run/varnish.sock check observe layer7 maxconn 3000 inter 1s send-proxy-v2
|
||||
|
||||
# BEGIN backend section for site 'example'
|
||||
backend example
|
||||
errorfile 503 /etc/haproxy/sites/example/maintenance.http
|
||||
http-response set-header X-Boost-Proto https if { ssl_bc }
|
||||
http-response set-header X-Boost-Proto http if !{ ssl_bc }
|
||||
server example-hostname 1.2.3.4:443 check observe layer4 ssl verify none
|
||||
|
||||
backend example_maintenance
|
||||
http-request set-log-level silent
|
||||
errorfile 503 /etc/haproxy/sites/example/maintenance.http
|
||||
# END backend section for site 'example'
|
||||
|
||||
|
||||
backend letsencrypt
|
||||
# Use this if the challenge is managed locally
|
||||
server localhost 127.0.0.1:81 send-proxy-v2 maxconn 10
|
||||
# Use this if the challenge is managed remotely
|
||||
### server my-certbot-challenge-manager 192.168.2.1:80 maxconn 10
|
||||
|
||||
|
||||
backend local
|
||||
option httpchk HEAD /haproxy-check
|
||||
server localhost 127.0.0.1:81 send-proxy-v2 maxconn 10
|
||||
|
||||
backend maintenance
|
||||
http-request set-log-level silent
|
||||
errorfile 503 /etc/haproxy/errors/maintenance.http
|
3
etc/systemd/system/varnish.service.d/evolinux.conf
Normal file
3
etc/systemd/system/varnish.service.d/evolinux.conf
Normal file
|
@ -0,0 +1,3 @@
|
|||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/sbin/varnishd -F -j unix,user=vcache -a /var/lib/haproxy/run/varnish.sock,user=vcache,group=varnish,mode=666,PROXY -a 127.0.0.1:82 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,24G -p thread_pools=4 -p thread_pool_add_delay=0 -p thread_pool_min=500 -p thread_pool_max=5000
|
12
etc/varnish/conf.d/builtin.backend_response.vcl
Normal file
12
etc/varnish/conf.d/builtin.backend_response.vcl
Normal file
|
@ -0,0 +1,12 @@
|
|||
if (bereq.uncacheable) {
|
||||
return (deliver);
|
||||
} else 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-Miss" for the next 2 minutes
|
||||
set beresp.ttl = 120s;
|
||||
set beresp.uncacheable = true;
|
||||
}
|
200
etc/varnish/conf.d/builtin.complete.vcl
Normal file
200
etc/varnish/conf.d/builtin.complete.vcl
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*-
|
||||
* Copyright (c) 2006 Verdens Gang AS
|
||||
* Copyright (c) 2006-2015 Varnish Software AS
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This is the builtin VCL code
|
||||
*/
|
||||
|
||||
vcl 4.0;
|
||||
|
||||
#######################################################################
|
||||
# Client side
|
||||
|
||||
sub vcl_recv {
|
||||
if (req.method == "PRI") {
|
||||
/* This will never happen in properly formed traffic (see: RFC7540) */
|
||||
return (synth(405));
|
||||
}
|
||||
if (!req.http.host &&
|
||||
req.esi_level == 0 &&
|
||||
req.proto ~ "^(?i)HTTP/1.1") {
|
||||
/* In HTTP/1.1, Host is required. */
|
||||
return (synth(400));
|
||||
}
|
||||
if (req.method != "GET" &&
|
||||
req.method != "HEAD" &&
|
||||
req.method != "PUT" &&
|
||||
req.method != "POST" &&
|
||||
req.method != "TRACE" &&
|
||||
req.method != "OPTIONS" &&
|
||||
req.method != "DELETE" &&
|
||||
req.method != "PATCH") {
|
||||
/* Non-RFC2616 or CONNECT which is weird. */
|
||||
return (pipe);
|
||||
}
|
||||
|
||||
if (req.method != "GET" && req.method != "HEAD") {
|
||||
/* We only deal with GET and HEAD by default */
|
||||
return (pass);
|
||||
}
|
||||
if (req.http.Authorization || req.http.Cookie) {
|
||||
/* Not cacheable by default */
|
||||
return (pass);
|
||||
}
|
||||
return (hash);
|
||||
}
|
||||
|
||||
sub vcl_pipe {
|
||||
# By default Connection: close is set on all piped requests, to stop
|
||||
# connection reuse from sending future requests directly to the
|
||||
# (potentially) wrong backend. If you do want this to happen, you can undo
|
||||
# it here.
|
||||
# unset bereq.http.connection;
|
||||
return (pipe);
|
||||
}
|
||||
|
||||
sub vcl_pass {
|
||||
return (fetch);
|
||||
}
|
||||
|
||||
sub vcl_hash {
|
||||
hash_data(req.url);
|
||||
if (req.http.host) {
|
||||
hash_data(req.http.host);
|
||||
} else {
|
||||
hash_data(server.ip);
|
||||
}
|
||||
return (lookup);
|
||||
}
|
||||
|
||||
sub vcl_purge {
|
||||
return (synth(200, "Purged"));
|
||||
}
|
||||
|
||||
sub vcl_hit {
|
||||
if (obj.ttl >= 0s) {
|
||||
// A pure unadulterated hit, deliver it
|
||||
return (deliver);
|
||||
}
|
||||
if (obj.ttl + obj.grace > 0s) {
|
||||
// Object is in grace, deliver it
|
||||
// Automatically triggers a background fetch
|
||||
return (deliver);
|
||||
}
|
||||
// fetch & deliver once we get the result
|
||||
return (miss);
|
||||
}
|
||||
|
||||
sub vcl_miss {
|
||||
return (fetch);
|
||||
}
|
||||
|
||||
sub vcl_deliver {
|
||||
return (deliver);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can come here "invisibly" with the following errors: 500 & 503
|
||||
*/
|
||||
sub vcl_synth {
|
||||
set resp.http.Content-Type = "text/html; charset=utf-8";
|
||||
set resp.http.Retry-After = "5";
|
||||
set resp.body = {"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>"} + resp.status + " " + resp.reason + {"</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Error "} + resp.status + " " + resp.reason + {"</h1>
|
||||
<p>"} + resp.reason + {"</p>
|
||||
<h3>Guru Meditation:</h3>
|
||||
<p>XID: "} + req.xid + {"</p>
|
||||
<hr>
|
||||
<p>Varnish cache server</p>
|
||||
</body>
|
||||
</html>
|
||||
"};
|
||||
return (deliver);
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Backend Fetch
|
||||
|
||||
sub vcl_backend_fetch {
|
||||
if (bereq.method == "GET") {
|
||||
unset bereq.body;
|
||||
}
|
||||
return (fetch);
|
||||
}
|
||||
|
||||
sub vcl_backend_response {
|
||||
if (bereq.uncacheable) {
|
||||
return (deliver);
|
||||
} else 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-Miss" for the next 2 minutes
|
||||
set beresp.ttl = 120s;
|
||||
set beresp.uncacheable = true;
|
||||
}
|
||||
return (deliver);
|
||||
}
|
||||
|
||||
sub vcl_backend_error {
|
||||
set beresp.http.Content-Type = "text/html; charset=utf-8";
|
||||
set beresp.http.Retry-After = "5";
|
||||
set beresp.body = {"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>"} + beresp.status + " " + beresp.reason + {"</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
|
||||
<p>"} + beresp.reason + {"</p>
|
||||
<h3>Guru Meditation:</h3>
|
||||
<p>XID: "} + bereq.xid + {"</p>
|
||||
<hr>
|
||||
<p>Varnish cache server</p>
|
||||
</body>
|
||||
</html>
|
||||
"};
|
||||
return (deliver);
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Housekeeping
|
||||
|
||||
sub vcl_init {
|
||||
return (ok);
|
||||
}
|
||||
|
||||
sub vcl_fini {
|
||||
return (ok);
|
||||
}
|
29
etc/varnish/conf.d/builtin.recv.vcl
Normal file
29
etc/varnish/conf.d/builtin.recv.vcl
Normal file
|
@ -0,0 +1,29 @@
|
|||
if (req.method == "PRI") {
|
||||
/* This will never happen in properly formed traffic (see: RFC7540) */
|
||||
return (synth(405));
|
||||
}
|
||||
if (!req.http.host &&
|
||||
req.esi_level == 0 &&
|
||||
req.proto ~ "^(?i)HTTP/1.1") {
|
||||
/* In HTTP/1.1, Host is required. */
|
||||
return (synth(400));
|
||||
}
|
||||
if (req.method != "GET" &&
|
||||
req.method != "HEAD" &&
|
||||
req.method != "PUT" &&
|
||||
req.method != "POST" &&
|
||||
req.method != "TRACE" &&
|
||||
req.method != "OPTIONS" &&
|
||||
req.method != "DELETE" &&
|
||||
req.method != "PATCH") {
|
||||
/* Non-RFC2616 or CONNECT which is weird. */
|
||||
return (pipe);
|
||||
}
|
||||
if (req.method != "GET" && req.method != "HEAD") {
|
||||
/* We only deal with GET and HEAD by default */
|
||||
return (pass);
|
||||
}
|
||||
if (req.http.Authorization || req.http.Cookie) {
|
||||
/* Not cacheable by default */
|
||||
return (pass);
|
||||
}
|
7
etc/varnish/conf.d/cleanup_requests_static.recv.vcl
Normal file
7
etc/varnish/conf.d/cleanup_requests_static.recv.vcl
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Cleanup requests on static binary files and force serving from cache.
|
||||
if (req.url ~ "\.(jpe?g|png|gif|ico|swf|gz|zip|rar|bz2|tgz|tbz|pdf|pls|torrent|mp4)(\?.*|)$") {
|
||||
unset req.http.Authenticate;
|
||||
unset req.http.POSTDATA;
|
||||
unset req.http.cookie;
|
||||
#set req.method = "GET";
|
||||
}
|
19
etc/varnish/conf.d/default_ttl.backend_response.vcl
Normal file
19
etc/varnish/conf.d/default_ttl.backend_response.vcl
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Low TTL for objects with an error response code.
|
||||
if (beresp.status == 403 || beresp.status == 404 || beresp.status >= 500) {
|
||||
set beresp.ttl = 10s;
|
||||
# mark as "hit_for_pass" for 10s
|
||||
#set beresp.uncacheable = false;
|
||||
return(deliver);
|
||||
}
|
||||
|
||||
set beresp.http.foo-bar "BAZ"
|
||||
|
||||
# Default TTL if the backend does not send any header.
|
||||
if (!beresp.http.Cache-Control) {
|
||||
set beresp.ttl = 1d;
|
||||
}
|
||||
|
||||
# Exceptions
|
||||
if (bereq.url ~ "\.(rss|xml|atom)(\?.*|)$") {
|
||||
set beresp.ttl = 2h;
|
||||
}
|
18
etc/varnish/conf.d/devicedetect.backend_response.vcl
Normal file
18
etc/varnish/conf.d/devicedetect.backend_response.vcl
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
# so, this is a bit counterintuitive. The backend creates content based on
|
||||
# the normalized User-Agent, but we use Vary on X-UA-Device so Varnish will
|
||||
# use the same cached object for all U-As that map to the same X-UA-Device.
|
||||
#
|
||||
# If the backend does not mention in Vary that it has crafted special
|
||||
# content based on the User-Agent (==X-UA-Device), add it.
|
||||
# If your backend does set Vary: User-Agent, you may have to remove that here.
|
||||
if (bereq.http.X-UA-Device) {
|
||||
if (!beresp.http.Vary) { # no Vary at all
|
||||
set beresp.http.Vary = "X-UA-Device";
|
||||
} elseif (beresp.http.Vary !~ "X-UA-Device") { # add to existing Vary
|
||||
set beresp.http.Vary = beresp.http.Vary + ", X-UA-Device";
|
||||
}
|
||||
}
|
||||
# comment this out if you don't want the client to know your
|
||||
# classification
|
||||
set beresp.http.X-UA-Device = bereq.http.X-UA-Device;
|
5
etc/varnish/conf.d/devicedetect.deliver.vcl
Normal file
5
etc/varnish/conf.d/devicedetect.deliver.vcl
Normal file
|
@ -0,0 +1,5 @@
|
|||
# to keep any caches in the wild from serving wrong content to client #2
|
||||
# behind them, we need to transform the Vary on the way out.
|
||||
if ((req.http.X-UA-Device) && (resp.http.Vary)) {
|
||||
set resp.http.Vary = regsub(resp.http.Vary, "X-UA-Device", "User-Agent");
|
||||
}
|
113
etc/varnish/conf.d/devicedetect.functions.vcl
Normal file
113
etc/varnish/conf.d/devicedetect.functions.vcl
Normal file
|
@ -0,0 +1,113 @@
|
|||
#
|
||||
# Copyright (c) 2016-2018 Varnish Cache project
|
||||
# Copyright (c) 2012-2016 Varnish Software AS
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# detectdevice.vcl - regex based device detection for Varnish
|
||||
# https://github.com/varnishcache/varnish-devicedetect/
|
||||
#
|
||||
# Original author: Lasse Karstensen <lkarsten@varnish-software.com>
|
||||
|
||||
sub devicedetect {
|
||||
unset req.http.X-UA-Device;
|
||||
set req.http.X-UA-Device = "pc";
|
||||
|
||||
# Handle that a cookie may override the detection alltogether.
|
||||
if (req.http.Cookie ~ "(?i)X-UA-Device-force") {
|
||||
/* ;?? means zero or one ;, non-greedy to match the first. */
|
||||
set req.http.X-UA-Device = regsub(req.http.Cookie, "(?i).*X-UA-Device-force=([^;]+);??.*", "\1");
|
||||
/* Clean up our mess in the cookie header */
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *X-UA-Device-force=[^;]+;? *", "\1");
|
||||
/* If the cookie header is now empty, or just whitespace, unset it. */
|
||||
if (req.http.Cookie ~ "^ *$") { unset req.http.Cookie; }
|
||||
} else {
|
||||
if (req.http.User-Agent ~ "\(compatible; Googlebot-Mobile/2.1; \+http://www.google.com/bot.html\)" ||
|
||||
(req.http.User-Agent ~ "(Android|iPhone)" && req.http.User-Agent ~ "\(compatible.?; Googlebot/2.1.?; \+http://www.google.com/bot.html") ||
|
||||
(req.http.User-Agent ~ "(iPhone|Windows Phone)" && req.http.User-Agent ~ "\(compatible; bingbot/2.0; \+http://www.bing.com/bingbot.htm")) {
|
||||
set req.http.X-UA-Device = "mobile-bot"; }
|
||||
elsif (req.http.User-Agent ~ "(?i)(ads|google|bing|msn|yandex|baidu|ro|career|seznam|)bot" ||
|
||||
req.http.User-Agent ~ "(?i)(baidu|jike|symantec)spider" ||
|
||||
req.http.User-Agent ~ "(?i)pingdom" ||
|
||||
req.http.User-Agent ~ "(?i)facebookexternalhit" ||
|
||||
req.http.User-Agent ~ "(?i)scanner" ||
|
||||
req.http.User-Agent ~ "(?i)slurp" ||
|
||||
req.http.User-Agent ~ "(?i)(web)crawler") {
|
||||
set req.http.X-UA-Device = "bot"; }
|
||||
elsif (req.http.User-Agent ~ "(?i)ipad") { set req.http.X-UA-Device = "tablet-ipad"; }
|
||||
elsif (req.http.User-Agent ~ "(?i)ip(hone|od)") { set req.http.X-UA-Device = "mobile-iphone"; }
|
||||
/* how do we differ between an android phone and an android tablet?
|
||||
http://stackoverflow.com/questions/5341637/how-do-detect-android-tablets-in-general-useragent */
|
||||
elsif (req.http.User-Agent ~ "(?i)android.*(mobile|mini)") { set req.http.X-UA-Device = "mobile-android"; }
|
||||
// android 3/honeycomb was just about tablet-only, and any phones will probably handle a bigger page layout.
|
||||
elsif (req.http.User-Agent ~ "(?i)android 3") { set req.http.X-UA-Device = "tablet-android"; }
|
||||
/* Opera Mobile */
|
||||
elsif (req.http.User-Agent ~ "Opera Mobi") { set req.http.X-UA-Device = "mobile-smartphone"; }
|
||||
// May very well give false positives towards android tablets. Suggestions welcome.
|
||||
elsif (req.http.User-Agent ~ "(?i)android") { set req.http.X-UA-Device = "tablet-android"; }
|
||||
elsif (req.http.User-Agent ~ "PlayBook; U; RIM Tablet") { set req.http.X-UA-Device = "tablet-rim"; }
|
||||
elsif (req.http.User-Agent ~ "hp-tablet.*TouchPad") { set req.http.X-UA-Device = "tablet-hp"; }
|
||||
elsif (req.http.User-Agent ~ "Kindle/3") { set req.http.X-UA-Device = "tablet-kindle"; }
|
||||
elsif (req.http.User-Agent ~ "Touch.+Tablet PC" ||
|
||||
req.http.User-Agent ~ "Windows NT [0-9.]+; ARM;" ) {
|
||||
set req.http.X-UA-Device = "tablet-microsoft";
|
||||
}
|
||||
elsif (req.http.User-Agent ~ "Mobile.+Firefox") { set req.http.X-UA-Device = "mobile-firefoxos"; }
|
||||
elsif (req.http.User-Agent ~ "^HTC" ||
|
||||
req.http.User-Agent ~ "Fennec" ||
|
||||
req.http.User-Agent ~ "IEMobile" ||
|
||||
req.http.User-Agent ~ "BlackBerry" ||
|
||||
req.http.User-Agent ~ "BB10.*Mobile" ||
|
||||
req.http.User-Agent ~ "GT-.*Build/GINGERBREAD" ||
|
||||
req.http.User-Agent ~ "SymbianOS.*AppleWebKit") {
|
||||
set req.http.X-UA-Device = "mobile-smartphone";
|
||||
}
|
||||
elsif (req.http.User-Agent ~ "(?i)symbian" ||
|
||||
req.http.User-Agent ~ "(?i)^sonyericsson" ||
|
||||
req.http.User-Agent ~ "(?i)^nokia" ||
|
||||
req.http.User-Agent ~ "(?i)^samsung" ||
|
||||
req.http.User-Agent ~ "(?i)^lg" ||
|
||||
req.http.User-Agent ~ "(?i)bada" ||
|
||||
req.http.User-Agent ~ "(?i)blazer" ||
|
||||
req.http.User-Agent ~ "(?i)cellphone" ||
|
||||
req.http.User-Agent ~ "(?i)iemobile" ||
|
||||
req.http.User-Agent ~ "(?i)midp-2.0" ||
|
||||
req.http.User-Agent ~ "(?i)u990" ||
|
||||
req.http.User-Agent ~ "(?i)netfront" ||
|
||||
req.http.User-Agent ~ "(?i)opera mini" ||
|
||||
req.http.User-Agent ~ "(?i)palm" ||
|
||||
req.http.User-Agent ~ "(?i)nintendo wii" ||
|
||||
req.http.User-Agent ~ "(?i)playstation portable" ||
|
||||
req.http.User-Agent ~ "(?i)portalmmm" ||
|
||||
req.http.User-Agent ~ "(?i)proxinet" ||
|
||||
req.http.User-Agent ~ "(?i)windows\ ?ce" ||
|
||||
req.http.User-Agent ~ "(?i)winwap" ||
|
||||
req.http.User-Agent ~ "(?i)eudoraweb" ||
|
||||
req.http.User-Agent ~ "(?i)htc" ||
|
||||
req.http.User-Agent ~ "(?i)240x320" ||
|
||||
req.http.User-Agent ~ "(?i)avantgo") {
|
||||
set req.http.X-UA-Device = "mobile-generic";
|
||||
}
|
||||
}
|
||||
}
|
48
etc/varnish/conf.d/prestashop.backend_response.vcl
Normal file
48
etc/varnish/conf.d/prestashop.backend_response.vcl
Normal file
|
@ -0,0 +1,48 @@
|
|||
## From https://github.com/CleverCloud/varnish-examples/blob/master/prestashop.vcl
|
||||
|
||||
# Remove some headers we never want to see
|
||||
unset beresp.http.Server;
|
||||
unset beresp.http.X-Powered-By;
|
||||
# For static content strip all backend cookies
|
||||
if (bereq.url ~ "\.(css|js|png|gif|jp(e?)g)|swf|ico|woff") {
|
||||
unset beresp.http.cookie;
|
||||
}
|
||||
# Don't store backend
|
||||
if (bereq.url ~ "admin70" || bereq.url ~ "preview=true") {
|
||||
set beresp.uncacheable = true;
|
||||
set beresp.ttl = 30s;
|
||||
|
||||
return (deliver);
|
||||
}
|
||||
if (bereq.method == "GET" && (bereq.url ~ "^/?mylogout=")) {
|
||||
set beresp.ttl = 0s;
|
||||
unset beresp.http.Set-Cookie;
|
||||
set beresp.uncacheable = true;
|
||||
|
||||
return(deliver);
|
||||
}
|
||||
# don't cache response to posted requests or those with basic auth
|
||||
if ( bereq.method == "POST" || bereq.http.Authorization ) {
|
||||
set beresp.uncacheable = true;
|
||||
set beresp.ttl = 120s;
|
||||
|
||||
return (deliver);
|
||||
}
|
||||
# don't cache search results
|
||||
if ( bereq.url ~ "\?s=" ){
|
||||
set beresp.uncacheable = true;
|
||||
set beresp.ttl = 120s;
|
||||
|
||||
return (deliver);
|
||||
}
|
||||
# only cache status ok
|
||||
if ( beresp.status != 200 ) {
|
||||
set beresp.uncacheable = true;
|
||||
set beresp.ttl = 120s;
|
||||
|
||||
return (deliver);
|
||||
}
|
||||
# A TTL of 2h
|
||||
set beresp.ttl = 2h;
|
||||
# Define the default grace period to serve cached content
|
||||
set beresp.grace = 30s;
|
87
etc/varnish/conf.d/prestashop.recv.vcl
Normal file
87
etc/varnish/conf.d/prestashop.recv.vcl
Normal file
|
@ -0,0 +1,87 @@
|
|||
## From https://github.com/CleverCloud/varnish-examples/blob/master/prestashop.vcl
|
||||
|
||||
# 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 has_js and CloudFlare/Google Analytics __* cookies.
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
|
||||
# Remove a ";" prefix, if present.
|
||||
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
|
||||
# Allow purging from ACL
|
||||
if (req.method == "PURGE") {
|
||||
# If not allowed then a error 405 is returned
|
||||
if (client.ip != "127.0.0.1" ) {
|
||||
return(synth(405, "This IP is not allowed to send PURGE requests."));
|
||||
}
|
||||
# If allowed, do a cache_lookup -> vlc_hit() or vlc_miss()
|
||||
return (purge);
|
||||
}
|
||||
# Post requests will not be cached
|
||||
if (req.http.Authorization || req.method == "POST") {
|
||||
return (pass);
|
||||
}
|
||||
if (req.method == "GET" && (req.url ~ "^/?mylogout=")) {
|
||||
unset req.http.Cookie;
|
||||
return (pass);
|
||||
}
|
||||
#we should not cache any page for Prestashop backend
|
||||
if (req.method == "GET" && (req.url ~ "^/admin70")) {
|
||||
return (pass);
|
||||
}
|
||||
#we should not cache any page for customers
|
||||
if (req.method == "GET" && (req.url ~ "^/authentification" || req.url ~ "^/my-account")) {
|
||||
return (pass);
|
||||
}
|
||||
#we should not cache any page for customers
|
||||
if (req.method == "GET" && (req.url ~ "^/identity" || req.url ~ "^/my-account.php")) {
|
||||
return (pass);
|
||||
}
|
||||
#we should not cache any page for sales
|
||||
if (req.method == "GET" && (req.url ~ "^/cart.php" || req.url ~ "^/order.php")) {
|
||||
return (pass);
|
||||
}
|
||||
#we should not cache any page for sales
|
||||
if (req.method == "GET" && (req.url ~ "^/addresses.php" || req.url ~ "^/order-detail.php")) {
|
||||
return (pass);
|
||||
}
|
||||
#we should not cache any page for sales
|
||||
if (req.method == "GET" && (req.url ~ "^/order-confirmation.php" || req.url ~ "^/order-return.php")) {
|
||||
return (pass);
|
||||
}
|
||||
if (req.method != "GET" && req.method != "HEAD") {
|
||||
return (pass);
|
||||
}
|
||||
# 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.=[^;]+(; )?", "");
|
||||
# removes all cookies named __utm? (utma, utmb...) - tracking thing
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "(^|(?<=; )) *__utm.=[^;]+;? *", "\1");
|
||||
# Remove a ";" prefix, if present.
|
||||
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
|
||||
# Are there cookies left with only spaces or that are empty?
|
||||
if (req.http.Cookie ~ "^ *$") {
|
||||
unset req.http.Cookie;
|
||||
}
|
||||
# Cache the following files extensions
|
||||
if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico|woff)") {
|
||||
unset req.http.Cookie;
|
||||
}
|
||||
# Normalize Accept-Encoding header and compression
|
||||
# https://www.varnish-cache.org/docs/3.0/tutorial/vary.html
|
||||
if (req.http.Accept-Encoding) {
|
||||
# Do no compress compressed files...
|
||||
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
|
||||
unset req.http.Accept-Encoding;
|
||||
} elsif (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;
|
||||
}
|
||||
}
|
||||
# Did not cache HTTP authentication and HTTP Cookie
|
||||
if (req.http.Authorization) {
|
||||
# Not cacheable by default
|
||||
return (pass);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
# respect Cache-Control from client
|
||||
if (req.http.Cache-Control ~ "(private|no-cache|no-store)" || req.http.Pragma == "no-cache") { return (pass); }
|
4
etc/varnish/conf.d/wordpress.backend_response.vcl
Normal file
4
etc/varnish/conf.d/wordpress.backend_response.vcl
Normal file
|
@ -0,0 +1,4 @@
|
|||
if (bereq.url ~ "wp-(login|admin)" || bereq.http.Cookie ~ "wordpress_logged_in_" ) {
|
||||
set beresp.uncacheable = true;
|
||||
set beresp.ttl = 0s;
|
||||
}
|
3
etc/varnish/conf.d/wordpress.recv.vcl
Normal file
3
etc/varnish/conf.d/wordpress.recv.vcl
Normal file
|
@ -0,0 +1,3 @@
|
|||
if (req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_" ) {
|
||||
return (pass);
|
||||
}
|
161
etc/varnish/default.vcl
Normal file
161
etc/varnish/default.vcl
Normal file
|
@ -0,0 +1,161 @@
|
|||
vcl 4.1;
|
||||
|
||||
backend default {
|
||||
.path = "/run/haproxy-frontend-default.sock";
|
||||
.proxy_header = 1;
|
||||
.connect_timeout = 3s;
|
||||
.first_byte_timeout = 300s;
|
||||
.between_bytes_timeout = 300s;
|
||||
.probe = {
|
||||
.request =
|
||||
"HEAD /haproxycheck HTTP/1.1"
|
||||
"Connection: close";
|
||||
.timeout = 1s;
|
||||
.interval = 3s;
|
||||
.window = 3;
|
||||
.threshold = 2;
|
||||
}
|
||||
}
|
||||
|
||||
# Uncomment if you want to do device detection
|
||||
# cf. https://varnish-cache.org/docs/6.0/users-guide/devicedetection.html
|
||||
#include "/etc/varnish/conf.d/devicedetect.functions.vcl";
|
||||
|
||||
# Those functions are applied everytime
|
||||
# Edit them cautiously!
|
||||
# Do not "return" from these functions.
|
||||
|
||||
sub vcl_recv {
|
||||
# HAProxy check
|
||||
if (req.url == "/varnishcheck") {
|
||||
return(synth(200, "Hi HAProxy, I'm fine!"));
|
||||
}
|
||||
|
||||
# Normalize encoding, and unset it on yet-compressed formats.
|
||||
if (req.http.Accept-Encoding) {
|
||||
if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|lzma|tbz|zip|rar)(\?.*|)$") {
|
||||
unset req.http.Accept-Encoding;
|
||||
}
|
||||
# use gzip when possible, otherwise use deflate
|
||||
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 {
|
||||
# unknown algorithm, unset accept-encoding header
|
||||
unset req.http.Accept-Encoding;
|
||||
}
|
||||
}
|
||||
|
||||
# Remove known cookies used only on client side (by JavaScript).
|
||||
if (req.http.cookie) {
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "_gat=[^;]+(; )?", ""); # Google Analytics
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", ""); # Google Analytics
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "_gaq=[^;]+(; )?", ""); # Google Analytics
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "__utm[^=]*=[^;]+(; )?", ""); # Google Analytics
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", ""); # Google Doubleclick
|
||||
set req.http.Cookie = regsuball(req.http.Cookie, "__auc=[^;]+(; )?", ""); # Alexa Analytics
|
||||
|
||||
if (req.http.cookie ~ "^ *$") {
|
||||
unset req.http.cookie;
|
||||
}
|
||||
}
|
||||
|
||||
# BEGIN HTTP tagging
|
||||
set req.http.X-Boost-Layer = "varnish";
|
||||
# END HTTP tagging
|
||||
}
|
||||
|
||||
sub vcl_backend_response {
|
||||
if (beresp.uncacheable) {
|
||||
set beresp.http.X-Cacheable = "FALSE";
|
||||
} else {
|
||||
set beresp.http.X-Cacheable = "TRUE";
|
||||
}
|
||||
|
||||
# our default TTL is 60s instead of 86400s
|
||||
if (beresp.http.cache-control !~ "max-age=") {
|
||||
set beresp.ttl = 60s;
|
||||
}
|
||||
|
||||
# Grace mode (Stale content delivery)
|
||||
# abor on 5xx errors, to keep grace mode, even 503 from HAProxy
|
||||
if (beresp.status >= 500 && bereq.is_bgfetch) {
|
||||
return (abandon);
|
||||
}
|
||||
set beresp.grace = 4h;
|
||||
}
|
||||
|
||||
sub vcl_deliver {
|
||||
|
||||
unset resp.http.Via;
|
||||
|
||||
# BEGIN HTTP tagging
|
||||
if (resp.http.Set-Cookie && resp.http.Cache-Control) {
|
||||
set resp.http.X-Boost-Step2 = "varnish WITH set-cookie AND cache-control on backend server";
|
||||
} elseif (resp.http.Set-Cookie) {
|
||||
set resp.http.X-Boost-Step2 = "varnish WITH set-cookie and NO cache-control on backend server";
|
||||
} elseif (resp.http.Cache-Control) {
|
||||
set resp.http.X-Boost-Step2 = "varnish with NO set-cookie and WITH cache-control on backend server";
|
||||
} else {
|
||||
set resp.http.X-Boost-Step2 = "varnish with NO set-cookie and NO cache-control on backend server";
|
||||
}
|
||||
# END HTTP tagging
|
||||
|
||||
if (resp.http.X-Varnish ~ "[0-9]+ +[0-9]+") {
|
||||
set resp.http.X-Cache = "HIT";
|
||||
unset resp.http.X-Boost-Step3;
|
||||
} else {
|
||||
set resp.http.X-Cache = "MISS";
|
||||
}
|
||||
|
||||
# DEBUG infos
|
||||
|
||||
## This is disabled, because of a bug in our Varnish verison
|
||||
## https://github.com/varnishcache/varnish-cache/issues/3765
|
||||
### set resp.http.X-Varnish-Client-Ip = client.ip;
|
||||
|
||||
set resp.http.X-Varnish-Client-Method = req.method;
|
||||
set resp.http.X-Varnish-Client-Url = req.url;
|
||||
set resp.http.X-Varnish-Client-Proto = req.proto;
|
||||
set resp.http.X-Varnish-Object-Ttl = obj.ttl;
|
||||
|
||||
# Enabel these, to increase debug information
|
||||
### set resp.http.X-Varnish-Client-Cache-Control = req.http.cache-control;
|
||||
### set resp.http.X-Varnish-Client-Cookie = req.http.cookie;
|
||||
### set resp.http.X-Varnish-Client-Ua = req.http.user-agent;
|
||||
### set resp.http.X-Varnish-Object-Grace = obj.grace;
|
||||
### set resp.http.X-Varnish-Object-Keep = obj.keep;
|
||||
### set resp.http.X-Varnish-Object-Storage = obj.storage;
|
||||
}
|
||||
|
||||
# BEGIN sites
|
||||
include "/etc/varnish/sites/example.vcl";
|
||||
# END sites
|
||||
|
||||
# Custom functions, executed as a "fallback"
|
||||
sub vcl_backend_error {
|
||||
set beresp.http.Content-Type = "text/html; charset=utf-8";
|
||||
set beresp.http.Retry-After = "5";
|
||||
set beresp.body = {"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>"} + beresp.status + " " + beresp.reason + {"</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
|
||||
<p>"} + beresp.reason + {"</p>
|
||||
<h3>EvoGuru Meditation:</h3>
|
||||
<p>XID: "} + bereq.xid + {"</p>
|
||||
<hr>
|
||||
<p>Varnish cache server</p>
|
||||
</body>
|
||||
</html>
|
||||
"};
|
||||
return (deliver);
|
||||
}
|
||||
|
||||
# Builtin functions are visible with this command:
|
||||
# varnishd -x builtin
|
143
etc/varnish/sites/example.vcl
Normal file
143
etc/varnish/sites/example.vcl
Normal file
|
@ -0,0 +1,143 @@
|
|||
sub vcl_recv {
|
||||
# Happens before we check if we have this in cache already.
|
||||
#
|
||||
# Typically you clean up the request here, removing cookies you don't need,
|
||||
# rewriting the request, etc.
|
||||
#if (req.http.host == "example.com") {
|
||||
if (req.http.host == "example.com" || req.http.host == "www.example.com") {
|
||||
|
||||
#if (req.method == "PURGE") {
|
||||
# # Allow from monitoring & hosting08
|
||||
# if (client.ip == "1.2.3.4" || client.ip == "4.5.6.7") {
|
||||
# if (req.url == "/_purge_all") {
|
||||
# ban("req.http.host == "+req.http.host+" && req.url ~ .");
|
||||
# return(synth(200, "ALL purge cache done"));
|
||||
# }
|
||||
# ban("req.http.host == "+req.http.host+" && req.url ~ "+req.url);
|
||||
# return(synth(200, "purge cache done"));
|
||||
# } else {
|
||||
# return(synth(403, "permission denied"));
|
||||
# }
|
||||
#}
|
||||
|
||||
# return (pass) when Cache-Control: no-cache, private etc. from client
|
||||
include "/etc/varnish/conf.d/respect_cache_request_headers.recv.vcl";
|
||||
|
||||
# unset cookie and auth headers for static files (jpg, png, pdf...)
|
||||
include "/etc/varnish/conf.d/cleanup_requests_static.recv.vcl";
|
||||
|
||||
# Wordpress : return (pass) when WP cookie or "^/wp-(login|admin)" url
|
||||
#include "/etc/varnish/conf.d/wordpress.recv.vcl";
|
||||
|
||||
# Uncomment if your site uses Prestashop
|
||||
#include "/etc/varnish/conf.d/prestashop.recv.vcl";
|
||||
|
||||
# Uncomment to use devide detection
|
||||
#call devicedetect;
|
||||
|
||||
# builtin configuration
|
||||
#include "/etc/varnish/conf.d/builtin.recv.vcl";
|
||||
if (req.method == "PRI") {
|
||||
/* This will never happen in properly formed traffic (see: RFC7540) */
|
||||
return (synth(405));
|
||||
}
|
||||
if (!req.http.host &&
|
||||
req.esi_level == 0 &&
|
||||
req.proto ~ "^(?i)HTTP/1.1") {
|
||||
/* In HTTP/1.1, Host is required. */
|
||||
return (synth(400));
|
||||
}
|
||||
if (req.method != "GET" &&
|
||||
req.method != "HEAD" &&
|
||||
req.method != "PUT" &&
|
||||
req.method != "POST" &&
|
||||
req.method != "TRACE" &&
|
||||
req.method != "OPTIONS" &&
|
||||
req.method != "DELETE" &&
|
||||
req.method != "PATCH") {
|
||||
/* Non-RFC2616 or CONNECT which is weird. */
|
||||
return (pipe);
|
||||
}
|
||||
if (req.method != "GET" && req.method != "HEAD") {
|
||||
/* We only deal with GET and HEAD by default */
|
||||
return (pass);
|
||||
}
|
||||
if (req.http.Authorization || req.http.Cookie) {
|
||||
/* Not cacheable by default */
|
||||
return (pass);
|
||||
}
|
||||
|
||||
return (hash);
|
||||
}
|
||||
}
|
||||
|
||||
sub vcl_backend_response {
|
||||
# Happens after we have read the response headers from the backend.
|
||||
#
|
||||
# Here you clean the response headers, removing silly Set-Cookie headers
|
||||
# and other mistakes your backend does..
|
||||
#if (bereq.http.host == "example.com") {
|
||||
if (bereq.http.host == "example.com" || bereq.http.host == "www.example.com") {
|
||||
|
||||
# Low TTL for objects with an error response code.
|
||||
if (beresp.status == 403 || beresp.status == 404 || beresp.status >= 500) {
|
||||
set beresp.ttl = 10s;
|
||||
# mark as "hit_for_pass" for 10s
|
||||
#set beresp.uncacheable = false;
|
||||
return(deliver);
|
||||
}
|
||||
|
||||
# Default TTL if the backend does not send Expires or max-age/s-max-age headers
|
||||
if (!beresp.http.expires && beresp.http.cache-control !~ "max-age=") {
|
||||
set beresp.ttl = 4h;
|
||||
}
|
||||
# grace time
|
||||
#set beresp.grace = 1d;
|
||||
|
||||
# Exceptions
|
||||
if (bereq.url ~ "\.(rss|xml|atom)(\?.*|)$") {
|
||||
set beresp.ttl = 2h;
|
||||
}
|
||||
|
||||
# Wordpress : no cache when WP cookie or "^/wp-(login|admin)" url
|
||||
#include "/etc/varnish/conf.d/wordpress.backend_response.vcl";
|
||||
|
||||
# Uncomment if your site uses Prestashop
|
||||
#include "/etc/varnish/conf.d/prestashop.backend_response.vcl";
|
||||
|
||||
# Uncomment if you want to do device detection
|
||||
#include "/etc/varnish/conf.d/devicedetect.backend_response.vcl";
|
||||
|
||||
# builtin configuration
|
||||
#include "/etc/varnish/conf.d/builtin.backend_response.vcl";
|
||||
if (bereq.uncacheable) {
|
||||
return (deliver);
|
||||
} else 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-Miss" for the next 2 minutes
|
||||
set beresp.ttl = 120s;
|
||||
set beresp.uncacheable = true;
|
||||
}
|
||||
|
||||
return (deliver);
|
||||
}
|
||||
}
|
||||
|
||||
sub vcl_deliver {
|
||||
# Happens when we have all the pieces we need, and are about to send the
|
||||
# response to the client.
|
||||
#
|
||||
# You can do accounting or modifying the final object here.
|
||||
#if (req.http.host == "example.com") {
|
||||
if (req.http.host == "example.com" || req.http.host == "www.example.com") {
|
||||
|
||||
# Uncomment if you want to do device detection
|
||||
#include "/etc/varnish/conf.d/devicedetect.deliver.vcl";
|
||||
|
||||
return (deliver);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue