golang 重新加载ssl证书

参考 stackoverflowicon-default.png?t=N7T8https://stackoverflow.com/questions/37473201/is-there-a-way-to-update-the-tls-certificates-in-a-net-http-server-without-any-d代码如下 ,http是用github.com/gogf/gf 框架。

package main

import (
	"crypto/tls"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"sync"
)
// 调用
func main() {
	s := g.Server("proxy")
	err := UpdateSsl("./ssl/cert.txt", "./ssl/key.txt", s)
	if err != nil {
		g.Log().Error(err)
		return
	}
	s.Group("/api", func(group *ghttp.RouterGroup) {
		group.POST("/ssl_renew", func(r *ghttp.Request) {
			err := ReloadSSL()
			if err != nil {
				return
			}
			r.Response.Writeln("更新完成")
		})
	})
	s.Run()
}
//==============================================
type keypairReloader struct {
	certMu   sync.RWMutex
	cert     *tls.Certificate
	certPath string
	keyPath  string
}

func NewKeypairReloader(certPath, keyPath string) (*keypairReloader, error) {
	result := &keypairReloader{
		certPath: certPath,
		keyPath:  keyPath,
	}
	cert, err := tls.LoadX509KeyPair(certPath, keyPath)
	if err != nil {
		return nil, err
	}
	result.cert = &cert

	return result, nil
}

func (kpr *keypairReloader) maybeReload() error {
	newCert, err := tls.LoadX509KeyPair(kpr.certPath, kpr.keyPath)
	if err != nil {
		return err
	}
	kpr.certMu.Lock()
	defer kpr.certMu.Unlock()
	kpr.cert = &newCert
	g.Log().Info("ssl 加载成功!")
	return nil
}

func (kpr *keypairReloader) GetCertificateFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
	return func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
		kpr.certMu.RLock()
		defer kpr.certMu.RUnlock()
		return kpr.cert, nil
	}
}

var kpr *keypairReloader

// 启用https服务
// 框架 github.com/gogf/gf,这个方法可以优化优化,改成其他框架
func UpdateSsl(certPath, keyPath string, s *ghttp.Server) error {
	var err error
	kpr, err = NewKeypairReloader(certPath, keyPath)
	if err != nil {
		return err
	}
	var ssl_tls = &tls.Config{
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
	}
	ssl_tls.GetCertificate = kpr.GetCertificateFunc()
	s.SetTLSConfig(ssl_tls)
	s.EnableHTTPS(certPath, keyPath, ssl_tls)
	return nil
}

// 外部调用这个方法
func ReloadSSL() error {
	if kpr == nil {
		return nil
	}
	return kpr.maybeReload()
}

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jicg33

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值