Configure varnish cache in front of any website
You need to get a dedicated server, VPS or a droplet on the digital ocean to setup varnish server.
Now i would be explaining the life cycle of each request.
The request will come on 443 which would be nginx in our case or 80 which would be varnish server.
Port 443 nginx will forward the request to varnish server on port 80, if the cache is available it will send back request to 443 otherwise follow the below step.
varnish will then send a request to apache server which is on port 8888.
Once you get the server login the panel via putty.
Change Password
passwd
Check for new updates
yum check-update
Update your server
yum update
Install commonly used programs
yum install -y links htop nano
Install the EPEL repository
sudo yum install epel-release
Change the security settings
nano /etc/selinux/config
change the line below
SELINUX=enforcing
to this line
SELINUX=disabled
Restart the server for the changes to take effect
sudo reboot
Stop the firewall
service firewalld stop
Install Nginx
yum install -y nginx
Take backup of original Nginx config file
mv /etc/nginx/nginx.conf /etc/nginx/nginx-old.conf
Place the new config changes
nano /etc/nginx/nginx.conf
# For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes 12; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 8096; multi_accept on; use epoll; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 20; types_hash_max_size 2048; client_max_body_size 256M; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { proxy_pass_header Server; listen 81 default_server; #listen [::]:81 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } include /etc/nginx/snippets/ssl-params.conf; include /etc/nginx/sites-enabled/*; # Settings for a TLS enabled server. # # server { # listen 443 ssl http2 default_server; # listen [::]:443 ssl http2 default_server; # server_name _; # root /usr/share/nginx/html; # # ssl_certificate "/etc/pki/nginx/server.crt"; # ssl_certificate_key "/etc/pki/nginx/private/server.key"; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 10m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # # # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf; # # location / { # } # # error_page 404 /404.html; # location = /40x.html { # } # # error_page 500 502 503 504 /50x.html; # location = /50x.html { # } # } }
Generate DH parameters, 2048 bit long safe prime.
openssl dhparam -rand - 2048 | sudo tee /etc/nginx/dhparams.pem
If you already have a certificate on the previous server, create SSL directory
mkdir /var/ssl/
mkdir /var/ssl/domain.com/
If you have an existing certificate, Copy ca.cert file
nano /var/ssl/domain.com/ca.crt
If you have an existing certificate, Copy priv.key file
nano /var/ssl/domain.com/priv.key
Install certbot which is used by LetsEncrypt.
yum install certbot
Create a new SSL certificate from below commands or ignore if you have copied the certificate.
OPTION 1:
certbot certonly --standalone --preferred-challenges http --http-01-port 888 -d domain.com -d www.domain.com --post-hook="service nginx restart"
OPTION 2:
certbot -d domain.com
Location: /etc/letsencrypt/live/domain.com/fullchain.pem
OPRION3:
Create Les Encrypt certifacte manully. you would have to upload a file to verify the domain on “/.well-known/acme-challenge”
certbot -d domain.com --manual certonly
Create folder /etc/nginx/sites-enabled
mkdir /etc/nginx/sites-enabled
Create vhost for proxy with name “domain.conf”
nano /etc/nginx/sites-enabled/domain.conf
server { listen 443 ssl; server_name domain.com; #ssl_certificate /var/ssl/domain.com/ca.crt; #ssl_certificate_key /var/ssl/domain.com/priv.key; ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:80; 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 Host $host; proxy_pass_header Server; } }
create folder /etc/nginx/snippets
mkdir /etc/nginx/snippets
create file inside /etc/nginx/snippets/ssl-params.conf
nano /etc/nginx/snippets/ssl-params.conf
# from https://cipherli.st/ # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Disable preloading HSTS for now. You can use the commented out header line that includes # the "preload" directive if you understand the implications. #add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; ssl_dhparam /etc/nginx/dhparams.pem;
Restart the nginx server
service nginx restart
Renew LetsEncrypt certificate
/usr/bin/certbot renew --renew-hook "/usr/sbin/nginx reload" >> /var/log/le-renew.log
You can also place this command in cronjobs.
crontab -e
30 2 * * * /usr/bin/certbot renew --renew-hook "/usr/sbin/nginx reload" >> /var/log/le-renew.log
service crond restart
Now install varnish
yum install pygpgme yum-utils
nano /etc/yum.repos.d/varnish.repo
Place this code inside this file
[varnishcache_varnish5] name=varnishcache_varnish5 baseurl=https://packagecloud.io/varnishcache/varnish5/el/7/$basearch repo_gpgcheck=1 gpgcheck=0 enabled=1 gpgkey=https://packagecloud.io/varnishcache/varnish5/gpgkey sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt metadata_expire=300 [varnishcache_varnish5-source] name=varnishcache_varnish5-source baseurl=https://packagecloud.io/varnishcache/varnish5/el/7/SRPMS repo_gpgcheck=1 gpgcheck=0 enabled=1 gpgkey=https://packagecloud.io/varnishcache/varnish5/gpgkey sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt metadata_expire=300
yum -q makecache -y --disablerepo='*' --enablerepo='varnishcache_varnish5'
yum install -y varnish
Edit file /etc/varnish/varnish.params and make changes below
nano /etc/varnish/varnish.params
Change: VARNISH_LISTEN_PORT=6081 to VARNISH_LISTEN_PORT=80
Replace the configuration in /etc/varnish/default.vcl
mv /etc/varnish/default.vcl /etc/varnish/default-old.vcl
nano /etc/varnish/default.vcl
vcl 4.0; # Based on: https://github.com/mattiasgeniar/varnish-4.0-configuration-templates/blob/master/default.vcl #import xkey; import std; #include "/etc/varnish/acmetool.vcl"; #include "/etc/varnish/streaming.vcl"; include "/etc/varnish/certbot.vcl"; # Define one backend backend default { .host = "111.111.111.111; # IP or Hostname of backend .port = "80"; # Port Apache or whatever is listening } backend admin { .host = "111.111.111.111"; # IP or Hostname of backend .port = "80"; # Port Apache or whatever is listening .first_byte_timeout = 600s; # How long to wait before we receive a first byte from our backend? .connect_timeout = 600s; # How long to wait for a backend connection? .between_bytes_timeout = 600s; # How long to wait between bytes received from our backend? } /* backend local_system_code { .host = "111.111.111.111"; # IP or Hostname of backend .port = "8888"; # Port Apache or whatever is listening .first_byte_timeout = 600s; # How long to wait before we receive a first byte from our backend? .connect_timeout = 600s; # How long to wait for a backend connection? .between_bytes_timeout = 600s; # How long to wait between bytes received from our backend? } */ acl purge { # ACL we'll use later to allow purges "localhost"; "209.126.111.251"; "127.0.0.1"; "::1"; #"Client Specific IPs here"; } sub vcl_recv { ## Send admin requests to different backend with extended timeouts if (req.url ~ "^/admin") { set req.backend_hint = admin; } /* if (req.http.host ~ "example.com") { set req.backend_hint = local_system_code; } */ ## To exclude domains from varnish /* if (req.http.host ~ "^(?i)staging.domain.com") { return (pass); } */ ## Redirect to https if ((client.ip != "127.0.0.1" && std.port(server.ip) == 80) && (req.http.host ~ "^(?i)(www\.)?domain.com")) { if (req.method != "PURGE") { set req.http.x-redir = "https://" + req.http.host + req.url; return (synth(850, "")); } } ## Redirect assets to CDN /* if ( req.http.host == "domain.com" || req.http.host == "www.domain.com" || req.http.host == "cdn.domain.com") { if ( req.url ~ "\.(gif|ico|jpg|jpeg|png)$" && req.http.host != "cdn.domain.com" ) { set req.http.x-redir = "https://cdn.domain.com" + req.url; return (synth(750, "")); } if ( req.url !~ "\.(gif|ico|jpg|jpeg|png)$" && req.http.host == "cdn.domain.com" ) { set req.http.x-redir = "https://www.domain.com" + req.url; return (synth(760, "")); } } */ ## Redirect specific traffic to another url /* if (req.http.host ~ "^(?i)m.domain.com") { return (synth(750, "")); } */ ## Allow htaccess password if (req.http.Authorization || req.http.Authenticate) { return (pass); } ##PASSING REAL IP TO BACKEND if (req.restarts == 0) { if (req.http.X-Forwarded-For) { set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } ## 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 ## Remove the proxy header (see https://httpoxy.org/#mitigate-varnish) unset req.http.proxy; ## Allow purging /* ## XKey logic if ( req.http.host == "domain.com" || req.http.host == "www.domain.com") { if (req.method == "PURGE") { # If not allowed then a error 405 is returned if (!client.ip ~ purge) { return(synth(405, "This IP is not allowed to send PURGE requests.")); } set req.http.n-gone = xkey.softpurge("10000"); return(synth(200, "BAN added - Invalidated "+req.http.n-gone+" objects")); } } */ ## Override purging where mass urls need to be purged if (req.method == "BAN") { # If not allowed then a error 405 is returned if (!client.ip ~ purge) { return(synth(405, "This IP is not allowed to send PURGE requests.")); } return (hash); } if (req.method == "PURGE") { # If not allowed then a error 405 is returned if (!client.ip ~ purge) { return(synth(405, "This IP is not allowed to send PURGE requests.")); } #return (purge); ban("req.http.host ~ " + req.http.host + " && req.url ~ " + req.url); } if (req.url ~ "wp-login|admin|git_deployment|show=preview|checkout") { return (pass); } if(req.http.Cookie ~ "wordpress_logged_in_" ) { return (pass); } # Post requests will not be cached if (req.http.Authorization || req.method == "POST") { return (pass); } ## Unset all cookies so that Varnish can serve cached content unset req.http.cookie; } ## Handle the HTTP request coming from our backend sub vcl_backend_response { /* if (bereq.http.Host ~ "^(?i)(www\.)?domain.com" ||bereq.http.Host == "^(?i)www.domain.com" ) { set beresp.http.xkey = "10000"; } */ /* if (beresp.status >= 500 && beresp.status <= 599) { return (abandon); } */ ## Do not cache error pages & 404 pages if (beresp.status == 403 || beresp.status == 404 || beresp.status >= 500) { set beresp.ttl = 0s; return (deliver); } ## Called after the response headers has been successfully retrieved from the backend. ## Enable cache for all static files ## The same argument as the static caches from above: monitor your cache size, if you get data nuked out of it, consider giving up the static file cache. ## Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-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|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 beresp.http.set-cookie; } ## 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 use streaming here to avoid locking. if (bereq.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 beresp.http.set-cookie; set beresp.do_stream = true; ## Check memory usage it'll grow in fetch_chunksize blocks (128k by default) ## if the backend doesn't send a Content-Length header, so only enable it for big objects } /* ## Don't cache 50x & 403 responses ## 404 added for testing - remove before live if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504 || beresp.status == 403) { return (abandon); } */ ## Allow stale content, in case the backend goes down. ## make Varnish keep all objects for 6 hours beyond their TTL # A TTL of 2h set beresp.ttl = 24h; set beresp.grace = 24h; return (deliver); } ## The routine when we deliver the HTTP request to the user ## Last chance to modify headers that are sent to the client sub vcl_deliver { #turn on if you want disable login bar on wordpress. /* if (req.url !~ "admin|wp-login") { unset resp.http.set-cookie; unset resp.http.cookie; } */ ## Called before a cached object is delivered to the client. if (obj.hits > 0) { ## 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 - " + obj.hits; } else { set resp.http.X-Cache = ""; } ## Remove some headers: PHP version unset resp.http.X-Powered-By; ## Remove some headers: Apache version & OS 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_synth { if (resp.status == 503 && req.http.sie-enabled) { unset req.http.sie-enabled; return (restart); } ## Redirector for CDN /* if (resp.status == 750) { set resp.http.Location = req.http.x-redir; set resp.status = 302; return (deliver); } if (resp.status == 760) { set resp.http.Location = req.http.x-redir; set resp.status = 302; return (deliver); } */ ## The actual redirector for HTTPS if (resp.status == 850) { // Redirect to HTTPS with 301 status. set resp.status = 301; set resp.http.Location = req.http.x-redir; return(deliver); } if (resp.status == 503) { synthetic(std.fileread("/etc/varnish/error_docs/503.html")); return(deliver); } if (resp.status == 403) { synthetic(std.fileread("/etc/varnish/error_docs/403.html")); return(deliver); } } sub vcl_hit { if (obj.ttl < 0s && obj.ttl + obj.grace > 0s) { if (req.restarts == 0) { set req.http.sie-enabled = true; return (restart); } else { set req.http.sie-abandon = true; return (deliver); } } if (obj.ttl >= 0s) { return (deliver); } return (restart); /* if (req.method == "PURGE") { softpurge.softpurge(); return (synth(200, "Successful softpurge")); } if (req.method == "BAN") { softpurge.softpurge(); return (synth(200, "Successful softpurge")); } */ } sub vcl_miss { /* if (req.method == "PURGE") { softpurge.softpurge(); return (synth(200, "Successful softpurge")); } if (req.method == "BAN") { softpurge.softpurge(); return (synth(200, "Successful softpurge")); } */ } # In the event of an error, show friendlier messages. sub vcl_backend_error { set beresp.http.Content-Type = "text/html; charset=utf-8"; set beresp.http.Retry-After = "5"; synthetic( {" <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <script>error_name="503 - Backend fetch failed";event_action="503 - Backend fetch failed";event_label="503 - Backend fetch failed";event_value="503";content_displaed_on_page="503 Varnish Error !";document.title=window.location.hostname + " - " + error_name;(function(i, s, o, g, r, a, m){i['GoogleAnalyticsObject']=r;i[r]=i[r] || function(){(i[r].q=i[r].q || []).push(arguments)}, i[r].l=1 * new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a, m)})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');ga('create', 'UA-111111111111', 'auto');ga('require', 'displayfeatures');ga('require', 'linkid', 'linkid.js');ga('send', 'pageview');ga('set', 'nonInteraction', true);ga('send', 'event',{eventCategory: window.location.hostname, eventAction: event_action, eventLabel: event_label, eventValue: event_value});var dimensionValue=event_value;ga('set', 'dimension1', dimensionValue);var dimensionValue=window.location.hostname;ga('set', 'dimension2', dimensionValue);ga('send', 'exception',{'exDescription': error_name,'exFatal': true});</script> <link href='' rel='stylesheet'><style>*:before, *:after{-webkit-box-sizing: border-box;-moz-box-sizing: b order-box;box-sizing: border-box;}body{font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;color: #394263;font-size: 13px;background-color: #FFF;}#error-container{padding: 120px 20px;position: relative;}#error-container .error-options{position: absolute;top: 20px;left: 20px;}#error-container h1{font-size: 96px;color: #431111;margin-bottom: 40px;}#error-container h2{color: #11103D;font-size: 24px;margin-bottom: 40px;margin-top: 80px;line-height: 1.4;}#error-container form{padding: 20px;border-radius: 3px;background: #fff;background: url(../img/template/ie8_opacity_light_10.png) repeat;background: rgba(255, 255, 255, .1);}#error-container .form-control{border-color: #fff;}.clearfix:before, .clearfix:after, .container:before, .container:after, .container-fluid:before, .container-fluid:after, .row:before, .row:after, .form-horizontal .form-group:before, .form-horizontal .form-group:after, .btn-toolbar:before, .btn-toolbar:after, .btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after, .nav:before, .nav:after, .navbar:before, .navbar:after, .navbar-header:before, .navbar-header:after, .navbar-collapse:before, .navbar-collapse:after, .pager:before, .pager:after, .panel-body:before, .panel-body:after, .modal-footer:before, .modal-footer:after{content: ' ';display: table;}.col-sm-offset-2{margin-left: 16.66666667%}.col-sm-8{width: 66.66666667%}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float: left;}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position: relative;min-height: 1px;padding-left: 15px;padding-right: 15px;}.text-center{text-align: center;}*{-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}.animation-tossing{animation-name: tossing;-webkit-animation-name: tossing;animation-duration: 2.5s;-webkit-animation-duration: 2.5s;animation-iteration-count: infinite;-webkit-animation-iteration-count: infinite;}@keyframes tossing{0%{transform: rotate(-4deg);}50%{transform: rotate(4deg);}100%{transform: rotate(-4deg);}}@-webkit-keyframes tossing{0%{-webkit-transform: rotate(-4deg);}50%{-webkit-transform: rotate(4deg);}100%{-webkit-transform: rotate(-4deg);}}.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6{font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;font-weight: 300;}a{//text-decoration: none;color: #2554B4;pointer: pointer;}.text-danger, .text-danger:hover, a.text-danger, a.text-danger:focus, a.text-danger:hover{color: #e74c3c;}/*@font-face{font-family: 'FontAwesome';src: url('../fonts/fontawesome-webfont.eot?v=4.1.0');src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight: normal;font-style: normal;}*/.fa-gear:before, .fa-cog:before{content: '\f013'}.fa{display: inline-block;font-family: FontAwesome;font-style: normal;font-weight: normal;line-height: 1;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}.fa-spin{-webkit-animation: spin 2s infinite linear;-moz-animation: spin 2s infinite linear;-o-animation: spin 2s infinite linear;animation: spin 2s infinite linear;}@-moz-keyframes spin{0%{-moz-transform: rotate(0deg);}100%{-moz-transform: rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform: rotate(0deg);}100%{-webkit-transform: rotate(359deg);}}@-o-keyframes spin{0%{-o-transform: rotate(0deg);}100%{-o-transform: rotate(359deg);}}@keyframes spin{0%{-webkit-transform: rotate(0deg);transform: rotate(0deg);}100%{-webkit-transform: rotate(359deg);transform: rotate(359deg);}</style></head> <body> <div id='error-container'><div class='row'><div class='col-sm-8 col-sm-offset-2 text-center'><h1 class=''><i class=''></i><script>document.write(content_displaed_on_page);</script></h1><h2 class='h3'>Don't worry, we'll be back.<br>Click <a href='javascript:document.location.reload(true);'>here</a> to reload the page</h2></div></div> </body> </html> <!-- Comment out default error html block <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); } sub vcl_fini { ## Called when VCL is discarded only after all requests have exited the VCL. ## Typically used to clean up VMODs. return (ok); }
Now you need to specify your main server ip.
nano /etc/varnish/default.vcl
Example line
.host = "111.111.111.111";
Edit ports in /etc/httpd/conf/httpd.conf and all vhosts to a port different from 80
nano /etc/httpd/conf/httpd.conf
Make sure you add the new port in /etc/varnish/default.vcl in the backend definition.
backend default { .host = "127.0.0.1"; .port = "8080"; }
to
# Default backend definition. Set this to point to your content server. backend default { .host = "111.111.111.111"; // your server ip .port = "80"; }
nano /etc/varnish/varnish.params
You can change varnish cache from RAM to disk
find the line below
VARNISH_STORAGE="malloc,256M"
Replace it with this line
VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,1G"
change 1G to space you want to allocate
create a new file in /etc/varnish/certbot.vcl
nano /etc/varnish/certbot.vcl
# Forward challenge-requests to acmetool, which will listen to port 402 # when issuing lets encrypt requests backend certbot { .host = "127.0.0.1"; .port = "888"; } sub vcl_recv { if (req.url ~ "^/.well-known/acme-challenge/") { set req.backend_hint = certbot; return(pass); } }
restart varnish
service varnish restart
Notes for Varnish: If you add a new domain, do the following:
Find the following block, replicate and insert below existing
if ( req.http.host == "domain.com" || req.http.host == "www.domain.com") { if (req.method == "PURGE") { # If not allowed then a error 405 is returned if (!client.ip ~ purge) { return(synth(405, "This IP is not allowed to send PURGE requests.")); } set req.http.n-gone = xkey.softpurge("10000"); return(synth(200, "BAN added - Invalidated "+req.http.n-gone+" objects")); } }