CloudFlare 不会让我只提供 HTTPS,它只有在我同时提供 HTTP 和 HTTPS 时才有效

CloudFlare will not let me serve only HTTPS, it works only if I serve HTTP along with HTTPS

我已经设置了一个简单的服务器来测试我的 TLS 证书,TLS 部分工作正常。我通过 CloudFlare 获得了我的 DNS。

我希望该网站保持匿名,所以我将域更改为 "example.com"。

这是简单服务器的代码:

package main

import (
    "log"
    "net/http"
)

var hostname = "example.com"

var key = "/srv/ssl/" + hostname + "-2017.03.20.key"
var cert = "/srv/ssl/ssl-bundle.crt"

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("TLS test"))
    })
    // go serveHTTP()
    // go redirectHTTP()
    serveHTTPS()
}

func serveHTTP() {
    if err := http.ListenAndServe(":80", nil); err != nil {
        log.Fatalf("ListenAndServe error: %v", err)
    }
}

func redirectHTTP() {
    err := http.ListenAndServe(":80", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        http.Redirect(w, r, "https://"+hostname+r.RequestURI, http.StatusMovedPermanently)
    }))
    if err != nil {
        log.Fatalf("ListenAndServe error: %v", err)
    }
}

func serveHTTPS() {
    log.Fatal(http.ListenAndServeTLS(":443", cert, key, nil))
}

现在如果我 运行 这样的服务器,然后转到 https://example.com 那么它就不起作用了。

但是,如果我将允许我提供 HTTP 服务的部分更改为:

go serveHTTP()
// go redirectHTTP()
serveHTTPS()

然后 HTTP 和 HTTPS 突然都可以用了。因此,如果我通过输入 http://example.comhttps://example.com 访问我的站点,两者都可以正常工作。

如果我注释掉 go serveHTTP() 并尝试像这样将 HTTP 重定向到 HTTPS:

// go serveHTTP()
go redirectHTTP()
serveHTTPS()

然后我在屏幕上看到这个:

如果我改回这个:

// go serveHTTP()
// go redirectHTTP()
serveHTTPS()

并且不是通过域名访问页面,而是通过ip地址访问页面,我当然会收到警告,因为证书不是颁发给ip地址,而是我使用的域名。

如果我坚持点击高级并添加异常,那么它就可以工作了。

所以实际上它是在端口 443 上提供服务的,但是试图通过域名访问该页面,让它通过 CloudFlare DNS,然后它不起作用。

即使我只使用 CloudFlare 作为 "DNS only" 也没关系:

或者我换成proxy,还是一样:

我已关闭缓存并使用开发人员模式,这样我应该可以从我的服务器获取 "real time responses"。

总而言之,由于我通过 CloudFlare 拥有我的 DNS,CloudFlare 不允许我在没有 HTTP 的情况下提供 HTTPS。我需要没有 HTTP 重定向的 HTTP 和 HTTPS。这真的很奇怪,我不知道如何解决这个问题。服务器通过 443 提供服务,因为正如我所展示的,如果我尝试通过 IP 地址访问该页面并添加安全例外,该页面实际上正在提供服务。

我能做什么?

当 Cloudflare 设置为灵活 SSL 模式时,the connection to the origin will always be over HTTP(不是 HTTPS)。

来自 Cloudflare 知识库:

You don't need to have an SSL certificate on your web server, but your visitors still see the site as being HTTPS enabled. This option is not recommended if you have any sensitive information on your website. This setting will only work for port 443->80, not for the other ports we support like 2053. It should only be used as a last resort if you are not able to setup SSL on your own web server, but it is less secure than any other option (even “Off”), and could even cause you trouble when you decide to switch away from it: How do I fix the infinite redirect loop...

要更改此设置,请转到 Cloudflare 仪表板中的加密选项卡,然后在 SSL 选项中将 "Flexible" 更改为 "Full (Strict)"(如果您使用的是 "Full"自签名证书)。