Leveraging Aegir for Deploying Drupal 7 with SSL and Varnish

Blog

Estimated
3 min read

Reliefweb.int is our first Drupal 7 site under development, and for it we are using SSL on the user login page and the HTTP accelerator Varnish to improve performance. As with most of our builds, we’re using Aegir during the staging process to facilitate rollouts, and it has really helped simplify the setup of both Varnish and SSL. In this post, I’ll explain how using Aegir with Varnish and SSL can really simplify the deployment of rather complicated sites.

The latest version of Aegir supports SSL configuration management for the first time. To set this up on the Aegir side, all you need to do is select that your web server is Aegir SSL-enabled and set a couple options for each site managed in Aegir — this will enable Aegir to take care of installing your certificates. Aegir can also generate self signed certificates for you, which is a time saver if you need SSL running on the staging server for testing purposes but can make due with a self signed certificate until launch.

SSL has been improved in Drupal 7 and now allows for the creation of a secure and non-secure session upon sign-in to the SSL-protected part of the site. Reliefweb.int only needs SSL on certain sections of its website, like the user login page. When a user signs in to Drupal from an SSL protected section, they get two cookies — one for a secure session to be used on the SSL protected pages and one non-secure cookie to be used on non-SSL protected pages. If just one cookie — a secure cookie — was used for both SSL and non-SSL pages, the supposedly “secure” cookie would be passed in the clear on non-secure sections of the site, breaking the SSL security model. This support for the simultaneous use of secure and non-secure cookies is a security improvement in Drupal 7 core.

On Reliefweb.int there are two specific configuration items needed to get SSL working. First it’s necessary to set the variable $conf['https'] = TRUE; in the site's settings.php. Second, we use an Apache redirect rule in the site's virtualhost to redirect requests to /user/* to use HTTPS and all other requests to use HTTP. If you use Aegir, you may wonder how to get this special configuration into where it needs to be in a way that Aegir won't overwrite it, since Aegir controls the writing of settings.php and virtualhost files for all the sites it manages. It's very simple. In the .drush directory of your Aegir install, make a file like mysite.drush.inc (mysite can be anything really, the directory is scanned for .drush.inc files), and then put something like the following into that file:

`/**
 * Implementation of hook_provision_apache_vhost_config().
 */
function mysite_provision_apache_vhost_config($url, $options) {
  $text = array();

  if (d()->ssl_enabled == 1) {

    $rewrites = <<<ENDTEXT
    
    # Added by reliefweb.drush.inc
    <IfModule mod_rewrite.c>
      RewriteEngine on
      // Add you rewrite rules here.
    </IfModule>
ENDTEXT;

    $text[] = $rewrites;
     
  }

  return $text;
}

/**
 * Implementation of hook_provision_drupal_config().
 */
function mysite_provision_drupal_config($url, $options) {
  $text = '';

  if (d()->ssl_enabled == 1) {
    $text = <<<END
    // Enable http/https
    \$conf['https'] = TRUE;
    // Add other conf overrides here.
END;
  }

  return array($text);
}`

These hooks will be invoked when a site is verified or re-verified in Aegir, and the virtual host and settings.php files will get written with this extra configuration if applicable. This lets you simplify the configuration process as well as keep this code in version control in order to track changes. If you need one-off customizations for sites controlled by Aegir, Aegir will now also look for a file called local.settings.php in each site’s “sites” directory. This local.settings.php file will be migrated along with the site whenever you migrate the site in Aegir.

As I mentioned above, we are also using Varnish in Reliefweb.int for the sections which to not use SSL, since Varnish does not work with HTTPS. Drupal 7 supports using Varnish out of the box, whereas in Drupal 6 it was necessary to use Pressflow because of how sessions worked with anonymous users. Session creation for anonymous users is now lazy in Drupal 7, instead of automatic like it was in Drupal 6. Pressflow will still have several performance advantages to Drupal 7, and it may still make sense for your situation, however it is now possible to simply use Varnish with Drupal 7.

As with SSL, Varnish requires a handful of cache-related variables to be set in order for you to use it, and you can set those variables using the same mysite.drush.inc file. the ones you likely want are:

`$conf['reverse_proxy'] = TRUE;
$conf['reverse_proxy_addresses'] = array('127.0.0.1');
$conf['page_cache_invoke_hooks'] = FALSE;
$conf['cache'] = 1;
$conf['cache_lifetime'] = 0;
$conf['page_cache_maximum_age'] = 21600;`

A few of these variables are well documented in the default.settings.php file that ships with Drupal. The ‘page_cache_invoke_hooks’ variable is not documented in default.settings.php, and it is what allows a Cache-Control max-age to be set to greater than 0. The ‘cache’ variable is what tells Drupal to use its own page cache, and you can actually get around using the Drupal page cache by doing something like the following in a custom module:

`/**
 * Implementation of hook_init()
 */
function mymodule_init() {
  global $user;
  if (!$user->uid) {
    $age = variable_get('page_cache_maximum_age', 0);
    drupal_add_http_header("Cache-Control", "public, max-age=$age");
  }
}`

drupal_add_http_header will by default overwrite existing header keys, and by this time ‘Cache-Control’ will be set by core, so your custom module will overwrite it. You can then set ‘cache’ to 0 or FALSE on the settings page or in your settings file, and set the Cache-Control in this manner to make Drupal skip its persistent page cache but still send headers to make Varnish serve cached pages.

Currently there is no UI for making these tweaks. Perhaps an existing or new contrib module will make these settings easier to manage, but if you’re using Aegir you can use the above mysite.drush.inc technique or place them in the site’s local.settings.php file, as mentioned above. The choice of whether you put Drupal variable settings in a .drush.inc file versus the local.settings.php file comes down to whether you want those settings to be used on just a particular site or on several or all sites. You can use a single mysite.drush.inc file to manage like settings for as many Aegir-managed sites as you need.

What we're doing.

Latest