mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
letsencrypt: Basic renewal failover and better error handling
This commit is contained in:
parent
c5635f21a3
commit
f24ecee603
1 changed files with 30 additions and 19 deletions
|
@ -17,8 +17,10 @@ import (
|
||||||
func keepCertificatesRenewed(configs []server.Config) {
|
func keepCertificatesRenewed(configs []server.Config) {
|
||||||
ticker := time.Tick(renewInterval)
|
ticker := time.Tick(renewInterval)
|
||||||
for range ticker {
|
for range ticker {
|
||||||
if err := processCertificateRenewal(configs); err != nil {
|
if errs := processCertificateRenewal(configs); len(errs) > 0 {
|
||||||
log.Printf("[ERROR] cert renewal: %v", err)
|
for _, err := range errs {
|
||||||
|
log.Printf("[ERROR] cert renewal: %v\n", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +28,12 @@ func keepCertificatesRenewed(configs []server.Config) {
|
||||||
// checkCertificateRenewal loops through all configured
|
// checkCertificateRenewal loops through all configured
|
||||||
// sites and looks for certificates to renew. Nothing is mutated
|
// sites and looks for certificates to renew. Nothing is mutated
|
||||||
// through this function. The changes happen directly on disk.
|
// through this function. The changes happen directly on disk.
|
||||||
func processCertificateRenewal(configs []server.Config) error {
|
func processCertificateRenewal(configs []server.Config) []error {
|
||||||
|
var errs []error
|
||||||
log.Print("[INFO] Processing certificate renewals...")
|
log.Print("[INFO] Processing certificate renewals...")
|
||||||
|
|
||||||
for _, cfg := range configs {
|
for _, cfg := range configs {
|
||||||
// Check if this entry is TLS enabled and managed by LE
|
// Host must be TLS-enabled and have assets managed by LE
|
||||||
if !cfg.TLS.Enabled || !existingCertAndKey(cfg.Host) {
|
if !cfg.TLS.Enabled || !existingCertAndKey(cfg.Host) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -38,11 +41,13 @@ func processCertificateRenewal(configs []server.Config) error {
|
||||||
// Read the certificate and get the NotAfter time.
|
// Read the certificate and get the NotAfter time.
|
||||||
certBytes, err := ioutil.ReadFile(storage.SiteCertFile(cfg.Host))
|
certBytes, err := ioutil.ReadFile(storage.SiteCertFile(cfg.Host))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
errs = append(errs, err)
|
||||||
|
continue // still have to check other certificates
|
||||||
}
|
}
|
||||||
expTime, err := acme.GetPEMCertExpiration(certBytes)
|
expTime, err := acme.GetPEMCertExpiration(certBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// The time returned from the certificate is always in UTC.
|
// The time returned from the certificate is always in UTC.
|
||||||
|
@ -50,23 +55,26 @@ func processCertificateRenewal(configs []server.Config) error {
|
||||||
// Directly convert it to days for the following checks.
|
// Directly convert it to days for the following checks.
|
||||||
daysLeft := int(expTime.Sub(time.Now().UTC()).Hours() / 24)
|
daysLeft := int(expTime.Sub(time.Now().UTC()).Hours() / 24)
|
||||||
|
|
||||||
// Renew on two or less days remaining.
|
// Renew with a week or less remaining.
|
||||||
if daysLeft <= 2 {
|
if daysLeft <= 7 {
|
||||||
log.Printf("[WARN] There are %d days left on the certificate of %s. Trying to renew now.", daysLeft, cfg.Host)
|
log.Printf("[INFO] There are %d days left on the certificate of %s. Trying to renew now.", daysLeft, cfg.Host)
|
||||||
client, err := newClient(getEmail(cfg))
|
client, err := newClient(getEmail(cfg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read metadata
|
// Read metadata
|
||||||
metaBytes, err := ioutil.ReadFile(storage.SiteMetaFile(cfg.Host))
|
metaBytes, err := ioutil.ReadFile(storage.SiteMetaFile(cfg.Host))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
privBytes, err := ioutil.ReadFile(storage.SiteKeyFile(cfg.Host))
|
privBytes, err := ioutil.ReadFile(storage.SiteKeyFile(cfg.Host))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var certMeta acme.CertificateResource
|
var certMeta acme.CertificateResource
|
||||||
|
@ -78,17 +86,20 @@ func processCertificateRenewal(configs []server.Config) error {
|
||||||
// TODO: revokeOld should be an option in the caddyfile
|
// TODO: revokeOld should be an option in the caddyfile
|
||||||
newCertMeta, err := client.RenewCertificate(certMeta, true)
|
newCertMeta, err := client.RenewCertificate(certMeta, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
time.Sleep(10 * time.Second)
|
||||||
|
newCertMeta, err = client.RenewCertificate(certMeta, true)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
saveCertsAndKeys([]acme.CertificateResource{newCertMeta})
|
saveCertsAndKeys([]acme.CertificateResource{newCertMeta})
|
||||||
}
|
} else if daysLeft <= 14 {
|
||||||
|
|
||||||
// Warn on 14 days remaining
|
// Warn on 14 days remaining
|
||||||
if daysLeft <= 14 {
|
log.Printf("[WARN] There are %d days left on the certificate for %s. Will renew when 7 days remain.\n", daysLeft, cfg.Host)
|
||||||
log.Printf("[WARN] There are %d days left on the certificate of %s. Will renew on two days left.\n", daysLeft, cfg.Host)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return errs
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue