是否可以使用 net/http 在 golang 中托管多个域 TLS?
Posted
技术标签:
【中文标题】是否可以使用 net/http 在 golang 中托管多个域 TLS?【英文标题】:Is it possible to host multiple domain TLS in golang with net/http? 【发布时间】:2016-06-09 02:07:17 【问题描述】:我有多个具有不同证书的域(比如说 abc.com 和 xyz.org)。是否可以使用基于主机名的密钥和证书而无需深入底层和 net.Listen 等。只需使用简单的 http.ListenAndServeTLS(...) 或类似的? 基本上和nginx一样。
【问题讨论】:
【参考方案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 仅允许将单个证书与给定名称相关联。将该字段留空,让库从证书中选择第一个兼容链。以上是关于是否可以使用 net/http 在 golang 中托管多个域 TLS?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Golang 的 net/http 包读取流响应正文?
Golang“net/http”错误:未定义:DetectContentType