Varnishing Wordpress

Mixing Varnish and HTTPS is usually a pain in the ass. Even more when Wordpress is involved.

The common setup is to expose Nginx on the 443 port, let him handle the HTTPS connections, proxying to Varnish, and fetching back from Nginx - in HTTP - listening on a high port to serve regular contents. In the last step the request arriving to Wordpress is in plain HTTP, so the CMS generates HTTP URLs for included CSS and JS files, and the browser rejects to include such files when visiting an HTTPS page. Providing an HTTP-to-HTTPS redirect is not enough, as the browser just do not fetches at all the contents so cannot be redirected where desired.

The solution is to fool Wordpress to act as if requests comes from HTTPS: as here suggested, it is possible to add the line

if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS']='on';

to the wp-config.php file.

Be sure to attach the required header when bypassing the request, for example in the Nginx configuration:

server {
    listen                 443;

    ssl                    on;
    ssl_certificate        /path/to/yourdomain.com.crt; 
    ssl_certificate_key    /path/to/yourdomain.com.key;

    server_name            yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:8081;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https; # ADD THIS!!!
        proxy_set_header X-Forwarded-Port 443;
        proxy_set_header Host $host;
    }
}