9

I am trying to implement Flexible SSL provided by CloudFlare to my site.

Here is my nginx config:

# PHP-FPM upstream; change it accordingly to your local config!
upstream php-fpm {
    server 127.0.0.1:9000;
}

server {
    listen         80;
    server_name    example.com www.example.com;
    return         301 https://$server_name$request_uri;
}

server {
    ## Listen ports
    listen 443;

    # use _ if you want to accept everything, or replace _ with domain
    server_name example.com www.example.com;

    location / {
      #proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_set_header X_FORWARDED_PROTO https;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header  Host $http_host;
      proxy_set_header  X-Url-Scheme $scheme;
      proxy_redirect    off;
      proxy_max_temp_file_size 0;
    }

(...rest of config...)

However, when I try to connect to the website (Wordpress), I get a redirect loop (chrome: ERR_TOO_MANY_REDIRECTS). How do I configure nginx to prevent this?

AD7six
  • 2,989
Deqq
  • 141
  • 1
  • 1
  • 3

3 Answers3

29

Cloudflare's flexible ssl means the connection between cloudflare and your server is always over http:

connection is always http

Given this - the only server block in the question of relevance is this one:

server {
   listen         80;
   server_name    example.com www.example.com;
   return         301 https://$server_name$request_uri;
}

It should be obvious why that results in a redirect loop, there are 2 solutions to force https connections using their flexible ssl solution.

Use Cloudflare's page rules

If access to the server is exclusively via cloudflare you can use cloudflare's own page rules to modify responses for a domain, subdomain, or any url pattern:

Using cloudflare's page rules

One of the options is to force https:

Always use HTTPS

Test $http_x_forwarded_proto

There are times you may want to avoid using page rules (should be rare or transitional only), for these scenarios it's possible to test the forwarded protocol and redirect based on that:

server {
   listen         80;
   server_name    example.com www.example.com;

   if ($http_x_forwarded_proto = "http") {
     return 301 https://$server_name$request_uri;
   }

   ... directives to generate a response
}
AD7six
  • 2,989
5

This can fix the problem if you have the valid SSL certificate on your. [Crypto] box and select Full (strict) as in the image. enter image description here

Really no need to update the web server configuration file for Nginx.

prosti
  • 348
0

AD7six's answer is very good, though it appears there's a simpler solution that doesn't require page rules. I'm not sure if this is a new addition since the previous answers, but it should definitely be documented on this question, especially given that you only get 3 free page rules with Cloudflare at the time of writing.

When you have Flexible SSL turned on for a given domain, you can scroll down on the Crypto tab and enable the Always use HTTPS option. This option will seamlessly solve the redirect loop issue (explained thoroughly in AD7six's answer).

Cloudflare's "Always Use HTTPS" option

This option is confirmed working with nginx; furthermore, there should not be any server setup where this option does not work, provided that Flexible SSL is already enabled and works without issue.

Chad
  • 113
  • 4