Golang笔记

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

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

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

首先配置autocert.Manager:

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:

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

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

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

全部代码:

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 上运行多个服务,还是有解决方案的,参考神器 https://ssldocker.com/ 270,下面是SSLDocker 配置示例:

{
  "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

相关项目:

本文网址: https://golangnote.com/topic/211.html (转载注明出处)
关于GolangNote:记录在工作中使用golang 遇到、面临的相关问题及解决方法。如果你在这里获得一些知识或信息,解决你的编程问题,请考虑捐赠给不幸的人或者你喜欢的慈善机构,除捐赠外,种植树木、志愿服务或减少排碳的行为也很有益处。如果你有任何问题可以在下面 留言
Be the first to comment!
Captcha image
Relative Articles