1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00

Add certificate reloader on SIGHUP

This commit is contained in:
Kane York 2017-09-26 13:04:39 -07:00
parent a5e3ad701b
commit 7b0cdc4baa
3 changed files with 83 additions and 8 deletions

View file

@ -0,0 +1,69 @@
package certreloader
import (
"crypto/tls"
"log"
"os"
"os/signal"
"sync"
)
type CertSource struct {
certMu sync.RWMutex
cert *tls.Certificate
certPath string
keyPath string
}
// Create a CertSource
func New(certPath, keyPath string) (*CertSource, error) {
result := &CertSource{
certPath: certPath,
keyPath: keyPath,
}
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
return nil, err
}
result.cert = &cert
return result, nil
}
// Automatically reload certificate on the provided signal
func (kpr *CertSource) AutoCheck(sig os.Signal) {
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, sig)
for range c {
log.Printf("Received %v, reloading TLS certificate and key from %q and %q", sig, kpr.certPath, kpr.keyPath)
if err := kpr.maybeReload(); err != nil {
log.Printf("Keeping old TLS certificate because the new one could not be loaded: %v", err)
}
}
}()
}
// Check() can be called manually to reload the certificate
func (kpr *CertSource) Check() error {
return kpr.maybeReload()
}
func (kpr *CertSource) 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
}
// Returns a tls.Config.GetCertificate function.
func (kpr *CertSource) 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
}
}

View file

@ -1,7 +1,10 @@
package main // import "github.com/FrankerFaceZ/FrankerFaceZ/socketserver/cmd/ffzsocketserver"
import _ "net/http/pprof"
import (
"context"
"crypto/tls"
"encoding/json"
"flag"
"fmt"
@ -14,11 +17,10 @@ import (
"syscall"
"time"
"github.com/FrankerFaceZ/FrankerFaceZ/socketserver/certreloader"
"github.com/FrankerFaceZ/FrankerFaceZ/socketserver/server"
)
import _ "net/http/pprof"
var configFilename = flag.String("config", "config.json", "Configuration file, including the keypairs for the NaCl crypto library, for communicating with the backend.")
var flagGenerateKeys = flag.Bool("genkeys", false, "Generate NaCl keys instead of serving requests.\nArguments: [int serverId] [base64 backendPublic]\nThe backend public key can either be specified in base64 on the command line, or put in the json file later.")
@ -69,12 +71,21 @@ func main() {
signal.Notify(stopSig, syscall.SIGTERM)
if conf.UseSSL {
reloader, err := certreloader.New(conf.SSLCertificateFile, conf.SSLKeyFile)
if err != nil {
log.Fatalln("Could not load TLS certificate:", err)
}
reloader.AutoCheck(syscall.SIGHUP)
server1 = &http.Server{
Addr: conf.SSLListenAddr,
Handler: http.DefaultServeMux,
TLSConfig: &tls.Config{
GetCertificate: reloader.GetCertificateFunc(),
},
}
go func() {
if err := server1.ListenAndServeTLS(conf.SSLCertificateFile, conf.SSLKeyFile); err != nil {
if err := server1.ListenAndServeTLS("", ""); err != nil {
log.Println("ListenAndServeTLS:", err)
stopSig <- os.Interrupt
}

View file

@ -35,11 +35,6 @@ type ConfigFile struct {
// Path to key file.
SSLKeyFile string
UseESLogStashing bool
ESServer string
ESIndexPrefix string
ESHostName string
// Nacl keys
OurPrivateKey []byte
OurPublicKey []byte