mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-01 03:16:31 +02:00
internal/autocert: refactoring updateAutocert
By factor out obtain and renew certification process, return specific error for each process if failed to contact with letsencrypt server.
This commit is contained in:
parent
3c23164347
commit
277e6b56e9
1 changed files with 46 additions and 22 deletions
|
@ -3,6 +3,7 @@ package autocert
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -16,6 +17,11 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errObtainCertFailed = errors.New("obtain cert failed")
|
||||||
|
errRenewCertFailed = errors.New("renew cert failed")
|
||||||
|
)
|
||||||
|
|
||||||
// Manager manages TLS certificates.
|
// Manager manages TLS certificates.
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
src config.Source
|
src config.Source
|
||||||
|
@ -85,6 +91,35 @@ func (mgr *Manager) update(cfg *config.Config) error {
|
||||||
return mgr.updateAutocert(cfg)
|
return mgr.updateAutocert(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// obtainCert obtains a certificate for given domain, use cached manager if cert exists there.
|
||||||
|
func (mgr *Manager) obtainCert(domain string, cm *certmagic.Config) (certmagic.Certificate, error) {
|
||||||
|
cert, err := cm.CacheManagedCertificate(domain)
|
||||||
|
if err != nil {
|
||||||
|
log.Info().Str("domain", domain).Msg("obtaining certificate")
|
||||||
|
err = cm.ObtainCert(context.Background(), domain, false)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("autocert failed to obtain client certificate")
|
||||||
|
return certmagic.Certificate{}, errObtainCertFailed
|
||||||
|
}
|
||||||
|
cert, err = cm.CacheManagedCertificate(domain)
|
||||||
|
}
|
||||||
|
return cert, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// renewCert attempts to renew given certificate.
|
||||||
|
func (mgr *Manager) renewCert(domain string, cert certmagic.Certificate, cm *certmagic.Config) (certmagic.Certificate, error) {
|
||||||
|
expired := time.Now().After(cert.Leaf.NotAfter)
|
||||||
|
log.Info().Str("domain", domain).Msg("renewing certificate")
|
||||||
|
err := cm.RenewCert(context.Background(), domain, false)
|
||||||
|
if err != nil {
|
||||||
|
if expired {
|
||||||
|
return certmagic.Certificate{}, errRenewCertFailed
|
||||||
|
}
|
||||||
|
log.Warn().Err(err).Msg("renew client certificated failed, use existing cert")
|
||||||
|
}
|
||||||
|
return cm.CacheManagedCertificate(domain)
|
||||||
|
}
|
||||||
|
|
||||||
func (mgr *Manager) updateAutocert(cfg *config.Config) error {
|
func (mgr *Manager) updateAutocert(cfg *config.Config) error {
|
||||||
if !cfg.Options.AutocertOptions.Enable {
|
if !cfg.Options.AutocertOptions.Enable {
|
||||||
return nil
|
return nil
|
||||||
|
@ -96,33 +131,22 @@ func (mgr *Manager) updateAutocert(cfg *config.Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, domain := range sourceHostnames(cfg) {
|
for _, domain := range sourceHostnames(cfg) {
|
||||||
cert, err := cm.CacheManagedCertificate(domain)
|
cert, err := mgr.obtainCert(domain, cm)
|
||||||
if err != nil {
|
if err != nil && errors.Is(err, errObtainCertFailed) {
|
||||||
log.Info().Str("domain", domain).Msg("obtaining certificate")
|
return fmt.Errorf("autocert: failed to obtain client certificate: %w", err)
|
||||||
err = cm.ObtainCert(context.Background(), domain, false)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("autocert: failed to obtain client certificate: %w", err)
|
|
||||||
}
|
|
||||||
cert, err = cm.CacheManagedCertificate(domain)
|
|
||||||
}
|
}
|
||||||
if err == nil && cert.NeedsRenewal(cm) {
|
if err == nil && cert.NeedsRenewal(cm) {
|
||||||
expired := time.Now().After(cert.Leaf.NotAfter)
|
cert, err = mgr.renewCert(domain, cert, cm)
|
||||||
log.Info().Str("domain", domain).Msg("renewing certificate")
|
|
||||||
err = cm.RenewCert(context.Background(), domain, false)
|
|
||||||
if err != nil && expired {
|
|
||||||
return fmt.Errorf("autocert: failed to renew client certificate: %w", err)
|
|
||||||
}
|
|
||||||
if !expired {
|
|
||||||
log.Warn().Err(err).Msg("renew client certificated failed, use existing cert")
|
|
||||||
}
|
|
||||||
cert, err = cm.CacheManagedCertificate(domain)
|
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err != nil && errors.Is(err, errRenewCertFailed) {
|
||||||
log.Info().Strs("names", cert.Names).Msg("autocert: added certificate")
|
return fmt.Errorf("autocert: failed to renew client certificate: %w", err)
|
||||||
cfg.Options.Certificates = append(cfg.Options.Certificates, cert.Certificate)
|
}
|
||||||
} else {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("autocert: failed to obtain client certificate")
|
log.Error().Err(err).Msg("autocert: failed to obtain client certificate")
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
log.Info().Strs("names", cert.Names).Msg("autocert: added certificate")
|
||||||
|
cfg.Options.Certificates = append(cfg.Options.Certificates, cert.Certificate)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Add table
Reference in a new issue