ssl 对网站越来越重要,用户信息安全,搜索引擎信赖... Let’s Encrypt 免费证书最近发展惊人。
如果使用nginx ,则需要配置、签发证书、添加定时任务更新,涉及的东西太多。如果使用go 则轻松在一个可实行包里完成所有功能。下面是使用官方包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,
}
HostPolicy
是要注册的域名,可填写多个域名:autocert.HostWhitelist(domain, domain2, domain3)
,如果留空则是任何解析向该服务器ip 的域名。Cache
是存放证书的目录- 还有个参数
RenewBefore
是指定更新证书的时间,如果不填则是在过期前30天自动更新。
再配置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 和后台进程,原理图如下:
相关项目:
- autocert https://github.com/golang/crypto/tree/master/acme/autocert
- SSLDocker https://ssldocker.com/
本文网址: https://golangnote.com/topic/211.html 转摘请注明来源