詳解如何使用go-acme/lego實(shí)現(xiàn)自動(dòng)簽發(fā)證書
相關(guān)背景知識(shí)
Let's Encrypt
Let's Encrypt是一個(gè)于2015年三季度推出的數(shù)字證書認(rèn)證機(jī)構(gòu),旨在以自動(dòng)化流程消除手動(dòng)創(chuàng)建和安裝證書的復(fù)雜流程,并推廣使萬維網(wǎng)服務(wù)器的加密連接無所不在,為安全網(wǎng)站提供免費(fèi)的傳輸層安全性協(xié)議證書。
ACME
ACME,即自動(dòng)自動(dòng)證書管理環(huán)境(Automatic Certificate Management Environment),是一種協(xié)議,用于自動(dòng)頒發(fā)和更新證書,無需人工干預(yù)。
互聯(lián)網(wǎng)安全研究小組 (ISRG) 最初為自己的證書服務(wù)設(shè)計(jì)了ACME協(xié)議。證書頒發(fā)機(jī)構(gòu)Let’s Encrypt通過ACME協(xié)議免費(fèi)提供DV證書。如今,各種其他的CA、PKI供應(yīng)商和瀏覽器都支持ACME協(xié)議,支持不同類型的證書。
go-acme/lego
一個(gè)用go語言寫的acme客戶端和go語言庫。下文簡(jiǎn)稱為 lego
。
使用 lego 客戶端
安裝
如果有g(shù)olang開發(fā)環(huán)境可以使用以下命令安裝lego
go install github.com/go-acme/lego/v4/cmd/lego@latest
如果沒有g(shù)olang開發(fā)環(huán)境可前往 github.com/go-acme/lego/releases 下載最新cli客戶端
簽發(fā)證書
簽發(fā)證書需要驗(yàn)證域名的所有權(quán),acme
協(xié)議提供了兩種方法來驗(yàn)證你的域名所有權(quán),分別是http服務(wù)器驗(yàn)證和dns驗(yàn)證。
http服務(wù)器驗(yàn)證
使用該方法驗(yàn)證需要有一臺(tái)服務(wù)器,該服務(wù)器要有公網(wǎng)ip。同時(shí)還需要擁有服務(wù)器的root權(quán)限,才能監(jiān)聽80和443端口。
假設(shè)需要部署證書的域名為 example.com ,我們需要先配置 example.com 指向該服務(wù)器的公網(wǎng)ip,然后在服務(wù)器上執(zhí)行
lego --email="you@example.com" --domains="example.com" --http run
該命令啟動(dòng)一個(gè)http服務(wù)器,監(jiān)聽80/443端口。
隨后Let's Encrypt
會(huì)根據(jù)域名(example.com)訪問服務(wù)器的80/443端口,驗(yàn)證域名的所有權(quán)。這個(gè)過程是自動(dòng)化的,只需要等待即可。
驗(yàn)證通過后會(huì)下發(fā)證書到 ./.lego/certificates
里,證書的有效期為3個(gè)月。
dns驗(yàn)證
lego
強(qiáng)大的地方便是集成了幾乎所有常用的云廠商,如CloudFlare、阿里云和騰訊云等的服務(wù)API。只需要設(shè)置API_KEY和API_SECRET便可以自動(dòng)幫你完成DNS驗(yàn)證。
這邊以騰訊云為例:
執(zhí)行以下命令:
TENCENTCLOUD_SECRET_ID=abcdefghijklmnopqrstuvwx \ TENCENTCLOUD_SECRET_KEY=your-secret-key \ lego --email you@example.com --dns tencentcloud --domains my.example.org run
該命令會(huì)調(diào)用騰訊云的后臺(tái)API,為example.com
填寫DNS驗(yàn)證信息;Let's Encrypt
驗(yàn)證通過之后,下發(fā)證書到./.lego/certificates
,同時(shí)也會(huì)自動(dòng)幫你刪除該DNS驗(yàn)證信息。
使用lego庫
我們也可以使用lego
庫來生成證書,或者做一些自動(dòng)化證書生成然后部署的二次開發(fā)。lego
庫同樣也支持http服務(wù)器驗(yàn)證和dns驗(yàn)證,下面給出完整可用代碼。
50-62行為騰訊云dns驗(yàn)證部分,64-73為http服務(wù)器驗(yàn)證部分,二選一即可。
package main import ( "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "fmt" "github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/providers/dns/tencentcloud" "github.com/go-acme/lego/v4/registration" "log" "os" ) type MyUser struct { Email string Registration *registration.Resource key crypto.PrivateKey } func (u *MyUser) GetEmail() string { return u.Email } func (u MyUser) GetRegistration() *registration.Resource { return u.Registration } func (u *MyUser) GetPrivateKey() crypto.PrivateKey { return u.key } func main() { privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { log.Fatal(err) } myUser := MyUser{ Email: "you@example.com", key: privateKey, } config := lego.NewConfig(&myUser) config.Certificate.KeyType = certcrypto.RSA2048 client, err := lego.NewClient(config) if err != nil { log.Fatal(err) } // 使用dns驗(yàn)證的方式,這邊以騰訊云為例子。 cfg := tencentcloud.NewDefaultConfig() cfg.SecretID = "abcdefghijklmnopqrstuvwx" cfg.SecretKey = "your-secret-key" p, err := tencentcloud.NewDNSProviderConfig(cfg) if err != nil { log.Fatal(err) } err = client.Challenge.SetDNS01Provider(p) if err != nil { log.Fatal(err) } // ---------使用dns-騰訊云驗(yàn)證的方式結(jié)束----------- // 使用http服務(wù)器驗(yàn)證的方式,注釋上面dns驗(yàn)證的代碼部分,取消下面http驗(yàn)證的代碼注釋部分 // err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "80")) // if err != nil { // log.Fatal(err) // } // err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "443")) // if err != nil { // log.Fatal(err) // } //-----------使用http服務(wù)器驗(yàn)證的方式結(jié)束----------- reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true}) if err != nil { log.Fatal(err) } myUser.Registration = reg request := certificate.ObtainRequest{ Domains: []string{"sd.pigudaxiang.cn"}, Bundle: true, } certificates, err := client.Certificate.Obtain(request) if err != nil { log.Fatal(err) } fmt.Printf("%#v\n", certificates) err = os.WriteFile("PrivateKey", certificates.PrivateKey, os.ModePerm) if err != nil { log.Print(err) } err = os.WriteFile("Certificate", certificates.Certificate, os.ModePerm) if err != nil { log.Print(err) } err = os.WriteFile("IssuerCertificate", certificates.IssuerCertificate, os.ModePerm) if err != nil { log.Print(err) } err = os.WriteFile("CSR", certificates.CSR, os.ModePerm) if err != nil { log.Print(err) } }
到此這篇關(guān)于詳解如何使用go-acme/lego實(shí)現(xiàn)自動(dòng)簽發(fā)證書的文章就介紹到這了,更多相關(guān)go自動(dòng)簽發(fā)證書內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go?mode?tidy出現(xiàn)報(bào)錯(cuò)go:?warning:?“all“?matched?no?package
使用go的時(shí)候我們一般都會(huì)使用go?mode管理,下面這篇文章主要給大家介紹了關(guān)于go?mode?tidy出現(xiàn)報(bào)錯(cuò)go:?warning:?“all“?matched?no?packages的解決方法,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08Go1.16新特性embed打包靜態(tài)資源文件實(shí)現(xiàn)
這篇文章主要為大家介紹了Go?1.16新特性embed打包靜態(tài)資源文件的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Go?json自定義Unmarshal避免判斷nil示例詳解
這篇文章主要為大家介紹了Go?json自定義Unmarshal避免判斷nil示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06golang對(duì)自定義類型進(jìn)行排序的解決方法
學(xué)習(xí)一門編程語言,要掌握原子數(shù)據(jù)類型,還需要掌握自定義數(shù)據(jù)類型。下面這篇文章主要給大家介紹了關(guān)于golang如何對(duì)自定義類型進(jìn)行排序的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-12-12golang?chan傳遞數(shù)據(jù)的性能開銷詳解
這篇文章主要為大家詳細(xì)介紹了Golang中chan在接收和發(fā)送數(shù)據(jù)時(shí)因?yàn)椤皬?fù)制”而產(chǎn)生的開銷,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2024-01-01