Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic on ZeroSSL API Issuer when no Storage is set #291

Closed
mbardelmeijer opened this issue May 24, 2024 · 3 comments
Closed

Panic on ZeroSSL API Issuer when no Storage is set #291

mbardelmeijer opened this issue May 24, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@mbardelmeijer
Copy link
Contributor

What version of the package are you using?

v0.21.2

What are you trying to do?

We're trying to implement the newly added ZeroSSL API issuer, to allow SSL certificates for IP addresses.

What steps did you take?

We've implemented the issuer conform to the documentation and PR changes. In it's most basic form:

magic.Issuers = append(magic.Issuers, &certmagic.ZeroSSLIssuer{
			APIKey: config.Certificates.ZeroSSLAPIKey,
			Logger: logger.With(zap.String("component", "zerossl_api_issuer")),
})

We handle the distributed HTTP challenge like:

func (s *httpServer) handleCertificateHttpValidation(res http.ResponseWriter, req *http.Request) bool {
	if certmagic.LooksLikeHTTPChallenge(req) {
		for _, issuer := range *s.issuers {
			if am, ok := issuer.(*certmagic.ACMEIssuer); ok {
				if am.HandleHTTPChallenge(res, req) {
					log.Debugf("handled ACME HTTP challenge for %s", req.Host)
	
					return true
				}
			}
		}

		return false
	}

	if certmagic.LooksLikeZeroSSLHTTPValidation(req) {
		for _, issuer := range *s.issuers {
			if am, ok := issuer.(*certmagic.ZeroSSLIssuer); ok {
				if am.HandleZeroSSLHTTPValidation(res, req) {
					log.Debugf("handled ZeroSSL HTTP challenge for %s", req.Host)
	
					return true
				}
			}
		}

		return false
	}

	return false
}

What did you expect to happen, and what actually happened instead?

2024-05-24T19:08:52.443Z        INFO    obtain  obtaining certificate   {"component": "acme", "identifier": "IPADDRESS"}
2024-05-24T19:08:52.445Z        DEBUG   obtain  trying issuer 1/2       {"component": "acme", "issuer": "acme-v02.api.letsencrypt.org-directory"}
2024-05-24T19:08:52.446Z        DEBUG   obtain  trying issuer 2/2       {"component": "acme", "issuer": "zerossl"}
2024-05-24T19:08:52.446Z        INFO    creating certificate    {"component": "zerossl_api_issuer", "identifiers": ["IPADDRESS"]}
2024-05-24T19:08:53.642Z        INFO    created certificate     {"component": "zerossl_api_issuer", "identifiers": ["IPADDRESS"], "cert_id": "CERTID"}
2024-05-24T19:08:53.643Z        INFO    validating identifiers  {"component": "zerossl_api_issuer", "identifiers": ["IPADDRESS"], "cert_id": "CERTID", "verification_method": "HTTP_CSR_HASH"}
2024/05/24 19:08:54 notifying bugsnag: runtime error: invalid memory address or nil pointer dereference
2024-05-24T19:08:54.224Z        DEBUG   stdlib  http/server.go:3411     http: panic serving 34.194.10.63:27608: runtime error: invalid memory address or nil pointer dereference
goroutine 306 [running]:
net/http.(*conn).serve.func1()
        /usr/local/go/src/net/http/server.go:1898 +0xbe
panic({0x114c640?, 0x1c6ccb0?})
        /usr/local/go/src/runtime/panic.go:770 +0x132
github.com/bugsnag/bugsnag-go/v2.(*Notifier).AutoNotify(0xc007bd80c0, {0xc000a791d8, 0x2, 0x2})
        /home/michel/go/pkg/mod/github.com/bugsnag/bugsnag-go/[email protected]/notifier.go:102 +0x545
panic({0x114c640?, 0x1c6ccb0?})
        /usr/local/go/src/runtime/panic.go:770 +0x132
github.com/caddyserver/certmagic.(*ZeroSSLIssuer).getDistributedValidationInfo(0xc007a72f00, {0x14bb350, 0xc000491590}, {0xc004f85bb0, 0xe})
        /home/michel/go/pkg/mod/github.com/caddyserver/[email protected]/zerosslissuer.go:275 +0x112
github.com/caddyserver/certmagic.(*ZeroSSLIssuer).distributedHTTPValidationAnswer(0xc007a72f00, {0x14b9cc8, 0xc007bd29a0}, 0xc00221afc0)
        /home/michel/go/pkg/mod/github.com/caddyserver/[email protected]/httphandlers.go:166 +0x158
github.com/caddyserver/certmagic.(*ZeroSSLIssuer).HandleZeroSSLHTTPValidation(0xc007a72f00?, {0x14b9cc8?, 0xc007bd29a0?}, 0xc00221afc0?)
        /home/michel/go/pkg/mod/github.com/caddyserver/[email protected]/httphandlers.go:154 +0xa9
main.(*httpServer).handleCertificateHttpValidation(0xc007a59440, {0x14b9cc8, 0xc007bd29a0}, 0xc00221afc0)
        /home/michel/code/http.go:236 +0x166
main.(*httpServer).serveRequest(0xc007a59440, {0x14b9cc8, 0xc007bd29a0}, 0xc00221afc0)
        /home/michel/code/http.go:255 +0xb4
main.newHttpServerRateLimiter.func1.1({0x14b9cc8, 0xc007bd29a0}, 0xc00221afc0)
        /home/michel/code/http.go:157 +0xeb
net/http.HandlerFunc.ServeHTTP(0x30?, {0x14b9cc8?, 0xc007bd29a0?}, 0xc000071008?)
        /usr/local/go/src/net/http/server.go:2166 +0x29
net/http.HandlerFunc.ServeHTTP(0xc007a65380?, {0x14b9cc8?, 0xc007bd29a0?}, 0xc007acda78?)
        /usr/local/go/src/net/http/server.go:2166 +0x29
net/http.(*ServeMux).ServeHTTP(0x14bb388?, {0x14b9cc8, 0xc007bd29a0}, 0xc00221afc0)
        /usr/local/go/src/net/http/server.go:2683 +0x1ad
github.com/bugsnag/bugsnag-go/v2.Handler.func1({0x14b9cc8, 0xc007bd29a0}, 0xc00221aea0)
        /home/michel/go/pkg/mod/github.com/bugsnag/bugsnag-go/[email protected]/bugsnag.go:188 +0x238
net/http.HandlerFunc.ServeHTTP(0x473779?, {0x14b9cc8?, 0xc007bd29a0?}, 0xc007acdb68?)
        /usr/local/go/src/net/http/server.go:2166 +0x29
net/http.serverHandler.ServeHTTP({0xc0004914d0?}, {0x14b9cc8?, 0xc007bd29a0?}, 0x6?)
        /usr/local/go/src/net/http/server.go:3137 +0x8e
net/http.(*conn).serve(0xc002501a70, {0x14bb350, 0xc007bd6870})
        /usr/local/go/src/net/http/server.go:2039 +0x5e8
created by net/http.(*Server).Serve in goroutine 116
        /usr/local/go/src/net/http/server.go:3285 +0x4b4
2024-05-24T19:08:55.449Z        INFO    canceled certificate    {"component": "zerossl_api_issuer", "identifiers": ["IPADDRESS"], "cert_id": "CERTID", "verification_method": "HTTP_CSR_HASH"}

How do you think this should be fixed?

Setting the Storage on the issuer solves the issue. I would expect the magic.Storage which is set globally to be used, like the ACME issuers.

Please link to any related issues, pull requests, and/or discussion

#279

@mbardelmeijer mbardelmeijer changed the title Panic on ZeroSSL API when no Storage is set Panic on ZeroSSL API Issuer when no Storage is set May 24, 2024
@mbardelmeijer
Copy link
Contributor Author

From what I can see debugging further, the ACME issuer's are created with certmagic.NewACMEIssuer, which forward some parameters to the underlying issuer. For ZeroSSL there isn't such method from what I can see.

What's recommend, setting the Storage itself, or would a certmagic.NewZeroSSLIssuer helper method be preferred?

@mholt
Copy link
Member

mholt commented May 24, 2024

Ohh good find. Set the storage. I'll update things when I'm back at my desk. The package doesn't have a default ZeroSSL issuer like it does ACME issuer since you'll always need to provide an API key, but that kind of thing isn't required to use ACME. So setting a default storage for ZeroSSL may not make sense.

And I hate constructor functions when we can avoid them 😅

@mholt mholt closed this as completed in bd400cc May 29, 2024
@mholt
Copy link
Member

mholt commented May 29, 2024

For now, I just made the Storage field required (and documented it as such) since it's simpler to store the verification info in storage whether distributed or not. In the future if I have more time (or a sponsor needs it), I can work on an implementation that doesn't require a Storage value.

Thanks for the issue!

@mholt mholt added the bug Something isn't working label May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants