fbpx

Configure varnish cache in front of any website

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"));
	}
}

 
 
 
 

Share this post