From 21e9fe9b3cb51a69049ed57ce120e969942796c3 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 18 Mar 2021 14:07:03 +0100 Subject: [PATCH] Reload TLS certs on SIGHUP References: https://todo.sr.ht/~emersion/soju/42 --- cmd/soju/main.go | 33 ++++++++++++++++++++++++++++----- doc/soju.1.scd | 2 ++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/cmd/soju/main.go b/cmd/soju/main.go index 8581d33..4c0d8ec 100644 --- a/cmd/soju/main.go +++ b/cmd/soju/main.go @@ -10,6 +10,7 @@ import ( "os" "os/signal" "strings" + "sync/atomic" "syscall" "github.com/pires/go-proxyproto" @@ -50,12 +51,19 @@ func main() { } var tlsCfg *tls.Config + var tlsCert atomic.Value if cfg.TLS != nil { cert, err := tls.LoadX509KeyPair(cfg.TLS.CertPath, cfg.TLS.KeyPath) if err != nil { log.Fatalf("failed to load TLS certificate and key: %v", err) } - tlsCfg = &tls.Config{Certificates: []tls.Certificate{cert}} + tlsCert.Store(cert) + + tlsCfg = &tls.Config{ + GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) { + return tlsCert.Load().(*tls.Certificate), nil + }, + } } srv := soju.NewServer(db) @@ -180,15 +188,30 @@ func main() { } sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) + signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) if err := srv.Start(); err != nil { log.Fatal(err) } - <-sigCh - log.Print("shutting down server") - srv.Shutdown() + for sig := range sigCh { + switch sig { + case syscall.SIGHUP: + if cfg.TLS != nil { + log.Print("reloading TLS certificate") + cert, err := tls.LoadX509KeyPair(cfg.TLS.CertPath, cfg.TLS.KeyPath) + if err != nil { + log.Printf("failed to reload TLS certificate and key: %v", err) + break + } + tlsCert.Store(cert) + } + case syscall.SIGINT, syscall.SIGTERM: + log.Print("shutting down server") + srv.Shutdown() + return + } + } } func proxyProtoListener(ln net.Listener, srv *soju.Server) net.Listener { diff --git a/doc/soju.1.scd b/doc/soju.1.scd index 3e169a2..82bc2c9 100644 --- a/doc/soju.1.scd +++ b/doc/soju.1.scd @@ -44,6 +44,8 @@ soju supports two connection modes: For per-client history to work, clients need to indicate their name. This can be done by adding a "@" suffix to the username. +soju will reload the TLS certificate and key when it receives the HUP signal. + # OPTIONS *-h, -help*