不久前部署了一个Magento网站,访问时却直接打不开:
该网页无法正常运作 xxx.com将您重定向的次数过多
若要解决此问题,请尝试清除 Cookie.
ERR_TOO_MANY_REDIRECTS
我的网络架构是这样的:
网站部署在Nginx服务器上, 做了加密证书https。
怎么看都不像能导致无限重定向的样子。
通过检查注意到被重定向到了一个网址:104.21.14.130,再一查,原来是 CloudFlare Load Balancer!
这时我才想起来曾经在 Cloudflare 上开启了 DNS 服务。
Cloudflare
那么问题来了,会是 DNS 服务导致的无限重定向吗?
登录 Cloudflare 看了一下,SSL/TLS 加密模式 设置成了 flexible , 这下真相大白了!
已知 SSL/TLS加密模式 有如下选项:
关闭(不安全)
未应用加密
灵活
加密浏览器与 Cloudflare 之间的流量
完全
端到端加密,使用服务器上的自签名证书
完全(严格)
端到端加密,但服务器上需要有受信任的 CA 证书或 Cloudflare Origin CA 证书
由于应用的是 灵活 , 所以只加密了浏览器与 Cloudflare 之间的流量,并没有加密 Cloudflare 到 VPS 服务器的流量。
什么原理呢:
当域名的 DNS 记录指向 Cloudflare 后,所有的流量都将经过 Cloudflare 的代理服务器。
而在 Nginx 配置中,我使用了 rewrite 规则将 HTTP 请求重定向到 HTTPS。然而,由于 Cloudflare 代理了流量,它将请求转发给 VPS 服务器时,仍然是通过 HTTP 连接进行。这导致了一个循环:请求通过 HTTPS 到达 Cloudflare,然后被转发为 HTTP 请求到 VPS,然后 VPS 再次重定向到 HTTPS, 无限循环了。
问题清楚了,解决方案有如下选择:
在 Nginx 中取消 http 到 https 的 rewrite。
加密 Cloudflare 到 VPS 的流量。
在 Nginx 配置中使用代理服务器的原始协议(X-Forwarded-Proto)来判断是否启用 HTTPS,例如
if (KaTeX parse error: Double subscript at position 7: http_x_̲forwarded_proto… https://${server_name}$1 permanent;
}
这将确保当请求通过 HTTPS 到达 Cloudflare 时,Cloudflare 会在转发请求时设置 X-Forwarded-Proto 头部字段为 https,然后服务器将检查该字段,并决定是否进行重定向。
毫无疑问最简单高效的方法是直接将 SSL/TLS 加密模式 设置成 完全(严格) 就行了。
点击一下选项,测试网页,问题解决。
Conclusion
从这个事情需要认识到,在使用 Cloudflare 或者其它服务时,要确保 Nginx 配置和 Cloudflare 设置之间的一致性,以避免任何不必要的重定向或连接问题。