mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 16:33:47 +03:00
at startup, request missing acme tls certificates more quickly/silently
This commit is contained in:
parent
dbd6773f6b
commit
4701857d7f
2 changed files with 42 additions and 0 deletions
|
@ -200,6 +200,40 @@ func Load(name, acmeDir, contactEmail, directoryURL string, eabKeyID string, eab
|
|||
return a, nil
|
||||
}
|
||||
|
||||
// CertAvailable checks whether a non-expired ECDSA certificate is available in the
|
||||
// cache for host. No other checks than expiration are done.
|
||||
func (m *Manager) CertAvailable(ctx context.Context, log mlog.Log, host dns.Domain) (bool, error) {
|
||||
ck := host.ASCII // Would be "+rsa" for rsa keys.
|
||||
data, err := m.Manager.Cache.Get(ctx, ck)
|
||||
if err != nil && errors.Is(err, autocert.ErrCacheMiss) {
|
||||
return false, nil
|
||||
} else if err != nil {
|
||||
return false, fmt.Errorf("attempt to get certificate from cache: %v", err)
|
||||
}
|
||||
|
||||
// The cached keycert is of the form: private key, leaf certificate, intermediate certificates...
|
||||
privb, rem := pem.Decode(data)
|
||||
if privb == nil {
|
||||
return false, fmt.Errorf("missing private key in cached keycert file")
|
||||
}
|
||||
pubb, _ := pem.Decode(rem)
|
||||
if pubb == nil {
|
||||
return false, fmt.Errorf("missing certificate in cached keycert file")
|
||||
} else if pubb.Type != "CERTIFICATE" {
|
||||
return false, fmt.Errorf("second pem block is %q, expected CERTIFICATE", pubb.Type)
|
||||
}
|
||||
cert, err := x509.ParseCertificate(pubb.Bytes)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("parsing certificate from cached keycert file: %v", err)
|
||||
}
|
||||
// We assume the certificate has a matching hostname, and is properly CA-signed. We
|
||||
// only check the expiration time.
|
||||
if time.Until(cert.NotBefore) > 0 || time.Since(cert.NotAfter) > 0 {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// SetAllowedHostnames sets a new list of allowed hostnames for automatic TLS.
|
||||
// After setting the host names, a goroutine is start to check that new host names
|
||||
// are fully served by publicIPs (only if non-empty and there is no unspecified
|
||||
|
|
|
@ -801,6 +801,14 @@ func Serve() {
|
|||
i := 0
|
||||
for m, hosts := range ensureManagerHosts {
|
||||
for host := range hosts {
|
||||
// Check if certificate is already available. If so, we don't print as much after a
|
||||
// restart, and finish more quickly if only a few certificates are missing/old.
|
||||
if avail, err := m.CertAvailable(mox.Shutdown, pkglog, host); err != nil {
|
||||
pkglog.Errorx("checking acme certificate availability", err, slog.Any("host", host))
|
||||
} else if avail {
|
||||
continue
|
||||
}
|
||||
|
||||
if i >= 10 {
|
||||
// Just in case someone adds quite some domains to their config. We don't want to
|
||||
// hit any ACME rate limits.
|
||||
|
|
Loading…
Reference in a new issue