26

I have a website running on a LEMP stack. I have enabled cloudflare with the website. I am using the cloudflare flexible SSL certificate for https. When i open the website in chrome it shows website redirected you too many times and in firefox has detected that the server is redirecting the request for this address in a way that will never complete. I have tried to see answers of other questions but none of them seem to solve the problem. NGINX conf file:-

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name mydomain.com www.mydomain.com;
    return 301 https://$server_name$request_uri;
}
server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    root /var/www/html;

    index index.php index.html index.htm index.nginx-debian.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

I would be highly grateful if anyone can point out what I am doing wrong.

mbomb007
  • 3,446
  • 2
  • 35
  • 61
  • I'm assuming you are using Cloudflare's Flexible SSL option for serving HTTPS content as you do not have a secure server block in your Nginx config. Take a look at https://serverfault.com/questions/653976/redirect-loop-using-cloudflares-flexible-ssl/654018#654018 – Anand Bhat Jan 11 '17 at 05:30

4 Answers4

68

Since you are using cloudflare flexible SSL your nginx config file wll look like this:-

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  server_name mydomain.com www.mydomain.com;

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

  root /var/www/html;

  index index.php index.html index.htm index.nginx-debian.html;

  location / {
     try_files $uri $uri/ =404;
  }

  location ~ \.php$ {
     include snippets/fastcgi-php.conf;
     fastcgi_pass unix:/run/php/php7.0-fpm.sock;
  }

  location ~ /\.ht {
     deny all;
  }
}
Kushal
  • 766
  • 7
  • 14
  • 1
    If I toggle/bypass cloudflare then the config mentioned in the question works. Assuming a scenario in which we have letscrypt SSL certificate, can we have a config that works in both scenarios? – Sandeep Jun 14 '17 at 12:48
  • Finally you solve my problem, I was struggling last few days.+1 – Mohammad Sayeed Mar 30 '18 at 13:26
  • This fixed my problem as well, but now when I run a PageSpeed Insight test, I receive the error `exceeded more than 10 redirects` .. anyway to fix this? – SuperVeetz May 16 '18 at 07:54
  • you save my day. – Manish Yadav Apr 01 '19 at 12:49
  • For those not using CloudFlare and ending up here for solution (like me) - You need to listen on Port 443 as well, and provide path to SSL certificate and private key like this: `ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key;` – Qumber Jun 08 '20 at 09:44
  • Cloudflare SSL/TLS settings caught me out once again. Thanks! – Callum Kerr Jul 16 '20 at 23:54
  • I had to use `$host` instead of `$server_name`. This is also best practice, because they aren't always the same, and `$host` takes everything into account. – mbomb007 Mar 05 '21 at 16:57
  • Might recommend using `return 301 https://$host$request_uri;` (`$host` instead of `$server_name`). Super helpful answer and thanks so much – groovenectar Apr 26 '22 at 23:13
13

Kushal's reasoning is correct. Since you are using "Flexible" SSL between Cloudflare and your origin, you get into this redirect loop.

This isn't ideal as traffic between Cloudflare and your origin is insecure. The best option is to have traffic encrypted.

Go into Cloudflare's Dashboard, select Crypto, then choose a different SSL option that meets your needs. I'm using Full (strict) since I have the certs installed via let's encrypt.

I would also suggest using https://nginxconfig.io/ to generate your config.

From Cloudflare's Help:

Why isn’t my site working over HTTPS? If you have recently signed up for Cloudflare, and your certificate status above shows “Authorizing Certificate”, HTTPS is not yet available for your site because Cloudflare does not have a certificate for it. Provisioning typically takes around 15 minutes for paid plans and up to 24 hours for Free. Contact Support if you do not have a certificate after that time. If the status above shows “Active Certificate” there are several other common problems that can appear when accessing your site over HTTPS.

What SSL setting should I use? This setting controls how Cloudflare’s servers connect to your origin for HTTPS requests. We recommend enabling the Full SSL (Strict) setting if possible. Common use cases for each are:

Off: No visitors will be able to view your site over HTTPS; they will be redirected to HTTP.

Flexible SSL: You cannot configure HTTPS support on your origin, even with a certificate that is not valid for your site. Visitors will be able to access your site over HTTPS, but connections to your origin will be made over HTTP. Note: You may encounter a redirect loop with some origin configurations.

Full SSL: Your origin supports HTTPS, but the certificate installed does not match your domain or is self-signed. Cloudflare will connect to your origin over HTTPS, but will not validate the certificate.

Full (strict): Your origin has a valid certificate (not expired and signed by a trusted CA or Cloudflare Origin CA) installed. Cloudflare will connect over HTTPS and verify the cert on each request.

hyprnick
  • 2,553
  • 2
  • 20
  • 18
13

I tried

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

But this not allways redirected. Manually write address in browser with begining http:// and nginx not redirected. But using $scheme it's working even manually entering http:// So (for my site) is always working variant:

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

P.S. sorry for my english :(

Freethinker
  • 127
  • 1
  • 4
2

The answer from Kushal is right. I had the same problem as yours.

I tried both solutions:

  1. taking the configuration from Kushal
  2. choosing in Cloudflare from "Flexible" to "Full (strict)" and keep your current configuration
zhou gong
  • 31
  • 2
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 07 '22 at 17:40
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/30763176) – kirjosieppo Jan 12 '22 at 21:56