https with Apache and Varnish

Hello everybody

Virtualmin is, IMHO, the best open-source solution for managing virtual servers.

I currently have a few VPS’s with the same configuration, managing dozens of domains for customers, mainly for wordpress websites: ubuntu 14.04 LAMP with Apache 2.4.7 php-fpm mod_event and Varnish 4.0.1.
It’s a very stable configuraton, allowing all the goodies of apache as an aplication server and varnish as a very fast cache for http connections.

However, the internet world is changing and now https begins to become the standard, specially with chrome 56 already telling visitors that http is unsafe. So https is the way to go.
And (kudos for that), virtualmin already integrates beautifully with LetsEncrypt, allowing SSL certificates for virtual servers in an easy and straightforward way, configuring apache for https. And everything works.

However, when running https, one loses the benefits of varnish, since it doesn’t support secure connections, thus having apache doing all the hard work.

I’ve seen a few workarounds for that, by installing proxies to forward https to varnish in http (nginx, HAProxy, Pound, Squid or Apache).
The most simple way , since it does not require a new piece of software, is to go for apache.
And I found a configuration that does jut that, thanks to DavidBU (see his solution here: http://davidbu.ch/mann/blog/2015-03-20/varnish-and-https-apache.html , it’s quite well explained)

Essentially, one gets a virtual server configuration like this (assuming Varnish is listening to port 80):

#/etc/apache2/sites-available/example.com-ssl

ServerName www.example.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:80/
RequestHeader set X-Forwarded-Port "443"
RequestHeader set X-Forwarded-Proto "https"

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/example.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/example.com.key
SSLCertificateChainFile /etc/apache2/ssl/example.com.chain
That would be perfect, but requires to be done manually on each virtual server, since, per present virtualmin configuration, the default https configuration per virtual server is something like this: SuexecUserGroup xxx xxxxx ServerName server.domain.tld

… (plus a lot of stuff related to directory indexes, document root, autoconfiguration,awstats and webmin and virtualmin access)…

SSLEngine on
SSLCertificateFile /home/“server”/ssl.cert
SSLCertificateKeyFile /home/“server”/ssl.key

My question is: is it possible to have virtualmin configuring apache as a https proxy and correctly identifying the ssl certificate for each virtual server domain, thus allowing to have https with varnish? If so, where can I change it and prevent it to be overwritten in a virtualmin upgrade?

Thanks in advance and best regards

any updates on this?

Did you ever get varnish and SSL to work? I’m really having a difficult time with it.

Hi #apessoa

Hope all is well. I was hoping that if you have a moment you could update your solution and configuration.

Also if anyone has a guide on how to install / setup Varnish with Virtualmin, that would be most useful.

All the best

Brad

Use Pound for doing SSL offloading. It is the best solution because it is a light program and works great in front of Varnish. Once you do the following setup Apache will stop dealing with SSL from now on and you will increase webserver speed. Pound will listen on both 80 and 443 ports then will pass the traffic flow to Varnish and varnish passes to Apache.

-> POUND (EXTERNAL_IP:80 and 443) -> VARNISH (127.0.0.1:8090) -> APACHE (EXTERNAL_IP:8080)

Here is the important part of configuration file for Pound (/etc/pound/pound.cfg)

ListenHTTP Address YOUR_EXTERNAL_IP Port 80
##  If  1  force Pound to change the Location: and Content-location:
##  headers in responses. If they point to the back-end itself or to
##  the  listener (but with the wrong protocol) the response will be
##  changed to show the virtual host  in  the  request.  Default:  1
##  (active).  If the value is set to 2 only the back-end address is
##  compared; this is useful for redirecting a request to  an  HTTPS
##  listener on the same server as the HTTP listener.
RewriteLocation 0

##  If  1 force Pound to change the Destination: header in requests.
##  The header is changed to point to the back-end itself  with  the
##  correct protocol. Default: 0.
#RewriteDestination 1

## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
#xHTTP 0
xHTTP 2

# Use this header for RewriteCond in .htaccess files
AddHeader "Ssl-Offloaded: off"

Service
    BackEnd
        ## APACHE2
        Address YOUR_EXTERNAL_IP
        Port 8080

        ## VARNISH
        #Address 127.0.0.1
        #Port 8090
    End
End

End

ListenHTTPS
Address YOUR_EXTERNAL_IP
Port 443
Cert “/etc/cert/MYDOMAIN-ssl.pem”
SSLAllowClientRenegotiation 0
SSLHonorCipherOrder 1
Disable SSLv3
Ciphers “ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-HA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:!ECDHE-RSA-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DES-CBC3-SHA:!DSS”

##  If  1  force Pound to change the Location: and Content-location:
##  headers in responses. If they point to the back-end itself or to
##  the  listener (but with the wrong protocol) the response will be
##  changed to show the virtual host  in  the  request.  Default:  1
##  (active).  If the value is set to 2 only the back-end address is
##  compared; this is useful for redirecting a request to  an  HTTPS
##  listener on the same server as the HTTP listener.
RewriteLocation 0

##  If  1 force Pound to change the Destination: header in requests.
##  The header is changed to point to the back-end itself  with  the
##  correct protocol. Default: 0.
#RewriteDestination 1

##  Behave  like an HTTP/1.0 server for HTTPS clients. If this value
##  is 0 disable the check. If the value is 1 do not allow  multiple
##  requests on SSL connections. If the value is 2 (default) disable
##  multiple requests on SSL  connections  only  for  MSIE  clients.
#NoHTTPS11 0

# Use this header for RewriteCond in .htaccess files
AddHeader "Ssl-Offloaded: on"

## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
#xHTTP 0
xHTTP 2

Service
    BackEnd
        ## APACHE2
        Address YOUR_EXTERNAL_IP
        Port 8080

        ## VARNISH
        #Address 127.0.0.1
        #Port 8090
    End
End

End

Here is a resource for Magento users who are using Turpentine extension. You will see my name at the end. It is a basic tutorial. Pound configuration I posted here is gold. Modern ciphers, SSL offloaded and many more with a small nice program named Pound.

https://github.com/nexcess/magento-turpentine/wiki/SSL_Support

You can bypass Varnish just changing Backend in pound.cfg file. If something goes wrong you connect Pound with Apache very easy in a few seconds.

hi ADDISON74

Is there any way you could help us with some instructions on how to implement Varnish and Pound on an Apache server?

Thanks

@impe81 - There is a plenty of tutorials on Internet related to Pound - Varnish - Apache. Just use Google finding a few. Then use my previous post to understand Pound configuration. Initially start with Varnish (IP:80) -> Apache (IP:8080), then Pound (IP:80) -> Varnish (IP:8080) -> Apache (IP:8081). You need a virtual machine to do some test before going in production. If you are familiar with Docker there are containers already for Varnish + Apache combination.

Thank you. I have searched quite a bit and couldn’t find anything that was exactly what I was looking for. The only installation tutorial of Varnish + Pound I found is this one https://web.archive.org/web/20170626220148/http://blog.ajnicholls.com/varnish-apache-and-https however after following the instructions It doesn’t work, at least for me. I was able to run Varnish + Apache before but adding Pound makes things a bit more confusing.