GolangNote

Golang笔记

Golang Web 自动安装、更新Let’s Encrypt 免费证书

Permalink

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

Golang Web 自动安装、更新Let’s Encrypt 免费证书

如果使用nginx ,则需要配置、签发证书、添加定时任务更新,涉及的东西太多。如果使用go 则轻松在一个可实行包里完成所有功能。下面是使用官方包golang.org/x/crypto/acme/autocert 做个简单示例。

首先配置 autocert.Manager:

Go: 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:

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

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

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

全部代码:

Go: 完整代码
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 配置示例:

JSON: 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 和后台进程,原理图如下:

ssldocker

相关项目:

Related articles

golang rot13 简单加密字符

ROT13 是一种简单的字符加密方法,把 26 个英文字母的前 13 个字母与后 13 个字母的编码互换。...

Write a Comment to "Golang Web 自动安装、更新Let’s Encrypt 免费证书"

Submit Comment Login
Based on Golang + fastHTTP + sdb | go1.16.5 Processed in 1ms