make certdb maintain go routine a own func

This commit is contained in:
6543 2021-12-05 17:44:10 +01:00
parent de439f9bec
commit a0e0d2d335
No known key found for this signature in database
GPG key ID: C99B82E40B027BAE
2 changed files with 64 additions and 71 deletions

View file

@ -109,6 +109,9 @@ func Serve(ctx *cli.Context) error {
certificates.SetupCertificates(mainDomainSuffix, dnsProvider, acmeConfig, acmeUseRateLimits, enableHTTPServer, challengeCache, keyDatabase) certificates.SetupCertificates(mainDomainSuffix, dnsProvider, acmeConfig, acmeUseRateLimits, enableHTTPServer, challengeCache, keyDatabase)
// TODO: make it graceful
go certificates.MaintainCertDB(mainDomainSuffix, dnsProvider, acmeUseRateLimits, keyDatabase)
if enableHTTPServer { if enableHTTPServer {
go func() { go func() {
err := httpServer.ListenAndServe("[::]:80") err := httpServer.ListenAndServe("[::]:80")

View file

@ -444,75 +444,65 @@ func SetupCertificates(mainDomainSuffix []byte, dnsProvider string, acmeConfig *
log.Printf("[ERROR] Couldn't renew main domain certificate, continuing with mock certs only: %s", err) log.Printf("[ERROR] Couldn't renew main domain certificate, continuing with mock certs only: %s", err)
} }
} }
}
go (func() {
for { func MaintainCertDB(mainDomainSuffix []byte, dnsProvider string, acmeUseRateLimits bool, keyDatabase database.CertDB) {
err := keyDatabase.Sync() for {
if err != nil { // clean up expired certs
log.Printf("[ERROR] Syncing key database failed: %s", err) now := time.Now()
} expiredCertCount := 0
time.Sleep(5 * time.Minute) keyDatabaseIterator := keyDatabase.Items()
// TODO: graceful exit key, resBytes, err := keyDatabaseIterator.Next()
} for err == nil {
})() if !bytes.Equal(key, mainDomainSuffix) {
go (func() { resGob := bytes.NewBuffer(resBytes)
for { resDec := gob.NewDecoder(resGob)
// clean up expired certs res := &certificate.Resource{}
now := time.Now() err = resDec.Decode(res)
expiredCertCount := 0 if err != nil {
keyDatabaseIterator := keyDatabase.Items() panic(err)
key, resBytes, err := keyDatabaseIterator.Next() }
for err == nil {
if !bytes.Equal(key, mainDomainSuffix) { tlsCertificates, err := certcrypto.ParsePEMBundle(res.Certificate)
resGob := bytes.NewBuffer(resBytes) if err != nil || !tlsCertificates[0].NotAfter.After(now) {
resDec := gob.NewDecoder(resGob) err := keyDatabase.Delete(key)
res := &certificate.Resource{} if err != nil {
err = resDec.Decode(res) log.Printf("[ERROR] Deleting expired certificate for %s failed: %s", string(key), err)
if err != nil { } else {
panic(err) expiredCertCount++
} }
}
tlsCertificates, err := certcrypto.ParsePEMBundle(res.Certificate) }
if err != nil || !tlsCertificates[0].NotAfter.After(now) { key, resBytes, err = keyDatabaseIterator.Next()
err := keyDatabase.Delete(key) }
if err != nil { log.Printf("[INFO] Removed %d expired certificates from the database", expiredCertCount)
log.Printf("[ERROR] Deleting expired certificate for %s failed: %s", string(key), err)
} else { // compact the database
expiredCertCount++ result, err := keyDatabase.Compact()
} if err != nil {
} log.Printf("[ERROR] Compacting key database failed: %s", err)
} } else {
key, resBytes, err = keyDatabaseIterator.Next() log.Printf("[INFO] Compacted key database (%+v)", result)
} }
log.Printf("[INFO] Removed %d expired certificates from the database", expiredCertCount)
// update main cert
// compact the database res := &certificate.Resource{}
result, err := keyDatabase.Compact() if !database.PogrebGet(keyDatabase, mainDomainSuffix, res) {
if err != nil { log.Printf("[ERROR] Couldn't renew certificate for main domain: %s", "expected main domain cert to exist, but it's missing - seems like the database is corrupted")
log.Printf("[ERROR] Compacting key database failed: %s", err) } else {
} else { tlsCertificates, err := certcrypto.ParsePEMBundle(res.Certificate)
log.Printf("[INFO] Compacted key database (%+v)", result)
} // renew main certificate 30 days before it expires
if !tlsCertificates[0].NotAfter.After(time.Now().Add(-30 * 24 * time.Hour)) {
// update main cert go (func() {
res := &certificate.Resource{} _, err = obtainCert(mainDomainAcmeClient, []string{"*" + string(mainDomainSuffix), string(mainDomainSuffix[1:])}, res, "", dnsProvider, mainDomainSuffix, acmeUseRateLimits, keyDatabase)
if !database.PogrebGet(keyDatabase, mainDomainSuffix, res) { if err != nil {
log.Printf("[ERROR] Couldn't renew certificate for main domain: %s", "expected main domain cert to exist, but it's missing - seems like the database is corrupted") log.Printf("[ERROR] Couldn't renew certificate for main domain: %s", err)
} else { }
tlsCertificates, err := certcrypto.ParsePEMBundle(res.Certificate) })()
}
// renew main certificate 30 days before it expires }
if !tlsCertificates[0].NotAfter.After(time.Now().Add(-30 * 24 * time.Hour)) {
go (func() { time.Sleep(12 * time.Hour)
_, err = obtainCert(mainDomainAcmeClient, []string{"*" + string(mainDomainSuffix), string(mainDomainSuffix[1:])}, res, "", dnsProvider, mainDomainSuffix, acmeUseRateLimits, keyDatabase) }
if err != nil {
log.Printf("[ERROR] Couldn't renew certificate for main domain: %s", err)
}
})()
}
}
time.Sleep(12 * time.Hour)
}
})()
} }