mv acme config setup into own func

This commit is contained in:
6543 2021-12-05 16:33:56 +01:00
parent 77e39b2213
commit 11fa729686
No known key found for this signature in database
GPG Key ID: C99B82E40B027BAE
3 changed files with 106 additions and 84 deletions

View File

@ -102,7 +102,12 @@ func Serve(ctx *cli.Context) error {
keyCache, challengeCache, dnsLookupCache, canonicalDomainCache, keyCache, challengeCache, dnsLookupCache, canonicalDomainCache,
keyDatabase)) keyDatabase))
certificates.SetupCertificates(mainDomainSuffix, acmeAPI, acmeMail, acmeEabHmac, acmeEabKID, dnsProvider, acmeUseRateLimits, acmeAcceptTerms, enableHTTPServer, challengeCache, keyDatabase) acmeConfig, err := certificates.SetupAcmeConfig(acmeAPI, acmeMail, acmeEabHmac, acmeEabKID, acmeAcceptTerms)
if err != nil {
return err
}
certificates.SetupCertificates(mainDomainSuffix, dnsProvider, acmeConfig, acmeUseRateLimits, enableHTTPServer, challengeCache, keyDatabase)
if enableHTTPServer { if enableHTTPServer {
go func() { go func() {

View File

@ -0,0 +1,27 @@
package certificates
import (
"crypto"
"github.com/go-acme/lego/v4/registration"
)
type AcmeAccount struct {
Email string
Registration *registration.Resource
Key crypto.PrivateKey `json:"-"`
KeyPEM string `json:"Key"`
}
// make sure AcmeAccount match User interface
var _ registration.User = &AcmeAccount{}
func (u *AcmeAccount) GetEmail() string {
return u.Email
}
func (u AcmeAccount) GetRegistration() *registration.Resource {
return u.Registration
}
func (u *AcmeAccount) GetPrivateKey() crypto.PrivateKey {
return u.Key
}

View File

@ -2,7 +2,6 @@ package certificates
import ( import (
"bytes" "bytes"
"crypto"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/elliptic" "crypto/elliptic"
"crypto/rand" "crypto/rand"
@ -12,15 +11,12 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"io/ioutil" "io/ioutil"
"log"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/reugn/equalizer"
"github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certcrypto"
"github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/certificate"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
@ -28,6 +24,8 @@ import (
"github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/lego"
"github.com/go-acme/lego/v4/providers/dns" "github.com/go-acme/lego/v4/providers/dns"
"github.com/go-acme/lego/v4/registration" "github.com/go-acme/lego/v4/registration"
"github.com/reugn/equalizer"
"github.com/rs/zerolog/log"
"codeberg.org/codeberg/pages/server/cache" "codeberg.org/codeberg/pages/server/cache"
"codeberg.org/codeberg/pages/server/database" "codeberg.org/codeberg/pages/server/database"
@ -147,26 +145,6 @@ func checkUserLimit(user string) error {
return nil return nil
} }
var myAcmeAccount AcmeAccount
var myAcmeConfig *lego.Config
type AcmeAccount struct {
Email string
Registration *registration.Resource
Key crypto.PrivateKey `json:"-"`
KeyPEM string `json:"Key"`
}
func (u *AcmeAccount) GetEmail() string {
return u.Email
}
func (u AcmeAccount) GetRegistration() *registration.Resource {
return u.Registration
}
func (u *AcmeAccount) GetPrivateKey() crypto.PrivateKey {
return u.Key
}
var acmeClient, mainDomainAcmeClient *lego.Client var acmeClient, mainDomainAcmeClient *lego.Client
var acmeClientCertificateLimitPerUser = map[string]*equalizer.TokenBucket{} var acmeClientCertificateLimitPerUser = map[string]*equalizer.TokenBucket{}
@ -331,15 +309,12 @@ func obtainCert(acmeClient *lego.Client, domains []string, renew *certificate.Re
return tlsCertificate, nil return tlsCertificate, nil
} }
func SetupCertificates(mainDomainSuffix []byte, acmeAPI, acmeMail, acmeEabHmac, acmeEabKID, dnsProvider string, acmeUseRateLimits, acmeAcceptTerms, enableHTTPServer bool, challengeCache cache.SetGetKey, keyDatabase database.KeyDB) { func SetupAcmeConfig(acmeAPI, acmeMail, acmeEabHmac, acmeEabKID string, acmeAcceptTerms bool) (*lego.Config, error) {
// getting main cert before ACME account so that we can panic here on database failure without hitting rate limits const configFile = "acme-account.json"
mainCertBytes, err := keyDatabase.Get(mainDomainSuffix) var myAcmeAccount AcmeAccount
if err != nil { var myAcmeConfig *lego.Config
// key database is not working
panic(err)
}
if account, err := ioutil.ReadFile("acme-account.json"); err == nil { if account, err := ioutil.ReadFile(configFile); err == nil {
err = json.Unmarshal(account, &myAcmeAccount) err = json.Unmarshal(account, &myAcmeAccount)
if err != nil { if err != nil {
panic(err) panic(err)
@ -351,11 +326,18 @@ func SetupCertificates(mainDomainSuffix []byte, acmeAPI, acmeMail, acmeEabHmac,
myAcmeConfig = lego.NewConfig(&myAcmeAccount) myAcmeConfig = lego.NewConfig(&myAcmeAccount)
myAcmeConfig.CADirURL = acmeAPI myAcmeConfig.CADirURL = acmeAPI
myAcmeConfig.Certificate.KeyType = certcrypto.RSA2048 myAcmeConfig.Certificate.KeyType = certcrypto.RSA2048
// Validate Config
_, err := lego.NewClient(myAcmeConfig) _, err := lego.NewClient(myAcmeConfig)
if err != nil { if err != nil {
// TODO: should we fail hard instead?
log.Printf("[ERROR] Can't create ACME client, continuing with mock certs only: %s", err) log.Printf("[ERROR] Can't create ACME client, continuing with mock certs only: %s", err)
} }
} else if os.IsNotExist(err) { return myAcmeConfig, nil
} else if !os.IsNotExist(err) {
return nil, err
}
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil { if err != nil {
panic(err) panic(err)
@ -399,18 +381,26 @@ func SetupCertificates(mainDomainSuffix []byte, acmeAPI, acmeMail, acmeEabHmac,
log.Printf("[FAIL] Error during json.Marshal(myAcmeAccount), waiting for manual restart to avoid rate limits: %s", err) log.Printf("[FAIL] Error during json.Marshal(myAcmeAccount), waiting for manual restart to avoid rate limits: %s", err)
select {} select {}
} }
err = ioutil.WriteFile("acme-account.json", acmeAccountJson, 0600) err = ioutil.WriteFile(configFile, acmeAccountJson, 0600)
if err != nil { if err != nil {
log.Printf("[FAIL] Error during ioutil.WriteFile(\"acme-account.json\"), waiting for manual restart to avoid rate limits: %s", err) log.Printf("[FAIL] Error during ioutil.WriteFile(\"acme-account.json\"), waiting for manual restart to avoid rate limits: %s", err)
select {} select {}
} }
} }
} }
} else {
return myAcmeConfig, nil
}
func SetupCertificates(mainDomainSuffix []byte, dnsProvider string, acmeConfig *lego.Config, acmeUseRateLimits, enableHTTPServer bool, challengeCache cache.SetGetKey, keyDatabase database.KeyDB) {
// getting main cert before ACME account so that we can panic here on database failure without hitting rate limits
mainCertBytes, err := keyDatabase.Get(mainDomainSuffix)
if err != nil {
// key database is not working
panic(err) panic(err)
} }
acmeClient, err = lego.NewClient(myAcmeConfig) acmeClient, err = lego.NewClient(acmeConfig)
if err != nil { if err != nil {
log.Printf("[ERROR] Can't create ACME client, continuing with mock certs only: %s", err) log.Printf("[ERROR] Can't create ACME client, continuing with mock certs only: %s", err)
} else { } else {
@ -426,7 +416,7 @@ func SetupCertificates(mainDomainSuffix []byte, acmeAPI, acmeMail, acmeEabHmac,
} }
} }
mainDomainAcmeClient, err = lego.NewClient(myAcmeConfig) mainDomainAcmeClient, err = lego.NewClient(acmeConfig)
if err != nil { if err != nil {
log.Printf("[ERROR] Can't create ACME client, continuing with mock certs only: %s", err) log.Printf("[ERROR] Can't create ACME client, continuing with mock certs only: %s", err)
} else { } else {