mholt / acmez

Premier ACME client library for Go
https://pkg.go.dev/github.com/mholt/acmez/v2
Apache License 2.0
272 stars 32 forks source link

If one of multiple SAN's challenges fails, multiple useless "ghost" challenges are presented #7

Closed skirsten closed 2 years ago

skirsten commented 2 years ago

If

then all certificates up to the one that failed will be presented and cleaned up again. No actual solving is done. This means that if there are 100 SAN's requested and the last one fails, 99 completely useless calls will be done to Present and CleanUp (which in turn do more requests to DNS api's etc.)

Here is a example log with replaced domain where the challenge for c.example.com fails:

acmez@v1.0.1/client.go:394      trying to solve challenge       {"identifier": "a.example.com", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
daemon/main.go:35       present {"id": "a.example.com", "record": "_acme-challenge.a.example.com", "value": "dJ8PiGOYRZRm9ncUaH9zoV-y4aJqymOCbt9fntmbdAo"}
acmez@v1.0.1/client.go:394      trying to solve challenge       {"identifier": "b.example.com", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
daemon/main.go:35       present {"id": "b.example.com", "record": "_acme-challenge.b.example.com", "value": "_vJbdqEhAogUIrwOGwiduTWY3vC9ZSrN7_8eQ0kI-78"}
acmez@v1.0.1/client.go:394      trying to solve challenge       {"identifier": "c.example.com", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
daemon/main.go:35       present {"id": "c.example.com", "record": "_acme-challenge.c.example.com", "value": "ifP-oljAlaX-Zf-yDBxV79mHrABZnXyp1Bx9zX1_LpE"}
acmez@v1.0.1/client.go:394      trying to solve challenge       {"identifier": "d.example.com", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
daemon/main.go:35       present {"id": "d.example.com", "record": "_acme-challenge.d.example.com", "value": "g3NU4vF2SSNEWWaYHcJ7STO6zU5eQB02drvadyc75UQ"}
daemon/main.go:49       wait    {"id": "a.example.com", "record": "_acme-challenge.a.example.com", "value": "dJ8PiGOYRZRm9ncUaH9zoV-y4aJqymOCbt9fntmbdAo"}
acmez@v1.0.1/client.go:433      challenge accepted      {"identifier": "a.example.com", "challenge_type": "dns-01"}
daemon/main.go:49       wait    {"id": "b.example.com", "record": "_acme-challenge.b.example.com", "value": "_vJbdqEhAogUIrwOGwiduTWY3vC9ZSrN7_8eQ0kI-78"}
acmez@v1.0.1/client.go:433      challenge accepted      {"identifier": "b.example.com", "challenge_type": "dns-01"}
daemon/main.go:49       wait    {"id": "c.example.com", "record": "_acme-challenge.c.example.com", "value": "ifP-oljAlaX-Zf-yDBxV79mHrABZnXyp1Bx9zX1_LpE"}
acmez@v1.0.1/client.go:433      challenge accepted      {"identifier": "c.example.com", "challenge_type": "dns-01"}
daemon/main.go:49       wait    {"id": "d.example.com", "record": "_acme-challenge.d.example.com", "value": "g3NU4vF2SSNEWWaYHcJ7STO6zU5eQB02drvadyc75UQ"}
acmez@v1.0.1/client.go:433      challenge accepted      {"identifier": "d.example.com", "challenge_type": "dns-01"}
daemon/main.go:90       cleanup {"id": "a.example.com", "record": "_acme-challenge.a.example.com", "value": "dJ8PiGOYRZRm9ncUaH9zoV-y4aJqymOCbt9fntmbdAo"}
daemon/main.go:90       cleanup {"id": "b.example.com", "record": "_acme-challenge.b.example.com", "value": "_vJbdqEhAogUIrwOGwiduTWY3vC9ZSrN7_8eQ0kI-78"}
daemon/main.go:90       cleanup {"id": "c.example.com", "record": "_acme-challenge.c.example.com", "value": "ifP-oljAlaX-Zf-yDBxV79mHrABZnXyp1Bx9zX1_LpE"}
acmez@v1.0.1/client.go:512      challenge failed        {"identifier": "c.example.com", "challenge_type": "dns-01", "problem": {"type": "urn:ietf:params:acme:error:unauthorized", "title": "", "detail": "Incorrect TXT record \"ifP-oljAlaX-Zf-yDBxV79mHrABZnXyp1Bx9zX1_LpE_fail\" found at _acme-challenge.c.example.com", "instance": "", "subproblems": []}}
github.com/mholt/acmez.(*Client).pollAuthorization
        /home/simon/go/pkg/mod/github.com/mholt/acmez@v1.0.1/client.go:512
github.com/mholt/acmez.(*Client).solveChallenges
        /home/simon/go/pkg/mod/github.com/mholt/acmez@v1.0.1/client.go:368
github.com/mholt/acmez.(*Client).ObtainCertificateUsingCSR
        /home/simon/go/pkg/mod/github.com/mholt/acmez@v1.0.1/client.go:127
github.com/mholt/acmez.(*Client).ObtainCertificate
        /home/simon/go/pkg/mod/github.com/mholt/acmez@v1.0.1/client.go:235
...
daemon/main.go:90       cleanup {"id": "d.example.com", "record": "_acme-challenge.d.example.com", "value": "g3NU4vF2SSNEWWaYHcJ7STO6zU5eQB02drvadyc75UQ"}
acmez@v1.0.1/client.go:143      validating authorization        {"identifier": "c.example.com", "problem": {"type": "urn:ietf:params:acme:error:unauthorized", "title": "", "detail": "Incorrect TXT record \"ifP-oljAlaX-Zf-yDBxV79mHrABZnXyp1Bx9zX1_LpE_fail\" found at _acme-challenge.c.example.com", "instance": "", "subproblems": []}, "order": "https://acme-staging-v02.api.letsencrypt.org/acme/order/38834018/1399577638", "attempt": 1, "max_attempts": 3}
github.com/mholt/acmez.(*Client).ObtainCertificateUsingCSR
        /home/simon/go/pkg/mod/github.com/mholt/acmez@v1.0.1/client.go:143
github.com/mholt/acmez.(*Client).ObtainCertificate
        /home/simon/go/pkg/mod/github.com/mholt/acmez@v1.0.1/client.go:235
...
acmez@v1.0.1/client.go:461      no solver configured    {"challenge_type": "tls-alpn-01"}
acmez@v1.0.1/client.go:461      no solver configured    {"challenge_type": "http-01"}
acmez@v1.0.1/client.go:394      trying to solve challenge       {"identifier": "a.example.com", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
daemon/main.go:35       present {"id": "a.example.com", "record": "_acme-challenge.a.example.com", "value": "qHh2Rep4kRSFiJEQ5x4vKS6OwDz_3A4vbo2qnsCCUY0"}
acmez@v1.0.1/client.go:461      no solver configured    {"challenge_type": "tls-alpn-01"}
acmez@v1.0.1/client.go:461      no solver configured    {"challenge_type": "http-01"}
acmez@v1.0.1/client.go:394      trying to solve challenge       {"identifier": "b.example.com", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
daemon/main.go:35       present {"id": "b.example.com", "record": "_acme-challenge.b.example.com", "value": "DmvYmPXjLpSkcdXgn7f_IoTjYqwJmsgIBR9AFyuSxY4"}
acmez@v1.0.1/client.go:461      no solver configured    {"challenge_type": "tls-alpn-01"}
acmez@v1.0.1/client.go:461      no solver configured    {"challenge_type": "http-01"}
daemon/main.go:90       cleanup {"id": "a.example.com", "record": "_acme-challenge.a.example.com", "value": "qHh2Rep4kRSFiJEQ5x4vKS6OwDz_3A4vbo2qnsCCUY0"}
daemon/main.go:90       cleanup {"id": "b.example.com", "record": "_acme-challenge.b.example.com", "value": "DmvYmPXjLpSkcdXgn7f_IoTjYqwJmsgIBR9AFyuSxY4"}

obtaining certificate: solving challenges: c.example.com: no solvers available for remaining challenges (configured=[dns-01] offered=[http-01 dns-01 tls-alpn-01] remaining=[http-01 tls-alpn-01]) (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/38834018/1399583088)

After the challenge failed, a.example.com and b.example.com are presented and cleaned up without any attempted solve.

mholt commented 2 years ago

Hmm, thanks for reporting this. What is your code that I can use as a basis to reproduce this?

mholt commented 2 years ago

@skirsten Might be solved by #8. Closing unless there's further indication it is still a problem.

skirsten commented 2 years ago

Hi, sorry for not providing any help to reproduce this :disappointed:. The code I was using was tightly integrated with my use-case. It wasn't as easy as copy-pasting it and then I completely forgot about it...

I will check later today if #8 solves this problem and if not, provide some code to reproduce.

skirsten commented 2 years ago

Yes, I can confirm that #8 solves this problem :) Thanks for the work @N0Cloud

mholt commented 2 years ago

Yay! Glad we got it merged then. Should go out on the next Caddy and CertMagic. Hope it didn't break anything, ha. :sweat_smile: