Mercury (Varnish) with SSL only traffic?

Events happening in the community are now at Drupal community events on www.drupal.org.
cookiesunshinex's picture

Our use case for our Mercury install has suddenly changed in our architecture and it has been determined that we will use SSL only traffic.

I've been trying to read up on how to get Varnish to interact with HTTPS. It appears, to my dismay, that Varnish does not play well with SSL.

I've found this thread:
Enforcing SSL Behind AWS Load balancer
http://groups.drupal.org/node/115284

and this blog post
Setting up Pressflow and Varnish to work with HTTP and HTTPS
http://singlemindconsulting.com/blog/christoler/2010/8/setting-pressflow...

So my questions are:
1) Is it oxymoronic to try and cache SSL traffic in the first place? Is it something that just shouldn't be done?

2) Are the approaches to using Varnish with HTTPS as mentioned in the two links above really best practices. What would be the recommended method?

3) If disabling Varnish is going to be the final answer, what is the best approach to doing so. I recently asked how to disable Varnish for development purposes and got this:
http://groups.drupal.org/node/118834
http://groups.drupal.org/node/113519

I wasn't able to correctly load many of my drupal pages (ie. menu items didn't appear on some pages, etc.) after stopping the Varnish service and loading the pages through port 81 which is what Apache2 is set to run at.

I'm using Mercury 1.1beta. This is an Amazon instance and we used the public Mercury AMI to start the instance.

Comments

Yes, varnish is HTTP only. If

soyarma's picture
  1. Yes, varnish is HTTP only. If you need https, then I'd recommend using something like NGINX for 443 and Varnish for 80
  2. If you want to essentially redirect all port 80 traffic to port 443, then a simple way would be to write a redirect in your site's .htaccess file. Though technically the securepages module should write a 302 redirect for people hitting pages on port 80 that you have requested to use 443
  3. A pretty easy way to pseudo-disable varnish is to go into the recv section, and at the very top, add this: return(pipe). That will cause varnish to pass every request straight through with no molestation.

Pound is an option if you

threading_signals's picture

1) Depends on how secure you want certain sessions to be.

2) Pound is an option if you have the technical support or knowhow: http://www.apsis.ch/pound/

Get rid

perusio's picture

of Varnish altogether and use Nginx. It has a cache that works in both SSL and non SSL sockets.

That's my suggestion.

Opps, just encountered this

AndyW's picture

Opps, just encountered this Varnish and HTTPS problem, but before I find a solution I want to understand why it works perfectly well on the admin pages but not on the front pages. I thought perhaps it was a cookie issue, but it's not. Does anybody have any ideas?

This is my default file:

backend default {
  .host = "127.0.0.1";
  .port = "8080";
  .connect_timeout = 600s;
  .first_byte_timeout = 600s;
  .between_bytes_timeout = 600s;
}

sub vcl_recv {
  if (req.request != "GET" &&
    req.request != "HEAD" &&
    req.request != "PUT" &&
    req.request != "POST" &&
    req.request != "TRACE" &&
    req.request != "OPTIONS" &&
    req.request != "DELETE") {
      /* Non-RFC2616 or CONNECT which is weird. /
      return (pipe);
  }

  if (req.request != "GET" && req.request != "HEAD") {
    /
We only deal with GET and HEAD by default /
    return (pass);
  }

  // Remove has_js and Google Analytics cookies.
  set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s
)(__[a-z]+)=[^;]", "");

  // To users: if you have additional cookies being set by your system (e.g.
  // from a javascript analytics file or similar) you will need to add VCL
  // at this point to strip these cookies from the req object, otherwise
  // Varnish will not cache the response. This is safe for cookies that your
  // backed (Drupal) doesn't process.
  //
  // Again, the common example is an analytics or other Javascript add-on.
  // You should do this here, before the other cookie stuff, or by adding
  // to the regular-expression above.


  // Remove a ";" prefix, if present.
  set req.http.Cookie = regsub(req.http.Cookie, "^;\s
", "");
  // Remove empty cookies.
  if (req.http.Cookie ~ "^\s$") {
    unset req.http.Cookie;
  }

  if (req.http.Authorization || req.http.Cookie) {
    /
Not cacheable by default */
    return (pass);
  }

  // Skip the Varnish cache for install, update, and cron
  if (req.url ~ "install.php|update.php|cron.php") {
    return (pass);
  }

  // Normalize the Accept-Encoding header
  // as per: http://varnish-cache.org/wiki/FAQ/Compression
  if (req.http.Accept-Encoding) {
    if (req.url ~ ".(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
      # No point in compressing these
      remove req.http.Accept-Encoding;
    }
    elsif (req.http.Accept-Encoding ~ "gzip") {
      set req.http.Accept-Encoding = "gzip";
    }
    else {
      # Unknown or deflate algorithm
      remove req.http.Accept-Encoding;
    }
  }

  // Let's have a little grace
  set req.grace = 30s;

  return (lookup);
}

sub vcl_hash {
   if (req.http.Cookie) {
     set req.hash += req.http.Cookie;
   }
}

// Strip any cookies before an image/js/css is inserted into cache.
sub vcl_fetch {
   if (req.url ~ ".(png|gif|jpg|swf|css|js)$") {
     // For Varnish 2.1 or later, replace obj with beresp:
     // unset beresp.http.set-cookie;
     unset obj.http.set-cookie;
   }
}

sub vcl_error {
   // Let's deliver a friendlier error page.
   // You can customize this as you wish.
   set obj.http.Content-Type = "text/html; charset=utf-8";
   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>
       <title>"} obj.status " " obj.response {"</title>
       <style type="text/css">
       #page {width: 400px; padding: 10px; margin: 20px auto; border: 1px solid black; background-color: #FFF;}
       p {margin-left:20px;}
       body {background-color: #DDD; margin: auto;}
       </style>
     </head>
     <body>
     <div id="page">
     <h1>Page Could Not Be Loaded</h1>
     <p>We're very sorry, but the page could not be loaded properly. This should be fixed very soon, and we apologize for any inconvenience.</p>
     <hr />     <h4>Debug Info:</h4>
     <pre>
Status: "} obj.status {"
Response: "} obj.response {"
XID: "} req.xid {"
</pre>
       <address><a href="http://www.varnish-cache.org/">Varnish</a></address>
       </div>
     </body>
    </html>
    "};
    deliver;
}

Okay worked it out - the

AndyW's picture

Okay worked it out - the Twitter widget was preventing the SSL from working. Well that's a new one

High performance

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: