有没有一种方法可以在没有停机的情况下更新net / http服务器中的TLS证书?

F21

我有一个简单的https服务器,提供了一个类似这样的简单页面(为简洁起见,没有错误处理):

package main

import (
    "crypto/tls"
    "fmt"
    "net/http"
)

func main() {
    mux := http.NewServeMux()

    mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintf(w, "hello!")
    })

    xcert, _ := tls.LoadX509KeyPair("cert1.crt", "key1.pem")

    tlsConf := &tls.Config{
        Certificates: []tls.Certificate{xcert},
    }

    srv := &http.Server{
        Addr:      ":https",
        Handler:   mux,
        TLSConfig: tlsConf,
    }

    srv.ListenAndServeTLS("", "")
}

我想使用“让我们加密TLS”证书在https上提供内容。我希望能够进行证书续订并更新服务器中的证书,而不会造成任何停机。

我尝试运行goroutine更新tlsConf

go func(c *tls.Config) {
        xcert, _ := tls.LoadX509KeyPair("cert2.crt", "key2.pem")

        select {
        case <-time.After(3 * time.Minute):
            c.Certificates = []tls.Certificate{xcert}
            c.BuildNameToCertificate()
            fmt.Println("cert switched!")
        }

    }(tlsConf)

但是,这不起作用,因为服务器不会“读入”更改后的配置。无论如何,有没有要求服务器重新加载TLSConfig

麦可

有:您可以使用tls.ConfigGetCertificate成员,而不是填充Certificates首先,定义一个封装证书和重载功能的数据结构(SIGHUP在此示例中,在接收到信号时):

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
        go func() {
                c := make(chan os.Signal, 1)
                signal.Notify(c, syscall.SIGHUP)
                for range c {
                        log.Printf("Received SIGHUP, reloading TLS certificate and key from %q and %q", *tlsCertPath, *tlsKeyPath)
                        if err := result.maybeReload(); err != nil {
                                log.Printf("Keeping old TLS certificate because the new one could not be loaded: %v", err)
                        }
                }
        }()
        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
        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
        }
}

然后,在您的服务器代码中,使用:

kpr, err := NewKeypairReloader(*tlsCertPath, *tlsKeyPath)
if err != nil {
    log.Fatal(err)
}
srv.TLSConfig.GetCertificate = kpr.GetCertificateFunc()

我最近在RobustIRC中实现了这种模式

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

有没有一种方法可以在不重新绑定的情况下更新RecyclerView中的某些项目?

来自分类Dev

有没有一种方法可以在没有CellEditor的情况下选择JTable中单元格中的所有文本?

来自分类Dev

有没有一种方法可以在不先打开Nautilus的情况下打开“连接到服务器”?

来自分类Dev

有没有一种方法可以在没有foreach循环的情况下对小于给定点的数组中的整数进行计数?

来自分类Dev

有没有一种方法可以在没有特定顺序的情况下测试集合中的元素?

来自分类Dev

有没有一种方法可以在不使用一个热编码器的情况下训练RNN?

来自分类Dev

有没有一种方法可以在未安装Chrome浏览器“环境”的情况下运行HTML文件?

来自分类Dev

有没有一种方法可以在不使用Selenium或浏览器客户端的情况下从在线应用程序提交表单?

来自分类Dev

有没有一种方法可以在不使用组的情况下引用re.sub中的整个匹配表达式?

来自分类Dev

PHP中有没有一种方法可以在不使用ob_gzhandler的情况下从JSON中删除空格?

来自分类Dev

有没有一种方法可以在不使用UINavigationController的情况下更改情节提要中的UINavigationBar的高度?

来自分类Dev

有没有一种方法可以在不使用小部件的情况下访问PageState类中的页面属性

来自分类Dev

在JavaScript中,有没有一种方法可以在不使用toLocaleString的情况下将Date转换为时区?

来自分类Dev

有没有一种方法可以在不使用className的情况下使用ID在React中设置元素的样式?

来自分类Dev

有没有一种方法可以在默认情况下使用Angle 8+中的ejs-documenteditorcontainer打开word(doc或docx)文件?

来自分类Dev

有没有一种方法可以在不解压缩的情况下打开zip文件中的文件(C#)

来自分类Dev

有没有一种方法可以在不使用用户代理的情况下从IE8-IE11中检测IE?

来自分类Dev

有没有一种方法可以在不使用宏的情况下合并Excel中的选项卡?

来自分类Dev

有没有一种方法可以在不刷新单元格的情况下显示单元格中的对象?

来自分类Dev

在SAS中,有没有一种方法可以在不存储循环值的情况下计算百分位数?

来自分类Dev

有没有一种方法可以使用Dropbox API在不使用Web服务器带宽的情况下下载文件?

来自分类Dev

有没有一种方法可以只更新EnvironmentObject中的某些元素

来自分类Dev

有没有一种方法可以更新ConcurrentMessageListenerContainer中的并发数量?

来自分类Dev

有没有一种方法可以自动插入在链接服务器上更新的行?

来自分类Dev

有没有一种方法可以在不使用现有表的情况下在选择中返回多于1行

来自分类Dev

有没有一种方法可以从一个表中全部选择,并在可能的情况下联接?

来自分类Dev

有没有一种方法可以确定Java中的应用程序服务器名称

来自分类Dev

有没有一种方法可以快速清除MarkLogic中的服务器错误日志?

来自分类Dev

有没有一种方法可以优化该代码?Go中的TCP服务器

Related 相关文章

  1. 1

    有没有一种方法可以在不重新绑定的情况下更新RecyclerView中的某些项目?

  2. 2

    有没有一种方法可以在没有CellEditor的情况下选择JTable中单元格中的所有文本?

  3. 3

    有没有一种方法可以在不先打开Nautilus的情况下打开“连接到服务器”?

  4. 4

    有没有一种方法可以在没有foreach循环的情况下对小于给定点的数组中的整数进行计数?

  5. 5

    有没有一种方法可以在没有特定顺序的情况下测试集合中的元素?

  6. 6

    有没有一种方法可以在不使用一个热编码器的情况下训练RNN?

  7. 7

    有没有一种方法可以在未安装Chrome浏览器“环境”的情况下运行HTML文件?

  8. 8

    有没有一种方法可以在不使用Selenium或浏览器客户端的情况下从在线应用程序提交表单?

  9. 9

    有没有一种方法可以在不使用组的情况下引用re.sub中的整个匹配表达式?

  10. 10

    PHP中有没有一种方法可以在不使用ob_gzhandler的情况下从JSON中删除空格?

  11. 11

    有没有一种方法可以在不使用UINavigationController的情况下更改情节提要中的UINavigationBar的高度?

  12. 12

    有没有一种方法可以在不使用小部件的情况下访问PageState类中的页面属性

  13. 13

    在JavaScript中,有没有一种方法可以在不使用toLocaleString的情况下将Date转换为时区?

  14. 14

    有没有一种方法可以在不使用className的情况下使用ID在React中设置元素的样式?

  15. 15

    有没有一种方法可以在默认情况下使用Angle 8+中的ejs-documenteditorcontainer打开word(doc或docx)文件?

  16. 16

    有没有一种方法可以在不解压缩的情况下打开zip文件中的文件(C#)

  17. 17

    有没有一种方法可以在不使用用户代理的情况下从IE8-IE11中检测IE?

  18. 18

    有没有一种方法可以在不使用宏的情况下合并Excel中的选项卡?

  19. 19

    有没有一种方法可以在不刷新单元格的情况下显示单元格中的对象?

  20. 20

    在SAS中,有没有一种方法可以在不存储循环值的情况下计算百分位数?

  21. 21

    有没有一种方法可以使用Dropbox API在不使用Web服务器带宽的情况下下载文件?

  22. 22

    有没有一种方法可以只更新EnvironmentObject中的某些元素

  23. 23

    有没有一种方法可以更新ConcurrentMessageListenerContainer中的并发数量?

  24. 24

    有没有一种方法可以自动插入在链接服务器上更新的行?

  25. 25

    有没有一种方法可以在不使用现有表的情况下在选择中返回多于1行

  26. 26

    有没有一种方法可以从一个表中全部选择,并在可能的情况下联接?

  27. 27

    有没有一种方法可以确定Java中的应用程序服务器名称

  28. 28

    有没有一种方法可以快速清除MarkLogic中的服务器错误日志?

  29. 29

    有没有一种方法可以优化该代码?Go中的TCP服务器

热门标签

归档