Menu
in , ,

How to talk to Varnish from Drupal site

To talk to Varnish from Drupal Side and to get good benefits from Varnish, for example, passing information about users from Drupal to Varnish so Varnish can take predefined actions.

We will make a custom Drupal module, so you may want to know more information about creating custom Drupal modules, please see Creating Drupal 7.x modules guide.

note

The Environment used in this Tutorial is LAMP Stack, varnish-3.0.7, and Drupal 7. and we will need root privileges too.

How this Connection between Varnish and Drupal can be done?

When Drupal get a request from Varnish, Drupal will reply with a custom Cookie word send to Varnish, That word can help Varnish to detect the current user type as this below example describe.

also can provide Varnish with extra information about current user ( ie: user id, user role, user name, and etc… ) using same technique.

so Varnish Can read this Cookie word that received from Drupal, then take a predefined VCL actions regards to it.

In general Case we can using this technique to differentiate between anonymous and logged-in users,
by creating a custom Drupal module, this module will make Drupal send a Cookie named VARNISH_COOKIE to Varnish and set it's value to the current User ID uid.

Note

While Caching the Drupal Pages Cookie word will created only for logged-in users. not for anonymous.
reason that we ignored creating VARNISH_COOKIE cookie with ID “0” or in anonymous users case is that, Drupal creating this cookie using hook_init() method, and this hooked method will not fired when Drupal Cache pages for anonymous users caching performance feature are enabled.

so Varnish will read the Drupal Cookie message and.. if it found the word “VARNISH_COOKIE” is set, it will understand that its logged-in user.
else it will be anonymous user.

Another Connection adjustment will be needed here, it's Purging Cache requests That can be fired automatically and regards to content change events from Drupal side to Varnish.
to accomplished this connection we will use the following 2 Contributed modules

  1. purge module
  2. expire module

now let's go to preparing Drupal side first..

Drupal side

Creating Drupal varnish_helper custom module

we need to create the custom Drupal Modules varnish_helper, and make it responsible to sending Drupal Cookie word “VARNISH_COOKIE” to Varnish, and as usual we will creating this module 2 files as following

  1. varnish_helper.info file which will located in sites/all/modules/varnish_helper/varnish_helper.info, in Drupal installation directory, and will contain the following code.

file: sites/all/modules/varnish_helper/varnish_helper.info

      name = Varnish Helper
description = Varnish Cookie Based Helper Module
package = other
core = 7.x
version = "7.x-1"
project = "varnish_helper"

  1. varnish_helper.module file which will located in sites/all/modules/varnish_helper/varnish_helper.module,in Drupal installation directory, and will contain the following code.

file: sites/all/modules/varnish_helper/varnish_helper.module

 

     <?php

/**
 * Default cookie name.
 */
define('VARNISH_COOKIE', 'VARNISH_COOKIE');



/**
 * Implements hook_init().
 */
 
function varnish_helper_init()
{
  global $user;
  
  if (strpos($_SERVER['SCRIPT_FILENAME'], 'index.php') === FALSE) {
  return;
  }
  
  $uid = isset($user->uid) ? $user->uid : 0;
  
  if (isset($_COOKIE[VARNISH_COOKIE]) && $uid == 0) {
  varnish_helper_set_cookie($uid, REQUEST_TIME - 86400);
  }
  
  elseif ((!isset($_COOKIE[VARNISH_COOKIE]) || $_COOKIE[VARNISH_COOKIE] == '-1') && $uid != 0) {
  varnish_helper_set_cookie($uid);
  }
  
  elseif (isset($_COOKIE[VARNISH_COOKIE]) && $_COOKIE[VARNISH_COOKIE] == '-1' && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD')) {
  varnish_helper_set_cookie($uid, REQUEST_TIME - 86400);
  }
  
  if ($uid == 0 && $_SERVER['REQUEST_METHOD'] != 'GET' && $_SERVER['REQUEST_METHOD'] != 'HEAD') {
  varnish_helper_set_cookie(-1);
  }
  
}


function varnish_helper_set_cookie($uid, $expires = NULL) {
  if (!$expires) {
  $expires = ini_get('session.cookie_lifetime');
  $expires = (!empty($expires) && is_numeric($expires)) ? REQUEST_TIME + (int)$expires : 0;
  setcookie(VARNISH_COOKIE, strval($uid), $expires, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure') == '1');
  }
  else {
  setcookie(VARNISH_COOKIE, '0', $expires, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure') == '1');
  }
}

note

This custom module code block modified and abstracted from the BOOST Drupal module source code.

3- Varnish side can now examine the Cookies it received from Drupal suing VCL, for example detect Cookies is exist and so prevent anonymous to pass to a path.

 

  sub vcl_recv {
   ....
   ....
    if( req.url ~ "(?i)^/path/.$" &&  ! req.http.Cookie ~ "VARNISH_COOKIE=" )
{
  error 405 "_>null route;";
}

   ....
   ....
  }

but how to secure Drupal using Varnish that will be described in the next articles.

Leave a Reply

Exit mobile version