fix: implement crl reloading on HUP

This commit is contained in:
Florian Bauer
2025-01-21 11:20:41 +01:00
parent 56319a79c9
commit a0731fe67d

52
main.go
View File

@@ -5,7 +5,6 @@ import (
"crypto/x509" "crypto/x509"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"github.com/prometheus/client_golang/prometheus/promhttp"
"log" "log"
"net/http" "net/http"
"ocspcrl/internal/metrics" "ocspcrl/internal/metrics"
@@ -15,9 +14,12 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
cfocsp "github.com/cloudflare/cfssl/ocsp" cfocsp "github.com/cloudflare/cfssl/ocsp"
"github.com/prometheus/client_golang/prometheus/promhttp"
"ocspcrl/internal/ocsp_source" "ocspcrl/internal/ocsp_source"
) )
type loadCrlFunction func() error
func loadCrlFromFile(path string) (*x509.RevocationList, error) { func loadCrlFromFile(path string) (*x509.RevocationList, error) {
crlContent, openCrlError := os.ReadFile(path) crlContent, openCrlError := os.ReadFile(path)
if openCrlError != nil { if openCrlError != nil {
@@ -34,6 +36,24 @@ func loadCrlFromFile(path string) (*x509.RevocationList, error) {
return crl, nil return crl, nil
} }
func reloadCrlWorker(signal chan os.Signal, loadCrlFunc loadCrlFunction) {
defer log.Println("reload crl worker stopped")
for {
select {
case _, ok := <-signal:
if !ok {
return
}
loadCrlError := loadCrlFunc()
if loadCrlError != nil {
log.Printf("failed to reload crl: %v", loadCrlError)
} else {
log.Println("reloaded crl")
}
}
}
}
type responder struct { type responder struct {
certificatePath string certificatePath string
keyPath string keyPath string
@@ -87,15 +107,32 @@ func main() {
} }
source := ocsp_source.NewCrlSource(caCertificate, responderKeyPair) source := ocsp_source.NewCrlSource(caCertificate, responderKeyPair)
crl, loadCrlError := loadCrlFromFile(config.crlSourceFile.path)
if loadCrlError != nil { crl := &x509.RevocationList{}
log.Fatalf("failed to load crl: %v", loadCrlError)
loadCrl := func() error {
crlCandiate, loadCrlError := loadCrlFromFile(config.crlSourceFile.path)
if loadCrlError != nil {
return loadCrlError
}
metrics.CrlEntries.Set(float64(len(crlCandiate.RevokedCertificateEntries)))
source.UseCrl(*crlCandiate)
crl = crlCandiate
return nil
} }
metrics.CrlEntries.Set(float64(len(crl.RevokedCertificateEntries)))
source.UseCrl(*crl)
signalChan := make(chan os.Signal, 1) signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
// initial load of the CRL
if loadCrlError := loadCrl(); loadCrlError != nil {
log.Fatalf("failed to load crl: %v", loadCrlError)
}
// on HUP reload the CRL
hupChan := make(chan os.Signal, 1)
signal.Notify(hupChan, syscall.SIGHUP)
go reloadCrlWorker(hupChan, loadCrl)
applicationRouter := http.NewServeMux() applicationRouter := http.NewServeMux()
applicationRouter.Handle("/ocsp", cfocsp.NewResponder(source, nil)) applicationRouter.Handle("/ocsp", cfocsp.NewResponder(source, nil))
@@ -129,6 +166,7 @@ func main() {
}() }()
<-signalChan <-signalChan
close(hupChan)
applicationServer.Shutdown(nil) applicationServer.Shutdown(nil)
metricsSever.Shutdown(nil) metricsSever.Shutdown(nil)
<-applicationServerClosed <-applicationServerClosed