【问题标题】:Is it possible to host multiple domain TLS in golang with net/http?是否可以使用 net/http 在 golang 中托管多个域 TLS?
【发布时间】:2016-06-09 02:07:17
【问题描述】:

我有多个具有不同证书的域(比如说 abc.com 和 xyz.org)。是否可以使用基于主机名的密钥和证书而无需深入底层和 net.Listen 等。只需使用简单的 http.ListenAndServeTLS(...) 或类似的? 基本上和nginx一样。

【问题讨论】:

    标签: go https http2


    【解决方案1】:

    BuildNameToCertificate() 将从证书中嗅探主机名。如果没有匹配 SNI 信息,则它为 [0] 提供服务。 https://golang.org/src/crypto/tls/common.go?s=18204:18245#L947

    Go 1.14 更新 - 请参阅 https://github.com/golang/go/commit/eb93c684d40de4924fc0664d7d9e98a84d5a100b

    package main
    
    import (
        "crypto/tls"
        "net/http"
        "time"
    
        "log"
    )
    
    func myHandler(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("tls"))
    }
    
    func main() {
        t := log.Logger{}
        var err error
        tlsConfig := &tls.Config{}
        tlsConfig.Certificates = make([]tls.Certificate, 3)
        // go http server treats the 0'th key as a default fallback key
        tlsConfig.Certificates[0], err = tls.LoadX509KeyPair("test0.pem", "key.pem")
        if err != nil {
            t.Fatal(err)
        }
        tlsConfig.Certificates[1], err = tls.LoadX509KeyPair("test1.pem", "key.pem")
        if err != nil {
            t.Fatal(err)
        }
        tlsConfig.Certificates[2], err = tls.LoadX509KeyPair("test2.pem", "key.pem")
        if err != nil {
            t.Fatal(err)
        }
    
        // as of go 1.14 this line is no longer needed
        // load the certs as above and skip BuildNameToCertificate()
        tlsConfig.BuildNameToCertificate()
    
        http.HandleFunc("/", myHandler)
        server := &http.Server{
            ReadTimeout:    10 * time.Second,
            WriteTimeout:   10 * time.Second,
            MaxHeaderBytes: 1 << 20,
            TLSConfig:      tlsConfig,
        }
    
        listener, err := tls.Listen("tcp", ":8443", tlsConfig)
        if err != nil {
            t.Fatal(err)
        }
        log.Fatal(server.Serve(listener))
    }
    

    【讨论】:

    • 服务器没有任何 StartTLS 方法!
    • 用一个工作示例更正。这个更完整的示例正确地创建了侦听器并启动了服务器。
    • 我应该如何在这里添加我的路由器?
    • @foo 我正在使用 gorilla mux 进行路由。我之前只使用了一个证书。所以,我使用了 http.ListenAndServe(port,cert,key,router)。如何在这里使用相同的路由器?
    • 提醒 tls.NameToCertificate 已弃用。 NameToCertificate 仅允许将单个证书与给定名称相关联。将该字段留空,让库从证书中选择第一个兼容链。
    猜你喜欢
    • 2017-02-18
    • 2013-12-05
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    相关资源
    最近更新 更多