Fix Varnish Mixed Content Errors + CloudFlare Flexible SSL + WordPress

Cloudflare Flexible SSL offers a free and simple way to add the HTTPS green lock to your WordPress site. There is a Flexible SSL plugin that will usually help resolve any problems like redirect loops. You may get broken CSS or mixed content errors when using Cloudflare's Flexible SSL with Varnish. This guide should help you resolve those issues.

Fix Varnish Mixed Content Errors + CloudFlare Flexible SSL + WordPress

The configurations for fixing Varnish mixed content errors with CloudFlare Flexible SSL are the same for Varnish versions 3, 4 and 5.

Varnish 3

Open your Varnish 3 vcl file

sudo nano /etc/varnish/default.vcl

In sub vcl_hash add this snippet. If you are missing a sub vcl_hash section you can add it before sub vcl_fetch.

sub vcl_hash {

    if (req.http.X-Forwarded-Proto) {
        hash_data(req.http.X-Forwarded-Proto);
    }
}

Ctrl+X, Y and Enter to Save and Exit

Test your Varnish 3 vcl syntax is valid

varnishd -C -f /etc/varnish/default.vcl

Reload Varnish service

sudo service varnish reload

Varnish 4

Open your Varnish 4 vcl file

sudo nano /etc/varnish/default.vcl

In sub vcl_hash add this snippet. If you do not have a sub vcl_hash section you will need to add the block. I usually put it before sub vcl_backend_response

sub vcl_hash {

    if (req.http.X-Forwarded-Proto) {
        hash_data(req.http.X-Forwarded-Proto);
    }
}

Ctrl+X, Y and Enter to Save and Exit.

Test your Varnish 4 vcl syntax is valid

varnishd -C -f /etc/varnish/default.vcl

Reload Varnish service

sudo service varnish reload

Time to configure WordPress for SSL termination behind a reverse proxy like Varnish.

Configure WordPress for SSL Termination

Open your wp-config.php file, you may need to do this via FTP if you don't have shell access to your server.

nano /var/www/wp-bullet.com/wp-config.php

Add this snippet to ‘catch' https, you should have salts for security which you can generate here.

When using WordPress behind Cloudflare or Varnish we need to tell WordPress to make some checks. The check is for the the X-Forwarded-Proto header with a scheme of https. If that https scheme is found WordPress will switch on for https instead of sending the request back. This will prevent redirect loops with Varnish and Cloudflare.

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

//Cloudflare Flexible SSL redirect loop fix
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
        $_SERVER['HTTPS']='on';
...

Ctrl + X, Y and Enter to Save and Exit.

Now start testing and your WordPress infinite redirect loop with Varnish or Cloudflare should be gone 🙂

Sources

Cloudflare Infinite Redirect Loop
Redirect Loop with Varnish and nginx HTTPS
Varnish Redirect Loop
WordPress wp-admin Redirect Loop