Author Topic: Drupal VCL tpl file for Varnish  (Read 4688 times)

0 Members and 2 Guests are viewing this topic.

Offline
*
Drupal VCL tpl file for Varnish
« on: December 08, 2021, 10:26:13 AM »
Hello!

If someone needs a Drupal Varnish VCL template here it is. I have been testing and it is working fine on my Drupal 7 and Drupal 9 installations.

Of course, I use CWP 7 and the Nginx+Varnish+Apache version of the webserver.

Code: [Select]
backend %backend_domain% {
.host = "%proxy_ip%";
.port = "%proxy_port%";
}

sub vcl_recv {
if (req.http.host ~ "%domain%") {
set req.backend_hint = %backend_domain%;

# Do not cache these paths.
if (req.url ~ "^/status\.php$" ||
req.url ~ "^/update\.php" ||
req.url ~ "^/install\.php" ||
req.url ~ "^/apc\.php$" ||
req.url ~ "^/admin" ||
req.url ~ "^/admin/.*$" ||
req.url ~ "^/user" ||
req.url ~ "^/user/.*$" ||
req.url ~ "^/users/.*$" ||
req.url ~ "^/info/.*$" ||
req.url ~ "^/flag/.*$" ||
req.url ~ "^.*/ajax/.*$" ||
req.url ~ "^.*/ahah/.*$" ||
req.url ~ "^/system/files/.*$") {

return (pass);
}

# Always cache the following file types for all users. This list of extensions
# appears twice, once here and again in vcl_backend_response so make sure you edit both
# and keep them equal.
if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
unset req.http.Cookie;
}

# Remove any Google Analytics based cookies
set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");

# Remove all cookies that Drupal doesn't need to know about. We explicitly
# list the ones that Drupal does need, the SESS and NO_CACHE. If, after
# running this code we find that either of these two cookies remains, we
# will pass as the page cannot be cached.
if (req.http.Cookie) {
# 1. Append a semi-colon to the front of the cookie string.
# 2. Remove all spaces that appear after semi-colons.
# 3. Match the cookies we want to keep, adding the space we removed
#    previously back. (\1) is first matching group in the regsuball.
# 4. Remove all other cookies, identifying them by the fact that they have
#    no space after the preceding semi-colon.
# 5. Remove all spaces and semi-colons from the beginning and end of the
#    cookie string.
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

if (req.http.Cookie == "") {
# If there are no remaining cookies, remove the cookie header. If there
# aren't any cookie headers, Varnish's default behavior will be to cache
# the page.
unset req.http.Cookie;
}
else {
# If there is any cookies left (a session or NO_CACHE cookie), do not
# cache the page. Pass it on to Apache directly.
return (pass);
}
}

# Do not cache AJAX requests.
if (req.http.X-Requested-With == "XMLHttpRequest") {
return(pass);
}

# Post requests will not be cached
if (req.http.Authorization || req.method == "POST") {
return (pass);
}
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}

# Do not cache Authorized requests.
if (req.http.Authorization) {
return(pass);
}

# LetsEncrypt Certbot passthrough
if (req.url ~ "^/\.well-known/acme-challenge/") {
return (pass);
}

if (req.url ~ "^/\.well-known/pki-validation/") {
return (pass);
}

# Forward client's IP to the backend
if (req.restarts == 0) {
if (req.http.X-Real-IP) {
set req.http.X-Forwarded-For = req.http.X-Real-IP;
} else 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;
}
}

return (hash);
}
}

« Last Edit: December 08, 2021, 11:07:16 AM by vradova »

Offline
*
Re: Drupal VCL tpl file for Varnish
« Reply #1 on: December 09, 2021, 10:58:02 AM »
I found an issue with webmail access, so I did a change on the vcl template.

Here it is.
Code: [Select]
backend %backend_domain% {
.host = "%proxy_ip%";
.port = "%proxy_port%";
}

sub vcl_recv {
if (req.http.host ~ "%domain%") {
set req.backend_hint = %backend_domain%;

# Do not cache these paths.
if (req.url ~ "^/status\.php$" ||
req.url ~ "^/update\.php" ||
req.url ~ "^/install\.php" ||
req.url ~ "^/apc\.php$" ||
req.url ~ "^/admin" ||
req.url ~ "^/admin/.*$" ||
req.url ~ "^/user" ||
req.url ~ "^/user/.*$" ||
req.url ~ "^/users/.*$" ||
req.url ~ "^/info/.*$" ||
req.url ~ "^/flag/.*$" ||
req.url ~ "^.*/ajax/.*$" ||
req.url ~ "^.*/ahah/.*$" ||
req.url ~ "^/system/files/.*$" ||
# roundcube issue
req.url ~ "^.*/webmail/.*$") {

return (pass);
}

# Always cache the following file types for all users. This list of extensions
# appears twice, once here and again in vcl_backend_response so make sure you edit both
# and keep them equal.
if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
unset req.http.Cookie;
}

# Remove any Google Analytics based cookies
set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");

# Remove all cookies that Drupal doesn't need to know about. We explicitly
# list the ones that Drupal does need, the SESS and NO_CACHE. If, after
# running this code we find that either of these two cookies remains, we
# will pass as the page cannot be cached.
if (req.http.Cookie) {
# 1. Append a semi-colon to the front of the cookie string.
# 2. Remove all spaces that appear after semi-colons.
# 3. Match the cookies we want to keep, adding the space we removed
#    previously back. (\1) is first matching group in the regsuball.
# 4. Remove all other cookies, identifying them by the fact that they have
#    no space after the preceding semi-colon.
# 5. Remove all spaces and semi-colons from the beginning and end of the
#    cookie string.
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

if (req.http.Cookie == "") {
# If there are no remaining cookies, remove the cookie header. If there
# aren't any cookie headers, Varnish's default behavior will be to cache
# the page.
unset req.http.Cookie;
}
else {
# If there is any cookies left (a session or NO_CACHE cookie), do not
# cache the page. Pass it on to Apache directly.
return (pass);
}
}

# Do not cache AJAX requests.
if (req.http.X-Requested-With == "XMLHttpRequest") {
return(pass);
}

# Post requests will not be cached
if (req.http.Authorization || req.method == "POST") {
return (pass);
}
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}

# Do not cache Authorized requests.
if (req.http.Authorization) {
return(pass);
}

# LetsEncrypt Certbot passthrough
if (req.url ~ "^/\.well-known/acme-challenge/") {
return (pass);
}

if (req.url ~ "^/\.well-known/pki-validation/") {
return (pass);
}

# Forward client's IP to the backend
if (req.restarts == 0) {
if (req.http.X-Real-IP) {
set req.http.X-Forwarded-For = req.http.X-Real-IP;
} else 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;
}
}

return (hash);
}
}

Offline
*****
Re: Drupal VCL tpl file for Varnish
« Reply #2 on: January 08, 2023, 08:59:06 PM »
Thanks much! I have a Drupal 9 site running under nginx but have had thoughts of integrating Varnish into the flow to milk a little more performance out of the site, esp. since it is more static in nature. I'll give your .vcl a test drive and see how it goes. I'll report back if I have any issues.

Offline
*
Re: Drupal VCL tpl file for Varnish
« Reply #3 on: January 09, 2023, 09:34:52 PM »
You are welcome!

Vlade.