31

I'm trying to set up NGINX and cloudflare. I've read about this on Google but nothing solved my problem. My cloudflare is active at the moment. I removed all page rules in cloudflare but before had domain.com and www.domain.com to use HTTPS. I thought this could be causing the problem so I removed it. Here is my default NGINX file, with purpose of allowing only access by domain name and forbid access by IP value of the website:

server{

  #REDIRECT HTTP TO HTTPS

  listen 80 default;
  listen [::]:80 default ipv6only=on; ## listen for ipv6
  rewrite ^ https://$host$request_uri? permanent;

}

server{

  #REDIRECT IP HTTPS TO DOMAIN HTTPS       

    listen 443;
    server_name numeric_ip;
    rewrite ^ https://www.domain.com; 

}

server{

  #REDIRECT IP HTTP TO DOMAIN HTTPS

    listen 80;
    server_name numeric_ip;
    rewrite ^ https://www.domain.com;

}

server {

         listen 443 ssl;
         server_name www.domain.com domain.com;
         #rewrite ^ https://$host$request_uri? permanent;
         keepalive_timeout 70;

         ssl_certificate     /ssl/is/working.crt;
         ssl_certificate_key /ssl/is/working.key;

         ssl_session_timeout 1d;
         ssl_session_cache shared:SSL:50m;

         #ssl_dhparam /path/to/dhparam.pem;

         ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
         ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM$
         ssl_prefer_server_ciphers on;

         add_header Strict-Transport-Security max-age=15768000;

         (...) more ssl configs

What could be off? I'll provide mroe information if needed...

Fane
  • 1,978
  • 8
  • 30
  • 58
  • 1
    Cloudflare has different SSL modes - flexible, strict, etc - did you try changing those? Also, can you show output of curl -I http://www.domain.com? – Denis Mysenko Feb 02 '16 at 03:41
  • @DenisMysenko I get a 301. I think I changed the ssl options in cloudflare, yes... I had HSTS enabled but also disabled it in thought it could be causing the problem but it still does not work. I ran through all ssl modes, still fails. What exactly could I be missing? – Fane Feb 02 '16 at 14:00
  • @DenisMysenko No idea, Dennis? – Fane Feb 03 '16 at 02:01
  • well, you haven't shown curl -I :)) HTTP status code is not enough – Denis Mysenko Feb 03 '16 at 03:13
  • @DenisMysenko it displays my 301 page in html, in the console, as a text file... – Fane Feb 03 '16 at 14:13

7 Answers7

99

After tryouts I found that this is only related to Cloudflare. Because I had no redirect problem before moving to Cloudflare.

In my case it was a simple fix like this. Select [Crypto] box and select Full (strict) as in the image.

enter image description here

Really, you can try this out first before any other actions.

prosti
  • 42,291
  • 14
  • 186
  • 151
  • 2
    I experienced this issue when hosting a site on Firebase, which serves over https/ssl by default. This was causing an infinite loop. – uniquelau Dec 16 '16 at 14:31
  • @sanjaypatel yes it does – Joaquín L. Robles May 24 '17 at 14:20
  • Experience this issue intermittently with GoDaddy. Thanks! – Marcel Gruber Jun 17 '17 at 21:40
  • 4
    It helped but couldn't understand the issue. Why enabling restrict mode fix the issue? – varnothing Jul 17 '17 at 09:38
  • 3
    Thanks, super-helpful. Note: in my case Full (without strict) also appeared to work, which might be useful if you don't want CF to block access to your site in case of self-signed or ("staging" e.g. certbot) certificates. – alexvicegrab Jul 23 '17 at 14:12
  • Thanks, that was exactly the answer I was looking for. Perfectly working, I needed to wait about 10 seconds and baaammm! :) – Drusantia Jul 28 '17 at 16:05
  • Jesus, I just spent an hour messing with my apache virtualhost config files... because of this one button. – Petr Nagy Feb 22 '18 at 20:29
  • 3
    WHY DOES THIS WORK? – SkyPunch Jul 29 '18 at 16:32
  • Thanks so much for this. Was quite confused cause I hadn't seen this before with sites I've routed through cloudflare, but this redirect loop was certainly perplexing. For folks curious about why this happens, maybe lemme know if you see commonalities. This essentially is my nginx conf: https://gist.github.com/ckuttruff/2ed2b46940a842fa901adf2d4f426817 My hypothesis is it might have to do with the redirect and certs being generated and not thinking it's hitting valid ssl so it keeps redirecting? def using certbot / letsencrypt as well – Christopher Kuttruff Nov 19 '18 at 03:23
  • See @Simba's answer below for explanation why this solution works. – oeter May 26 '22 at 18:04
  • Just a note, this tab is called SSL/TLS now. – Eamonn M.R. Jan 08 '23 at 05:22
  • 1
    I should've looked here first. Searched for 2 hours like an idiot and in the end, this answer solved it for me. Big thanks to you mate! – C4d Aug 20 '23 at 12:30
19

These questions with run-away redirects come up all the time!

Usually, the problem lies with the fact that 301 Moved Permanently responses are often cached within the browsers "for good", and there is often no way to CtrlR nor CtrlShiftR out of it, short of clearing the whole cache. (This is one of the reasons I often prefer 302 Found / 302 Moved Temporarily instead, especially during the development phase, because 302 responses are generally not cached at all by default.)

Additionally, if you've had HSTS in the past, and it was successfully fetched and quietly installed by the browser under the hood, and was never explicitly cleared nor expired yet, then the browser would never make any subsequent requests over http:// until and unless the policy is cleared -- all requests would always be over https://.

As for putting CloudFlare into the mix, doesn't it alleviate the need to have so many different server definitions and redirects in the first place, since your IP address is supposed to be hidden? I'm not sure what good it does to presumably hide your IP address behind CloudFlare, yet openly reveal the domain name it serves for anyone doing a global internet scan.

As you already ran through all the "SSL modes" offered by CloudFlare, I would suggest to change all your 301 permanent redirects to 302 temporary redirects (if not remove all of these in entirety in the first place), clear the browser's cache, and then try circling around the ssl options again. :-)

cnst
  • 25,870
  • 6
  • 90
  • 122
  • Just changing my redirect to a 302 fixed the problem for me. Thanks! – Evan Mattson Mar 17 '16 at 19:28
  • your solution simple didn't worked in my case, and really 301 doesn't have the alternative. that's what it is. – prosti Oct 01 '16 at 20:43
  • @prosti, my solution has worked for a whole lot of many people; the OP had a problem of circling though ALL of these options within cloudflare, and none of them worked for him at that time, because... see my solution! – cnst Oct 03 '16 at 00:40
13

@prosti provided the solution. I'll add some explanation here about why the redirection loop happens.

After Cloudflare CDN is setup in front of Nginx server. Clients don't have direct access to Nginx anymore. The content is fetched by the intermedia proxy provided by Cloudflare. The cause of the problem is this very proxy doesn't follow redirection set on Nginx. Or you can deem it's hardcoded.

Unlike a web browser who follows the 302/301 redirection. The behavior of the proxy, access the Nginx on our VPS by HTTP or HTTPS, is configured in Cloudflare Dashboard -> "SSL/TLS".

enter image description here

enter image description here

The solution is to configure the encryption level higher than "Full".

Simba
  • 23,537
  • 7
  • 64
  • 76
3

Troubleshooting redirect loop errors

Resolve redirect loop (too many redirects) errors that prevent visitors from viewing your website.

Cloudflare SSL options incompatible with your origin web server

The most common cause of redirect loops is due to a combination of

  • a redirect performed by your origin web server, and
  • a Cloudflare SSL option that is incompatible with the redirect performed by your origin.

Cause

The “Flexible” SSL encryption mode in the Cloudflare “SSL/TLS” app, “Overview” tab, encrypts traffic between the browser and the Cloudflare network over HTTPS. However, when the “Flexible” SSL option is enabled, Cloudflare sends requests to your origin web server unencrypted over HTTP. Redirect loops occur if your origin web server is configured to redirect all HTTP requests to HTTPS when using the “Flexible” SSL option.

Redirect loops may also occur when using the “Full” or “Full(strict)” SSL option. The only difference is that Cloudflare contacts your origin web server over HTTPS and the redirect loop occurs if your origin web server redirects HTTPS requests to HTTP.

Resolution

Update the Cloudflare SSL option in the “SSL/TLS” app, “Overview” tab.

  • If currently set to “Flexible”, update it to “Full” if you have an SSL certificate configured at your origin web server.
  • If currently set to “Full”, try updating it to “Flexible.”

“Flexible” SSL mode diagram

“Full” SSL mode diagram

3

Cloudflare sends the Cdn-Loop: cloudflare header to the original server. This Cdn-Loop is submitted as standard. See: https://datatracker.ietf.org/doc/html/rfc8586

This works on nginx. Only redirects to https if not accessed by/from CDN:

server {
     # ..

     if ($http_cdn_loop ~ "^$") {
         return 301 https://$host$request_uri;
     }
}

Can also use $http_cf_visitor:

server {
        # ..

        if ($http_cf_visitor ~ '{"scheme":"http"}') {
            return 301 https://$host$request_uri;
        }
}

See also "If is evil":

https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/

nggit
  • 611
  • 8
  • 8
0

Go to Page Rules section and check if you have an "always redirect to https" rule. I had it enabled by default.

  • 1
    So.. did you turn it on or off? – Enrico Apr 26 '21 at 14:38
  • 1
    @Enrico I turned off. I guess it was messing around with config from nginx. Let nginx do the https redirection. In my case Cloudflare only handle the DNS. The rest is for nginx (SSL, redirection, ...) – Phạm Tuấn Anh Apr 27 '21 at 03:17
-1

The support team of Cloudflare has given the cause and solution. It is clear and helpful.