ssl 对网站越来越重要,用户信息安全,搜索引擎信赖... Let’s Encrypt 免费证书最近发展惊人。

golang.org/x/crypto/acme/autocert

首先配置 autocert.Manager:

1
2
3
4
5
6
autocert.Manager{
    Prompt:     autocert.AcceptTOS,
    HostPolicy: autocert.HostWhitelist(domain), //your domain here
    Cache:      autocert.DirCache("certs"),     //folder for storing certificates
    Email:      contactEmail,
}
HostPolicyautocert.HostWhitelist(domain, domain2, domain3)CacheRenewBefore

再配置tls.Config:

1
2
3
4
5
tls.Config{
    GetCertificate: certManager.GetCertificate,
    NextProtos:     []string{http2.NextProtoTLS, "http/1.1"},
    MinVersion:     tls.VersionTLS12,
}

还要添加一个协程来监听80 端口并转向443 端口

1
2
3
go func(domain string) {
    http.ListenAndServe(":http", http.RedirectHandler("https://"+domain, 301))
}(domain)

全部代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package main

import (
	"crypto/tls"
	"golang.org/x/crypto/acme/autocert"
	"golang.org/x/net/http2"
	"net/http"
)

const (
	contactEmail = "youremail@example.com"
	domain       = "www.golangnote.com"
)

func main() {
	//go func(domain string) {
	//	http.ListenAndServe(":http", http.RedirectHandler("https://"+domain, 301))
	//}(domain)

	certManager := autocert.Manager{
		Prompt:     autocert.AcceptTOS,
		HostPolicy: autocert.HostWhitelist(domain), //your domain here
		Cache:      autocert.DirCache("certs"),     //folder for storing certificates
		Email:      contactEmail,
	}

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello world ssl!"))
	})

	go http.ListenAndServe(":http", certManager.HTTPHandler(nil)) // 支持 http-01
	server := &http.Server{
		Addr: ":https",
		TLSConfig: &tls.Config{
			GetCertificate: certManager.GetCertificate,
			NextProtos:     []string{http2.NextProtoTLS, "http/1.1"},
			MinVersion:     tls.VersionTLS12,
		},
		MaxHeaderBytes: 32 << 20,
	}

	server.ListenAndServeTLS("", "") //key and cert are comming from Let's Encrypt
}

这样的好处是方便,弊端是80、443 端口被独占了。若要想在一台VPS 上运行多个服务,还是有解决方案的,参考神器 SSLDocker,下面是SSLDocker 配置示例:

1
2
3
4
5
6
7
8
9
10
11
{
  "GzipOn": true,
  "Http2https": true,
  "MaxHeader": 10,
  "Certs": "certs",
  "ProxyItems": [
    {"Host": "abc.com", "Target": "http://abc.com"},
    {"Host": "app1.com", "Target": "http://127.0.0.1:1234"},
    {"Host": "app2.com", "Target": "http://127.0.0.1:1235"}
  ]
}

用Supervisor 守护SSLDocker 和后台进程,原理图如下:

相关项目:

本文网址: https://golangnote.com/topic/211.html 转摘请注明来源