Firstly, lets get this out of the way: Varnish does not do SSL, at all and likely won’t ever.
Varnish is not a tool for connection managment, it’s a tool to cache web-pages and make them faster. That is all.
To get the speed benefits of Varnish over the SSL traffic we have to run an additional service to manage the SSL connections. Cue Nginx.
Our example configuration looks something like this, all on one server – but in real-life this should be distributed across dedicated machines.
- Nginx Public IP 74.207.248.164
- Varnish on Private IP 127.0.0.1:8080
- Apache on Private IP 127.0.0.1:80
Visual Overview
The HTTP requests from the internet hit Nginx, which passes some directly to Apache and some to Varnish (based on rules). Varnish, on cache-miss, will request to Apache. And Apache will likely hit the database.
Configuring Nginx
Please see our existing howto for Nginx.
The configuration there will be adjusted along these lines, again, update as necessary for your environment. Here, we just
http { server { listen 74.207.248.164:80; server_name _; location /c { root /var/www/css; } location /i { root /var/www/images; } location / { proxy_pass http://127.0.0.1:8080; } } } http { server { listen 74.207.248.164:443; server_name _; ssl on; ssl_certificate /etc/ssl/server.crt; ssl_certificate_key /etc/ssl/server.key; # ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; # ssl_ciphers HI:!aNULL:!MD5; location / { proxy_pass http://127.0.0.1:8080; } } }
Configure Varnish
This can be a typical Varnish configuration, what changes here is the listening and the back-end. Configure the sub vcl_*
routines as you normally would. Keep in mind however, some requests can be handled a the Nginx layer, so don’t need rules here (anymore).
backend default { .host = "127.0.0.1"; .port = "80"; .connect_timeout = 16s; .first_byte_timeout = 96s; .between_bytes_timeout = 8s; }
And remember to start varnish with -a 127.0.0.1:8080
, so it’s only listening on the local system, high-http port.
Configure Apache
I like to have Apache listen on the default HTTP port, then I explicitly set the hostname on the machine as well as in the Apache configuration. This way many of the running apps will think they are still publicly exposed and it helps them resolve their hostname. This is needed for example by Chiliproject, Redmine, Drupal, WordPress and many others.
<VirtualHost 127.0.0.1:80> ServerName edoceo.com ErrorLog /dev/null CustomLog /dev/null fuck-it <VirtualHost>
It should be noted here that the Apache configuration maybe able to operate with a much stripped configuration. As a result of sitting behind these other systems we can do away with many modules and remove some of the other rules which are designed for public consumption (such as Keep Alive).
Testing
We use curl to test.