diff --git a/caddy/caddy.go b/caddy/caddy.go index 5d1cd9c2..734e984d 100644 --- a/caddy/caddy.go +++ b/caddy/caddy.go @@ -1,4 +1,5 @@ -// Package caddy implements the Caddy web server as a service. +// Package caddy implements the Caddy web server as a service +// in your own Go programs. // // To use this package, follow a few simple steps: // diff --git a/caddy/letsencrypt/letsencrypt.go b/caddy/letsencrypt/letsencrypt.go index 769370e9..a115d91b 100644 --- a/caddy/letsencrypt/letsencrypt.go +++ b/caddy/letsencrypt/letsencrypt.go @@ -72,7 +72,11 @@ func Activate(configs []server.Config) ([]server.Config, error) { // set up redirects configs = MakePlaintextRedirects(configs) - // renew all relevant certificates that need renewal; TODO: handle errors + // renew all relevant certificates that need renewal. this is important + // to do right away for a couple reasons, mainly because each restart, + // the renewal ticker is reset, so if restarts happen more often than + // the ticker interval, renewals would never happen. but doing + // it right away at start guarantees that renewals aren't missed. renewCertificates(configs, false) // keep certificates renewed and OCSP stapling updated @@ -127,7 +131,7 @@ func ObtainCerts(configs []server.Config, optPort string) error { } Obtain: - certificate, failures := client.ObtainCertificate([]string{cfg.Host}, true) + certificate, failures := client.ObtainCertificate([]string{cfg.Host}, true, nil) if len(failures) == 0 { // Success - immediately save the certificate resource err := saveCertResource(certificate) @@ -289,11 +293,9 @@ func HostQualifies(hostname string) bool { strings.TrimSpace(hostname) != "" && net.ParseIP(hostname) == nil && // cannot be an IP address, see: https://community.letsencrypt.org/t/certificate-for-static-ip/84/2?u=mholt - // TODO: net.ParseIP also catches the two variants without brackets - hostname != "[::]" && // before parsing - hostname != "::" && // after parsing - hostname != "[::1]" && // before parsing - hostname != "::1" // after parsing + // These special cases can sneak through if specified with -host and with empty/no Caddyfile + hostname != "[::]" && + hostname != "[::1]" } // existingCertAndKey returns true if the host has a certificate @@ -335,8 +337,8 @@ func newClientPort(leEmail, port string) (*acme.Client, error) { if err != nil { return nil, err } - client.SetHTTPPort(port) - client.SetTLSPort(port) + client.SetHTTPAddress(":" + port) + client.SetTLSAddress(":" + port) client.ExcludeChallenges([]string{"tls-sni-01", "dns-01"}) // We can only guarantee http-01 at this time // If not registered, the user must register an account with the CA diff --git a/caddy/letsencrypt/maintain.go b/caddy/letsencrypt/maintain.go index d9ac45e9..0fca4ad4 100644 --- a/caddy/letsencrypt/maintain.go +++ b/caddy/letsencrypt/maintain.go @@ -49,7 +49,7 @@ func maintainAssets(configs []server.Config, stopChan chan struct{}) { case <-ocspTicker.C: for bundle, oldResp := range ocspCache { // start checking OCSP staple about halfway through validity period for good measure - refreshTime := oldResp.ThisUpdate.Add(oldResp.NextUpdate.Sub(oldResp.ThisUpdate) / 10) + refreshTime := oldResp.ThisUpdate.Add(oldResp.NextUpdate.Sub(oldResp.ThisUpdate) / 2) if time.Now().After(refreshTime) { _, newResp, err := acme.GetOCSPForCert(*bundle) if err != nil { @@ -112,8 +112,8 @@ func renewCertificates(configs []server.Config, useCustomPort bool) (int, []erro // Directly convert it to days for the following checks. daysLeft := int(expTime.Sub(time.Now().UTC()).Hours() / 24) - // Renew with two weeks or less remaining. - if daysLeft <= 14 { + // Renew if getting close to expiration. + if daysLeft <= renewDaysBefore { log.Printf("[INFO] Certificate for %s has %d days remaining; attempting renewal", cfg.Host, daysLeft) var client *acme.Client if useCustomPort { @@ -164,11 +164,13 @@ func renewCertificates(configs []server.Config, useCustomPort bool) (int, []erro saveCertResource(newCertMeta) n++ - } else if daysLeft <= 21 { - // Warn on 21 days remaining. TODO: Just do this once... - log.Printf("[WARNING] Certificate for %s has %d days remaining; will automatically renew when 14 days remain\n", cfg.Host, daysLeft) + } else if daysLeft <= renewDaysBefore+7 && daysLeft >= renewDaysBefore+6 { + log.Printf("[WARNING] Certificate for %s has %d days remaining; will automatically renew when %d days remain\n", cfg.Host, daysLeft, renewDaysBefore) } } return n, errs } + +// renewDaysBefore is how many days before expiration to renew certificates. +const renewDaysBefore = 14