{"id":418,"date":"2015-11-17T16:51:25","date_gmt":"2015-11-17T16:51:25","guid":{"rendered":"http:\/\/onlinelab.info\/?p=418"},"modified":"2015-11-17T16:51:25","modified_gmt":"2015-11-17T16:51:25","slug":"why-pound-is-awesome-in-front-of-varnish","status":"publish","type":"post","link":"https:\/\/www.asianux.org.vn\/index.php\/2015\/11\/17\/why-pound-is-awesome-in-front-of-varnish\/","title":{"rendered":"Why Pound is awesome in front of Varnish"},"content":{"rendered":"<p>We all know <a href=\"https:\/\/www.varnish-cache.org\/\" target=\"_blank\" rel=\"noopener\">Varnish<\/a> is awesome. I went as far as\u00a0<a href=\"https:\/\/www.adammalone.net\/post\/varnish-beginners\" target=\"_blank\" rel=\"noopener\">presenting a topic on Varnish<\/a> then <a href=\"https:\/\/www.adammalone.net\/post\/explaining-varnish-beginners\" target=\"_blank\" rel=\"noopener\">writing about it<\/a>. This is\u00a0a known fact.<\/p>\n<p>However, what happens to all that caching goodness when you want to run your entire site over SSL? Out of the box, Varnish doesn&#8217;t support it. While I&#8217;ve heard some mention that not supporting SSL is an oversight,<a href=\"https:\/\/www.varnish-cache.org\/docs\/trunk\/phk\/ssl.html\" target=\"_blank\" rel=\"noopener\">there exists some very sound reasoning for why\u00a0<em>not<\/em><\/a>.<\/p>\n<p>So how do people terminate SSL?<\/p>\n<ul>\n<li>Nginx &#8211; <a href=\"https:\/\/docs.acquia.com\/cloud\/arch\" target=\"_blank\" rel=\"noopener\">How Acquia, my employer does it<\/a><\/li>\n<li>Stunnel\u00a0&#8211; <a href=\"https:\/\/www.stunnel.org\/index.html\" target=\"_blank\" rel=\"noopener\">Software I&#8217;m fond of<\/a><\/li>\n<li>Pound &#8211; My preferred method<\/li>\n<li>Apache &#8211; <a href=\"http:\/\/httpd.apache.org\/docs\/2.2\/mod\/mod_ssl.html\" target=\"_blank\" rel=\"noopener\">mod_ssl<\/a><\/li>\n<\/ul>\n<h2>What is Pound?<\/h2>\n<p>Without copying exactly what&#8217;s on the <a href=\"http:\/\/www.apsis.ch\/pound\" target=\"_blank\" rel=\"noopener\">Pound documentation<\/a>, or the<a href=\"http:\/\/en.wikipedia.org\/wiki\/Pound_(networking)\" target=\"_blank\" rel=\"noopener\">Wikipedia entry about Pound<\/a>, it&#8217;s essentially a reverse proxy, SSL terminator and load balancer but\u00a0<strong>NOT<\/strong>\u00a0a webserver. It&#8217;s small, easy enough to install and has minimal configuration. Stunnel is similarly simple, but since I have quite extensive experience using Stunnel, I decided to learn something new.<\/p>\n<p>On my load balancing servers, Pound listens on port 443 and Varnish listens on port 80. When traffic comes in on port 443, it hits Pound, gets decrypted using my server certificate and then gets passed to Varnish on port 80. By putting <strong>all<\/strong>\u00a0traffic through Varnish, I&#8217;m able to take advantage of its caching ability for both HTTP and HTTPS traffic.<\/p>\n<p>It&#8217;s <em>almost<\/em>, that simple. I had to make some minor changes to my <a href=\"https:\/\/www.varnish-cache.org\/docs\/3.0\/reference\/vcl.html\" target=\"_blank\" rel=\"noopener\">VCL<\/a>\u00a0to receive and cache mixed mode traffic. Prior to these changes, I would sometimes deliver resources using the HTTP schema to pages delivered over HTTPS. This had the understandable effect of causing my browser to complain about insecure resources.<\/p>\n<h2>Getting Varnish and Pound to play nicely<\/h2>\n<p>Realising that we need to handle HTTP\/HTTPS traffic differently in Varnish, even though it all comes in on port 80, I decided to use a separate cache hash key for each. Varnish uses hashes of the URI as a key to store and look up data by. My VCL\u00a0implements the <a href=\"https:\/\/www.varnish-software.com\/static\/book\/VCL_functions.html#vcl-vcl-hash\" target=\"_blank\" rel=\"noopener\">vcl_hash<\/a>subroutine to detect HTTPS traffic and alter the hash key. We add a header in Pound to tell Varnish that the traffic came in over SSL and then watch the magic happen.<\/p>\n<p><strong>pound.cfg<\/strong><\/p>\n<div class=\"geshifilter\">\n<pre class=\"text geshifilter-text\">ListenHTTPS\n  Address 0.0.0.0\n  Port 443\n  HeadRemove \"X-Forwarded-Proto\"\n  AddHeader \"X-Forwarded-Proto: https\"\n  Cert \"\/etc\/ssl\/certs\/adammalone.net.pem\"\nEnd\n\u00a0\nService\n  HeadRequire \"Host:.*adammalone.net.*\"\n    Backend\n      Address 127.0.0.1\n      Port 80\n    End\nEnd<\/pre>\n<\/div>\n<p><strong>default.vcl &#8211; vcl_hash {}<\/strong><\/p>\n<div class=\"geshifilter\">\n<pre class=\"text geshifilter-text\">sub vcl_hash {\n  hash_data(req.url);\n  if (req.http.host) {\n    hash_data(req.http.host);\n  } else {\n    hash_data(server.ip);\n  }\n  # Use special internal SSL hash for https content\n  # X-Forwarded-Proto is set to https by Pound\n  if (req.http.X-Forwarded-Proto ~ \"https\") {\n    hash_data(req.http.X-Forwarded-Proto);\n  }\n  return (hash);\n}<\/pre>\n<\/div>\n<p>The <a href=\"https:\/\/www.varnish-cache.org\/docs\/trunk\/reference\/vcl.html#functions\" target=\"_blank\" rel=\"noopener\">hash_data<\/a> function allows us to add further information to the hash. By adding &#8216;https&#8217; to the host and uri information, we&#8217;re altering the hash in such a way that it is different from just the host + uri that an\u00a0http request would use.<\/p>\n<p>I&#8217;ve also attached a downloadable copy of my full Pound config\u00a0and the puppet manifest that generates it for people who are interested in replicating this functionality. I&#8217;m using my Pound puppet class located at\u00a0<a href=\"https:\/\/github.com\/typhonius\/puppet-pound\" target=\"_blank\" rel=\"noopener\">typhonius\/puppet-pound<\/a>,\u00a0a fork of <a href=\"https:\/\/github.com\/mrintegrity\/puppet-pound\" target=\"_blank\" rel=\"noopener\">mrintegrity\/puppet-pound<\/a>.<\/p>\n<h2>Drupal configuration<\/h2>\n<p>The final thing to do is to inform Drupal it needs to be in SSL mixed mode and to enter a small snippet in my settings.php so it can be turned on or off based on the incoming request. If Varnish is running on the same server as your Drupal installation, you&#8217;ll need to replace www.xxx.yyy.zzz with 127.0.0.1. Otherwise it&#8217;ll be the IP of your load balancing server.<\/p>\n<div class=\"geshifilter\">\n<pre class=\"text geshifilter-text\">\/\/ Varnish Settings\n$conf['reverse_proxy'] = TRUE;\n$conf['reverse_proxy_addresses'] = array('www.xxx.yyy.zzz');\n$conf['reverse_proxy_header'] = 'HTTP_X_FORWARDED_FOR';\n$conf['page_cache_invoke_hooks'] = FALSE;\n\u00a0\nif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &amp;&amp; $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {\n  $_SERVER['HTTPS'] = 'on';\n}<\/pre>\n<\/div>\n<p>This is how I allow SSL through Varnish, if you do it differently, <a href=\"https:\/\/www.adammalone.net\/post\/why-pound-awesome-front-varnish#comment-form\" target=\"_blank\" rel=\"noopener\">add a comment<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We all know Varnish is awesome. I went as far as\u00a0presenting a topic on Varnish then writing about it. This is\u00a0a known fact. However, what happens to all that caching goodness when you want to&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,3],"tags":[],"class_list":["post-418","post","type-post","status-publish","format-standard","hentry","category-he-thong","category-linux"],"_links":{"self":[{"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/posts\/418","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/comments?post=418"}],"version-history":[{"count":0,"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/posts\/418\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/media?parent=418"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/categories?post=418"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.asianux.org.vn\/index.php\/wp-json\/wp\/v2\/tags?post=418"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}