mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2024-11-18 10:29:43 +00:00
rm certDB helper and build in
This commit is contained in:
parent
a0534f1fde
commit
5fe51d8621
5 changed files with 53 additions and 59 deletions
|
@ -188,8 +188,11 @@ func (a AcmeHTTPChallengeProvider) CleanUp(domain, token, _ string) error {
|
|||
|
||||
func retrieveCertFromDB(sni, mainDomainSuffix []byte, dnsProvider string, acmeUseRateLimits bool, keyDatabase database.CertDB) (tls.Certificate, bool) {
|
||||
// parse certificate from database
|
||||
res := &certificate.Resource{}
|
||||
if !database.PogrebGet(keyDatabase, sni, res) {
|
||||
res, err := keyDatabase.Get(sni)
|
||||
if err != nil {
|
||||
panic(err) // TODO: no panic
|
||||
}
|
||||
if res == nil {
|
||||
return tls.Certificate{}, false
|
||||
}
|
||||
|
||||
|
@ -294,7 +297,9 @@ func obtainCert(acmeClient *lego.Client, domains []string, renew *certificate.Re
|
|||
if err == nil && tlsCertificate.Leaf.NotAfter.After(time.Now()) {
|
||||
// avoid sending a mock cert instead of a still valid cert, instead abuse CSR field to store time to try again at
|
||||
renew.CSR = []byte(strconv.FormatInt(time.Now().Add(6*time.Hour).Unix(), 10))
|
||||
database.PogrebPut(keyDatabase, []byte(name), renew)
|
||||
if err := keyDatabase.Put(name, renew); err != nil {
|
||||
return mockCert(domains[0], err.Error(), string(mainDomainSuffix), keyDatabase), err
|
||||
}
|
||||
return tlsCertificate, nil
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +307,9 @@ func obtainCert(acmeClient *lego.Client, domains []string, renew *certificate.Re
|
|||
}
|
||||
log.Printf("Obtained certificate for %v", domains)
|
||||
|
||||
database.PogrebPut(keyDatabase, []byte(name), res)
|
||||
if err := keyDatabase.Put(name, res); err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
tlsCertificate, err := tls.X509KeyPair(res.Certificate, res.PrivateKey)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
|
@ -447,12 +454,12 @@ func SetupCertificates(mainDomainSuffix []byte, dnsProvider string, acmeConfig *
|
|||
}
|
||||
}
|
||||
|
||||
func MaintainCertDB(ctx context.Context, interval time.Duration, mainDomainSuffix []byte, dnsProvider string, acmeUseRateLimits bool, keyDatabase database.CertDB) {
|
||||
func MaintainCertDB(ctx context.Context, interval time.Duration, mainDomainSuffix []byte, dnsProvider string, acmeUseRateLimits bool, certDB database.CertDB) {
|
||||
for {
|
||||
// clean up expired certs
|
||||
now := time.Now()
|
||||
expiredCertCount := 0
|
||||
keyDatabaseIterator := keyDatabase.Items()
|
||||
keyDatabaseIterator := certDB.Items()
|
||||
key, resBytes, err := keyDatabaseIterator.Next()
|
||||
for err == nil {
|
||||
if !bytes.Equal(key, mainDomainSuffix) {
|
||||
|
@ -466,7 +473,7 @@ func MaintainCertDB(ctx context.Context, interval time.Duration, mainDomainSuffi
|
|||
|
||||
tlsCertificates, err := certcrypto.ParsePEMBundle(res.Certificate)
|
||||
if err != nil || !tlsCertificates[0].NotAfter.After(now) {
|
||||
err := keyDatabase.Delete(key)
|
||||
err := certDB.Delete(key)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] Deleting expired certificate for %s failed: %s", string(key), err)
|
||||
} else {
|
||||
|
@ -479,7 +486,7 @@ func MaintainCertDB(ctx context.Context, interval time.Duration, mainDomainSuffi
|
|||
log.Printf("[INFO] Removed %d expired certificates from the database", expiredCertCount)
|
||||
|
||||
// compact the database
|
||||
result, err := keyDatabase.Compact()
|
||||
result, err := certDB.Compact()
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] Compacting key database failed: %s", err)
|
||||
} else {
|
||||
|
@ -487,16 +494,18 @@ func MaintainCertDB(ctx context.Context, interval time.Duration, mainDomainSuffi
|
|||
}
|
||||
|
||||
// update main cert
|
||||
res := &certificate.Resource{}
|
||||
if !database.PogrebGet(keyDatabase, mainDomainSuffix, res) {
|
||||
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")
|
||||
res, err := certDB.Get(mainDomainSuffix)
|
||||
if err != nil {
|
||||
log.Err(err).Msgf("could not get cert for domain '%s'", mainDomainSuffix)
|
||||
} else if res == nil {
|
||||
log.Error().Msgf("Couldn't renew certificate for main domain: %s", "expected main domain cert to exist, but it's missing - seems like the database is corrupted")
|
||||
} 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() {
|
||||
_, err = obtainCert(mainDomainAcmeClient, []string{"*" + string(mainDomainSuffix), string(mainDomainSuffix[1:])}, res, "", dnsProvider, mainDomainSuffix, acmeUseRateLimits, keyDatabase)
|
||||
_, err = obtainCert(mainDomainAcmeClient, []string{"*" + string(mainDomainSuffix), string(mainDomainSuffix[1:])}, res, "", dnsProvider, mainDomainSuffix, acmeUseRateLimits, certDB)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] Couldn't renew certificate for main domain: %s", err)
|
||||
}
|
||||
|
|
|
@ -74,7 +74,9 @@ func mockCert(domain, msg, mainDomainSuffix string, keyDatabase database.CertDB)
|
|||
if domain == "*"+mainDomainSuffix || domain == mainDomainSuffix[1:] {
|
||||
databaseName = mainDomainSuffix
|
||||
}
|
||||
database.PogrebPut(keyDatabase, []byte(databaseName), res)
|
||||
if err := keyDatabase.Put(databaseName, res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
tlsCertificate, err := tls.X509KeyPair(res.Certificate, res.PrivateKey)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
)
|
||||
|
||||
func PogrebPut(db CertDB, name []byte, obj interface{}) {
|
||||
var resGob bytes.Buffer
|
||||
resEnc := gob.NewEncoder(&resGob)
|
||||
err := resEnc.Encode(obj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = db.Put(name, resGob.Bytes())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func PogrebGet(db CertDB, name []byte, obj interface{}) bool {
|
||||
resBytes, err := db.Get(name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if resBytes == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
resGob := bytes.NewBuffer(resBytes)
|
||||
resDec := gob.NewDecoder(resGob)
|
||||
err = resDec.Decode(obj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
package database
|
||||
|
||||
import "github.com/akrylysov/pogreb"
|
||||
import (
|
||||
"github.com/akrylysov/pogreb"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
)
|
||||
|
||||
type CertDB interface {
|
||||
Close() error
|
||||
Put(key []byte, value []byte) error
|
||||
Get(key []byte) ([]byte, error)
|
||||
Put(name string, cert *certificate.Resource) error
|
||||
Get(name []byte) (*certificate.Resource, error)
|
||||
Delete(key []byte) error
|
||||
Compact() (pogreb.CompactionResult, error)
|
||||
Items() *pogreb.ItemIterator
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/akrylysov/pogreb"
|
||||
"github.com/akrylysov/pogreb/fs"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type aDB struct {
|
||||
|
@ -23,12 +25,27 @@ func (p aDB) Close() error {
|
|||
return p.intern.Sync()
|
||||
}
|
||||
|
||||
func (p aDB) Put(key []byte, value []byte) error {
|
||||
return p.intern.Put(key, value)
|
||||
func (p aDB) Put(name string, cert *certificate.Resource) error {
|
||||
var resGob bytes.Buffer
|
||||
if err := gob.NewEncoder(&resGob).Encode(cert); err != nil {
|
||||
return err
|
||||
}
|
||||
return p.intern.Put([]byte(name), resGob.Bytes())
|
||||
}
|
||||
|
||||
func (p aDB) Get(key []byte) ([]byte, error) {
|
||||
return p.intern.Get(key)
|
||||
func (p aDB) Get(name []byte) (*certificate.Resource, error) {
|
||||
cert := &certificate.Resource{}
|
||||
resBytes, err := p.intern.Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resBytes == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if err = gob.NewDecoder(bytes.NewBuffer(resBytes)).Decode(cert); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func (p aDB) Delete(key []byte) error {
|
||||
|
|
Loading…
Reference in a new issue