去ListenAndServeTLS握手

时间:2016-06-17 09:51:35

标签: ssl go

目前。我有以下这一行(效果很好)

http.ListenAndServeTLS(":"+Config.String("port"), Config.Key("https").String("cert"), Config.Key("https").String("key"), router)

当我尝试将端口设置为443而不是例如8080时出现问题。我在浏览器上出现以下错误(Chrome)

  

此网站无法提供安全连接。

     

www.example.com发送了

     

无效回复。 ERR_SSL_PROTOCOL_ERROR

我不确定我做错了什么,或者我不应该在端口443上运行服务器?

1 个答案:

答案 0 :(得分:2)

我可以想到发生这种情况的两个原因

  • 您的服务器应用程序无权访问端口443
  • 您的浏览器正在尝试通过端口80
  • 访问您的服务器

由于标记的标签无法解决第一个问题,因此本答案将涵盖第二种情况。

出现此问题是因为默认情况下,当您键入www.domain.com这样的地址时,您的浏览器会尝试使用端口80上的http协议联系url域,这是Golang ListenAndServeTLS returns data when not using https in the browser的已知行为

现在,如果您使用正确的方案(如https://www.domain.com)在浏览器中输入完整的URL,浏览器将通过端口443接近服务器并启动与服务器的TLS握手,从而呈现正确的数据。 / p>

现在,您知道这一点,但不是您的用户。如果您的用户每次尝试仅使用您的域作为URL访问您的Web应用程序时,会因SSL握手错误而收到通知,这将非常令人沮丧。

为了避免这个问题,您可以使用端口上的服务器启动一个go例程:80(或8080),使用这段简单的代码将所有请求重定向到端口443:

// redir is a net.Http handler which redirects incoming requests to the 
// proper scheme, in this case being https
func redir(w http.ResponseWriter, req *http.Request) {
    hostParts := strings.Split(req.Host, ":")
    http.Redirect(w, req, "https://"+hostParts[0]+req.RequestURI,  http.StatusMovedPermanently)
}


func main() {

    // this go subroutine creates a server on :8080 and uses the redir handler
    go func() {
        err := http.ListenAndServe(":8080", http.HandlerFunc(redir))
        if err != nil {
            panic("Error: " + err.Error())
        }
    }()

    http.ListenAndServeTLS(":"+Config.String("port"), Config.Key("https").String("cert"), Config.Key("https").String("key"), router)
}

我希望它有所帮助 欢呼声,