在golang中使用net/http是否可以托管多个域名的TLS?

huangapple go评论71阅读模式
英文:

Is it possible to host multiple domain TLS in golang with net/http?

问题

我有多个域名(比如abc.com和xyz.org),每个域名都有不同的证书。是否可以在不深入底层和使用net.Listen等的情况下,根据主机名使用密钥和证书?只是使用简单的http.ListenAndServeTLS(...)或类似的方法?基本上就像nginx所做的那样。

英文:

I have multiple domain (let's say abc.com and xyz.org) with diffrent certificate. Is it possible to use key and certificate based on hostname without going deep low level and net.Listen, etc. Just using simple http.ListenAndServeTLS(...) or similar ?
Basically like what nginx does.

答案1

得分: 23

BuildNameToCertificate()函数将从证书中提取主机名。如果没有匹配的SNI信息,它将返回[0]。

更新至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))
}

以上是要翻译的内容。

英文:

BuildNameToCertificate() will sniff the hostname from the cert. If none match the SNI info it serves the [0].
https://golang.org/src/crypto/tls/common.go?s=18204:18245#L947

Update for Go 1.14 - see https://github.com/golang/go/commit/eb93c684d40de4924fc0664d7d9e98a84d5a100b

package main
import (
&quot;crypto/tls&quot;
&quot;net/http&quot;
&quot;time&quot;
&quot;log&quot;
)
func myHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(&quot;tls&quot;))
}
func main() {
t := log.Logger{}
var err error
tlsConfig := &amp;tls.Config{}
tlsConfig.Certificates = make([]tls.Certificate, 3)
// go http server treats the 0&#39;th key as a default fallback key
tlsConfig.Certificates[0], err = tls.LoadX509KeyPair(&quot;test0.pem&quot;, &quot;key.pem&quot;)
if err != nil {
t.Fatal(err)
}
tlsConfig.Certificates[1], err = tls.LoadX509KeyPair(&quot;test1.pem&quot;, &quot;key.pem&quot;)
if err != nil {
t.Fatal(err)
}
tlsConfig.Certificates[2], err = tls.LoadX509KeyPair(&quot;test2.pem&quot;, &quot;key.pem&quot;)
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(&quot;/&quot;, myHandler)
server := &amp;http.Server{
ReadTimeout:    10 * time.Second,
WriteTimeout:   10 * time.Second,
MaxHeaderBytes: 1 &lt;&lt; 20,
TLSConfig:      tlsConfig,
}
listener, err := tls.Listen(&quot;tcp&quot;, &quot;:8443&quot;, tlsConfig)
if err != nil {
t.Fatal(err)
}
log.Fatal(server.Serve(listener))
}

huangapple
  • 本文由 发表于 2016年2月26日 09:42:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/35641888.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定