WordPress redirect loop with CloudFlare Flexible SSL

If you have ever ran into this issue you’ll find that you are not alone. There are a number of plugins available that supposedly fix the problem but if you’re like me you hate to install to many plugins. If you are using Nginx/PHP-FPM you can forgo the plugin route and fix this issue before WordPress gets the incoming request. When CloudFlare sends your server a request they also send some additional headers. The one we need to watch for is $_SERVER[“HTTP_X_FORWARDED_PROTO”] which will have a value of “https” for secure requests or “http” insecure requests. With a flexible SSL setup the client connects to CloudFlare’s servers via SSL https while CloudFlare connects to your server over non SSL http. We need inform PHP that content is actually being delivered under SSL. To do this we’ll map the incoming header to a variable in our Nginx configuration.

map $http_x_forwarded_proto $cf_proto {
        default "none";
        http  "http";
        https "https";
}
server {
        listen 80;
...
...
        # optional - redirect non SSL requests to SSL location
        if ($cf_proto = "http") {
                return 301 https://$http_host$request_uri;
        }
...
...
        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_param HTTPS $cf_https;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
        }
}

With the above setting PHP will show $_SERVER[“HTTPS”] as “on”.

Since CloudFlare is a proxy solution your server does not assign the visitor IP address in PHP super global $_SERVER[“REMOTE_ADDR”]. This to can be adjusted in a similar manner.

        set $cf_connecting_ip $remote_addr;
        if ($http_cf_connecting_ip) { 
                set $cf_connecting_ip $http_cf_connecting_ip;
        }

        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_param REMOTE_ADDR $http_cf_connecting_ip;
                fastcgi_param HTTPS $cf_https;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
        }

Now PHP should show $_SERVER[“REMOTE_ADDR”] === $_SERVER[“HTTP_CF_CONNECTING_IP”] and you have avoided yet another plugin in WordPress.

Be the first to write a comment.

Your feedback