Heroku 的解决方法不再支持 Cloudflare 背后的 SSL ("Strict TLS in CDN not supported")?

Workaround for Heroku no longer supporting SSL behind Cloudflare ("Strict TLS in CDN not supported")?

几天前,我们在 Cloudflare 代理(橙色云,如果您知道 Cloudflare)背后的 1 个 Heroku 应用程序上收到错误 "Strict TLS in CDN not supported"。

基本上,客户端请求https://foo.example.com are proxied through Cloudflare, who then make the requests to https://foo.herokuapp.com,缓存响应,并将结果传回给客户端。请注意,整个链都通过 HTTPS。我们已将 Clouflare 配置为 通过 HTTPS 与终端服务器通信,我们不希望终端服务器通过 HTTP 发送响应。

Heroku 的政策似乎不再允许在检测到您位于已经处理 SSL 的代理之后时通过 SSL 提供服务。在过去一周,越来越多的应用程序开始显示此错误,我们不得不禁用 Cloudflare 的代理。 Here's their documentation关于这个,给出的理由是"because Cloudflare provides SSL certificates."

还有其他人遇到过这种情况并有解决方法吗?虽然 Cloudflare 仍然可以防止从客户端到 Cloudflare 的某些漏洞,但这会使其他漏洞从 Cloudflare 开放到终端服务器。

更新: 我收到 Heroku 的回复:

ACM can be used with Full or Flexible, and can be made to work with "Full (Strict)", but is not recommended. "Full (Strict)" mode ... can be used after ACM completes. If "Full (Strict)" is necessary we recommend a longer term, CA-issued certificate with a CSR signing process instead.

但是,我还没有发现以上内容是真的。在任一设置(Full 或 Strict)上,Heroku 总是报告上述错误。我已经从 Cloudflare 安装了原始证书来解决这个问题。

Heroku 似乎特别不希望您使用 ACM(自动证书管理),其中他们使用 Let's Encrypt 自动为您颁发证书。当您的证书不面向客户时,这是不必要的。

如果始终是 Cloudflare 与您的 Heroku 应用通信,我建议改用 "origin certificates"。 Cloudflare 可以专门为您生成一个证书和私钥,安装在您的原始服务器上,以便向 Cloudflare 进行身份验证。此证书由 Cloudflare 的私有 CA 签名,浏览器无法识别,只能由 Cloudflare 自身识别。这意味着您不必像使用普通 CA 证书那样跳过这么多环节来验证您的域和续订证书。

您可以告诉 Cloudflare 在 Cloudflare 仪表板中生成原始证书。您可以根据此文档将证书安装到 Heroku 中:

https://devcenter.heroku.com/articles/ssl#manually-uploading-certificates-and-intermediaries

请注意,这在 Heroku 端不需要 "ACM",因为您要携带自己的证书。我希望 Heroku 在这种模式下表现良好,但落后于 Cloudflare(如果不是……那将是 Heroku 中一个非常严重的缺陷)。

这是 Cloudflare 关于原始证书的一般文档:

https://support.cloudflare.com/hc/en-us/articles/115000479507-Managing-Cloudflare-Origin-CA-certificates

(免责声明:我实际上并没有在 Heroku 上尝试过这个,但我过去已经成功地在其他主机上使用了原始证书。)

我遇到了这个问题,我就是这样解决的。首先,我从 Heroku 中删除了我的证书,然后还删除了我的自定义域,然后我去了终端

  1. $ heroku certs:info --app myapp(确保我没有证书)

  2. $ heroku certs:auto:enable --app myapp (我这样做是为了好的措施,这创建了一个证书)

  3. heroku domains:add data.myapp.com --app data-myapp (我正在使用子域,这添加了我的自定义域)

  4. 将 DNS 详细信息添加到 Cloudflare,我将其设置为 DNS 而不是代理并且它起作用了。我把它设置回代理并且它起作用了,我想,问题是过程,首先使用终端,第二确保你有证书,然后再添加域名。

我希望这对某人有用。

我能够通过以下方式让 Heroku 颁发 ACM 证书:

  1. 为我的应用启用 ACM:heroku certs:auto -a my-app
  2. 转到 https://dashboard.heroku.com/apps/my-app/settings 并为 public-facing 域名添加 CNAME(例如 www.my-app.com)。记下私有 DNS 名称(例如 foo-bar-12345.herokudns.com
  3. 在 Cloudflare 中,将 www.my-app.com 的 CNAME DNS 条目添加到 foo-bar-12345.herokudns.com
  4. 在 Cloudflare 中,将 TLS 设置为“灵活”
  5. 稍等
  6. 在 Heroku 中,单击“更新 ACM 状态”
  7. 稍等
  8. 在 Cloudflare 中,将 TLS 设置回“严格”