Fix timeout for HTTP-01, bug in HTTP challenge response & only count domains towards user limit after acquiring locks

This commit is contained in:
Moritz Marquardt 2021-11-20 21:39:40 +01:00
parent f22cd6c4e0
commit eae4513b96
No known key found for this signature in database
GPG key ID: D5788327BEE388B6
2 changed files with 13 additions and 12 deletions

View file

@ -95,12 +95,7 @@ var tlsConfig = &tls.Config{
return nil, errors.New("won't request certificate for main domain, something really bad has happened")
}
err = CheckUserLimit(targetOwner)
if err != nil {
return nil, err
}
tlsCertificate, err = obtainCert(acmeClient, []string{sni}, nil)
tlsCertificate, err = obtainCert(acmeClient, []string{sni}, nil, targetOwner)
if err != nil {
return nil, err
}
@ -241,7 +236,7 @@ func retrieveCertFromDB(sni []byte) (tls.Certificate, bool) {
// renew certificates 7 days before they expire
if !tlsCertificate.Leaf.NotAfter.After(time.Now().Add(-7 * 24 * time.Hour)) {
go (func() {
tlsCertificate, err = obtainCert(acmeClient, []string{string(sni)}, res)
tlsCertificate, err = obtainCert(acmeClient, []string{string(sni)}, res, "")
if err != nil {
log.Printf("Couldn't renew certificate for %s: %s", sni, err)
}
@ -253,7 +248,7 @@ func retrieveCertFromDB(sni []byte) (tls.Certificate, bool) {
}
var obtainLocks = sync.Map{}
func obtainCert(acmeClient *lego.Client, domains []string, renew *certificate.Resource) (tls.Certificate, error) {
func obtainCert(acmeClient *lego.Client, domains []string, renew *certificate.Resource, user string) (tls.Certificate, error) {
name := strings.TrimPrefix(domains[0], "*")
if os.Getenv("DNS_PROVIDER") == "" && len(domains[0]) > 0 && domains[0][0] == '*' {
domains = domains[1:]
@ -284,6 +279,12 @@ func obtainCert(acmeClient *lego.Client, domains []string, renew *certificate.Re
log.Printf("Renewing certificate for %v", domains)
res, err = acmeClient.Certificate.Renew(*renew, true, false, "")
} else {
if user != "" {
if err := CheckUserLimit(user); err != nil {
return tls.Certificate{}, err
}
}
if os.Getenv("ACME_USE_RATE_LIMITS") != "false" {
acmeClientOrderLimit.Take()
acmeClientRequestLimit.Take()
@ -422,7 +423,7 @@ func setupCertificates() {
// key database is not working
panic(err)
} else if resBytes == nil {
_, err = obtainCert(mainDomainAcmeClient, []string{"*" + string(MainDomainSuffix), string(MainDomainSuffix[1:])}, nil)
_, err = obtainCert(mainDomainAcmeClient, []string{"*" + string(MainDomainSuffix), string(MainDomainSuffix[1:])}, nil, "")
if err != nil {
log.Fatalf("Couldn't renew certificate for *%s: %s", MainDomainSuffix, err)
}
@ -495,7 +496,7 @@ func setupCertificates() {
// 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)
_, err = obtainCert(mainDomainAcmeClient, []string{"*" + string(MainDomainSuffix), string(MainDomainSuffix[1:])}, res, "")
if err != nil {
log.Printf("Couldn't renew certificate for *%s: %s", MainDomainSuffix, err)
}

View file

@ -91,7 +91,7 @@ func main() {
MaxRequestBodySize: 0,
NoDefaultServerHeader: true,
NoDefaultDate: true,
ReadTimeout: 10 * time.Second,
ReadTimeout: 30 * time.Second, // needs to be this high for ACME certificates with ZeroSSL & HTTP-01 challenge
Concurrency: 1024 * 32, // TODO: adjust bottlenecks for best performance with Gitea!
MaxConnsPerIP: 100,
}
@ -110,7 +110,7 @@ func main() {
err := fasthttp.ListenAndServe("[::]:80", func(ctx *fasthttp.RequestCtx) {
if bytes.HasPrefix(ctx.Path(), challengePath) {
challenge, ok := challengeCache.Get(string(TrimHostPort(ctx.Host())) + "/" + string(bytes.TrimPrefix(ctx.Path(), challengePath)))
if !ok {
if !ok || challenge == nil {
ctx.SetStatusCode(http.StatusNotFound)
ctx.SetBodyString("no challenge for this token")
}