mirror of
https://github.com/caddyserver/caddy.git
synced 2025-04-16 16:19:15 +08:00
caddytls: Regularly reload static certificates
This commit is contained in:
parent
b06a9496d1
commit
b36a7ab9a1
@ -122,13 +122,15 @@ type TLS struct {
|
||||
DNSRaw json.RawMessage `json:"dns,omitempty" caddy:"namespace=dns.providers inline_key=name"`
|
||||
dns any // technically, it should be any/all of the libdns interfaces (RecordSetter, RecordAppender, etc.)
|
||||
|
||||
certificateLoaders []CertificateLoader
|
||||
automateNames []string
|
||||
ctx caddy.Context
|
||||
storageCleanTicker *time.Ticker
|
||||
storageCleanStop chan struct{}
|
||||
logger *zap.Logger
|
||||
events *caddyevents.App
|
||||
magic *certmagic.Config
|
||||
certificateLoaders []CertificateLoader
|
||||
unmanagedCertsTicker *time.Ticker
|
||||
automateNames []string
|
||||
ctx caddy.Context
|
||||
storageCleanTicker *time.Ticker
|
||||
storageCleanStop chan struct{}
|
||||
logger *zap.Logger
|
||||
events *caddyevents.App
|
||||
|
||||
serverNames map[string]struct{}
|
||||
serverNamesMu *sync.Mutex
|
||||
@ -238,7 +240,7 @@ func (t *TLS) Provision(ctx caddy.Context) error {
|
||||
// certificates have been manually loaded, and also so that
|
||||
// commands like validate can be a better test
|
||||
certCacheMu.RLock()
|
||||
magic := certmagic.New(certCache, certmagic.Config{
|
||||
t.magic = certmagic.New(certCache, certmagic.Config{
|
||||
Storage: ctx.Storage(),
|
||||
Logger: t.logger,
|
||||
OnEvent: t.onEvent,
|
||||
@ -248,18 +250,14 @@ func (t *TLS) Provision(ctx caddy.Context) error {
|
||||
DisableStorageCheck: t.DisableStorageCheck,
|
||||
})
|
||||
certCacheMu.RUnlock()
|
||||
for _, loader := range t.certificateLoaders {
|
||||
certs, err := loader.LoadCertificates()
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading certificates: %v", err)
|
||||
}
|
||||
for _, cert := range certs {
|
||||
hash, err := magic.CacheUnmanagedTLSCertificate(ctx, cert.Certificate, cert.Tags)
|
||||
if err != nil {
|
||||
return fmt.Errorf("caching unmanaged certificate: %v", err)
|
||||
}
|
||||
t.loaded[hash] = ""
|
||||
}
|
||||
|
||||
unmanaged, err := t.loadUnmanagedCertificates(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if unmanaged > 0 {
|
||||
t.regularlyReloadUnmanagedCertificates()
|
||||
}
|
||||
|
||||
// on-demand permission module
|
||||
@ -720,6 +718,61 @@ func (t *TLS) HasCertificateForSubject(subject string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *TLS) loadUnmanagedCertificates(ctx caddy.Context) (int, error) {
|
||||
cached := 0
|
||||
for _, loader := range t.certificateLoaders {
|
||||
certs, err := loader.LoadCertificates()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("loading certificates: %v", err)
|
||||
}
|
||||
for _, cert := range certs {
|
||||
hash, err := t.magic.CacheUnmanagedTLSCertificate(ctx, cert.Certificate, cert.Tags)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("caching unmanaged certificate: %v", err)
|
||||
}
|
||||
t.loaded[hash] = ""
|
||||
}
|
||||
}
|
||||
return cached, nil
|
||||
}
|
||||
|
||||
func (t *TLS) regularlyReloadUnmanagedCertificates() {
|
||||
t.unmanagedCertsTicker = time.NewTicker(2 * time.Hour)
|
||||
go func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Printf("[PANIC] unmanaged certificates reloader: %v\n%s", err, debug.Stack())
|
||||
}
|
||||
}()
|
||||
t.reloadUnmanagedCertificates()
|
||||
for {
|
||||
select {
|
||||
case <-t.storageCleanStop:
|
||||
return
|
||||
case <-t.storageCleanTicker.C:
|
||||
t.cleanStorageUnits()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (t *TLS) reloadUnmanagedCertificates() error {
|
||||
for _, loader := range t.certificateLoaders {
|
||||
certs, err := loader.LoadCertificates()
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading certificates: %v", err)
|
||||
}
|
||||
for _, cert := range certs {
|
||||
hash, err := t.magic.CacheUnmanagedTLSCertificate(t.ctx, cert.Certificate, cert.Tags)
|
||||
if err != nil {
|
||||
return fmt.Errorf("caching unmanaged certificate: %v", err)
|
||||
}
|
||||
t.loaded[hash] = ""
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// keepStorageClean starts a goroutine that immediately cleans up all
|
||||
// known storage units if it was not recently done, and then runs the
|
||||
// operation at every tick from t.storageCleanTicker.
|
||||
|
Loading…
x
Reference in New Issue
Block a user