Cloudflare和nginx:重定向过多

31

我正试图设置NGINX和Cloudflare。我在Google上阅读了相关信息,但没有解决我的问题。目前,我的cloudflare是活动的。我删除了cloudflare中的所有页面规则,但之前曾将domain.com和www.domain.com用于使用HTTPS。我认为这可能导致问题,所以我将其移除。这是我的default NGINX文件,目的是只允许通过域名访问,并禁止通过网站的IP值进行访问:

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

有什么可能出了问题?如果需要,我可以提供更多信息...


1
Cloudflare有不同的SSL模式-灵活、严格等-你尝试更改过吗?另外,你能展示一下curl -I http://www.domain.com的输出吗? - Denis Mysenko
@DenisMysenko 我收到了301状态码。我认为我改变了Cloudflare中的SSL选项,是的...我启用了HSTS,但也禁用了它,认为它可能会引起问题,但仍然无法正常工作。我运行了所有SSL模式,但仍然失败。我可能错过了什么? - Fane
@DenisMysenko 无头绪,Dennis? - Fane
好的,你还没有展示curl -I :)) HTTP状态码是不够的。 - Denis Mysenko
@DenisMysenko 它会在控制台中以文本文件的形式显示我的301页面的HTML内容... - Fane
7个回答

103

经过测试,我发现这个问题只与Cloudflare有关。在迁移到Cloudflare之前,我没有重定向问题。

在我的情况下,简单的修复方法如下。选择[Crypto]框并像图中一样选择Full (strict)。

输入图片说明

实际上,在采取任何其他措施之前,您可以先尝试此方法。


2
当我在Firebase上托管网站时,遇到了这个问题,因为Firebase默认使用https/ssl。这导致了一个无限循环。 - uniquelau
4
有所帮助,但无法理解问题。为什么启用限制模式可以解决问题? - varnothing
3
谢谢,非常有帮助。注意:在我的情况下,“Full”(而不是“Strict”)也能起作用,这对于您不想让CF在自签名或(“staging”例如certbot)证书情况下阻止访问您的站点可能很有用。 - alexvicegrab
3
为什么这个有效? - SkyPunch
1
我本该先在这里找。像个白痴一样搜索了两个小时,最后这个答案解决了我的问题。非常感谢你,老兄! - C4d
显示剩余7条评论

19
这些关于run-away重定向的问题经常出现!通常问题在于301 Moved Permanently响应经常被浏览器“永久”缓存,往往没有办法通过CtrlRCtrlShiftR来解决,除非清空整个缓存。(这是我通常更喜欢使用302 Found / 302 Moved Temporarily的原因之一,特别是在开发阶段,因为默认情况下302响应通常不会被缓存。)
此外,如果您以前使用过HSTS,并且它已经被浏览器成功地获取并在幕后安静地安装,并且从未明确清除或过期,那么浏览器将永远不会发出任何后续的http://请求,直到策略被清除 - 所有请求始终都会通过https://进行。
至于将CloudFlare放入混合中,是否减轻了首先需要有如此多不同的服务器定义和重定向的需求,因为您的IP地址应该被隐藏?我不确定为什么要隐藏您的IP地址在CloudFlare后面,但对于任何进行全球互联网扫描的人公开透露它所服务的域名有什么好处。
既然您已经运行了CloudFlare提供的所有“SSL模式”,我建议将所有301 permanent重定向更改为302临时redirect(如果不是首先完全删除所有这些),清除浏览器缓存,然后再尝试围绕SSL选项进行循环。 :-)

只是将我的重定向更改为302,问题就解决了。谢谢! - Evan Mattson
你的解决方案在我的情况下根本没有起作用,而且真的没有301的替代方案。就是这样。 - prosti
@prosti,我的解决方案已经为很多人解决了问题;OP在Cloudflare中遇到了一个循环所有选项的问题,但那时没有一个选项适用于他,因为……看看我的解决方案! - cnst

15

@prosti提供了解决方案。我在这里增加一些关于为什么会出现重定向循环的解释。

在Cloudflare CDN配置在Nginx服务器之前后,客户端不再直接访问Nginx。内容是由Cloudflare提供的中间代理获取的。问题的原因是这个代理没有遵循在Nginx上设置的重定向。或者你可以认为是硬编码。

与网页浏览器不同,它会遵循302/301重定向的行为。该代理的访问方式(通过HTTP或HTTPS访问我们VPS上的Nginx)是在Cloudflare仪表板 -> "SSL/TLS"中配置的。

输入图像描述

输入图像描述

解决方案是将加密级别配置为高于“Full”


真棒的解决方案! - Julien J
谢谢您的解释,现在我明白了这个解决方案背后的原因。 - oeter
我选择了全面严格的设置,现在Cloudflare可以将流量重定向到我的Rancher 443端口上的K8s仪表盘。非常感谢! - nobjta_9x_tq

3

Cloudflare会向原始服务器发送Cdn-Loop: cloudflare头信息。这个Cdn-Loop是标准的提交方式。 参见:https://datatracker.ietf.org/doc/html/rfc8586

这在nginx上可以实现。只有在未通过CDN访问时才会重定向到https:

server {
     # ..

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

还可以使用$http_cf_visitor

server {
        # ..

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

请参考 "If is evil":

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


3

解决重定向循环错误

解决导致访问者无法查看您的网站的重定向循环(too many redirects)错误。

Cloudflare SSL选项与您的源Web服务器不兼容

重定向循环的最常见原因是以下两种情况的组合:

  • 由您的源Web服务器执行的重定向
  • 与您的源执行的重定向不兼容的 Cloudflare SSL 选项

原因

Cloudflare “SSL/TLS” 应用程序中“概述”选项卡中的“Flexible” SSL 加密模式,将浏览器和 Cloudflare 网络之间的流量加密传输到 HTTPS。然而,启用“Flexible” SSL 选项时,Cloudflare会将未加密的 HTTP 请求发送到您的源Web服务器。当使用“Flexible” SSL 选项时,如果您的源Web服务器配置为将所有HTTP请求重定向到HTTPS,则会发生重定向循环。

当使用“Full”或“Full(strict)” SSL 选项时,也可能会发生重定向循环。唯一的区别在于,Cloudflare 通过 HTTPS 联系您的源Web服务器,如果您的源重定向 HTTPS 请求到 HTTP,则会导致重定向循环。

解决方法

在“SSL/TLS”应用程序中的“概述”选项卡中更新 Cloudflare SSL 选项。

  • 如果当前设置为“Flexible”,并且在源Web服务器上配置了SSL证书,请将其更新为“Full”。
  • 如果当前设置为“Full”,请尝试将其更新为“Flexible”。

“Flexible” SSL模式图

“Full” SSL模式图


0

前往页面规则部分,检查是否有“始终重定向到https”的规则。我默认启用了它。


1
所以.. 你是打开还是关闭了它? - Enrico
1
@Enrico 我关掉了。我猜是它在搞nginx的配置。让nginx来做https重定向。 在我的情况下,Cloudflare只处理DNS。其余的都交给nginx(SSL、重定向等)。 - Phạm Tuấn Anh

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接