Skip to content

Decouple cleanup context from obtaining context #313

@aplr

Description

@aplr

What version of the package are you using?

v0.21.4

What are you trying to do?

Cleaning up after a failed obtain attempt

What steps did you take?

Configured Certmagic to issue certificates on-demand

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

Obtaining an on-demand certificate runs into the configured timeout of 180s:

certmagic/handshake.go

Lines 524 to 526 in c783cbd

var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, 180*time.Second)
defer cancel()

If that happens, I expect the cleanup routines to succeed.

https://github.com/mholt/acmez/blob/527e47cae3f84fa3a92d1d9b9c21c5eb0b44359a/client.go#L316-L323

https://github.com/mholt/acmez/blob/527e47cae3f84fa3a92d1d9b9c21c5eb0b44359a/client.go#L337

However, the cleanup routines are bound to the cancelled context, and won't run as the context was cancelled.

Show error logs
{
  "insertId": "19ucu8ye3zmtq",
  "jsonPayload": {
    "msg": "cleaning up solver",
    "challenge_type": "http-01",
    "level": "error",
    "ts": 1729163825.755899,
    "identifier": "redacted.com",
    "caller": "[email protected]/client.go:544",
    "time": "2024-10-17T11:17:05.75616761Z",
    "stacktrace": "github.com/mholt/acmez/v2.(*Client).pollAuthorization\n\t/go/pkg/mod/github.com/mholt/acmez/[email protected]/client.go:544\ngithub.com/mholt/acmez/v2.(*Client).solveChallenges\n\t/go/pkg/mod/github.com/mholt/acmez/[email protected]/client.go:378\ngithub.com/mholt/acmez/v2.(*Client).ObtainCertificate\n\t/go/pkg/mod/github.com/mholt/acmez/[email protected]/client.go:136\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/acmeissuer.go:371\ngithub.com/aplr/redacted/tlsx.(*conditionalIssuer).Issue\n\t/app/tlsx/issuer.go:111\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).obtainOnDemandCertificate\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:531\ngithub.com/caddyserver/certmagic.(*Config).getCertDuringHandshake\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:369\ngithub.com/caddyserver/certmagic.(*Config).GetCertificateWithContext\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:92\ngithub.com/caddyserver/certmagic.(*Config).GetCertificate\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:49\ncrypto/tls.(*Config).getCertificate\n\t/usr/local/go/src/crypto/tls/common.go:1196\ncrypto/tls.(*serverHandshakeStateTLS13).pickCertificate\n\t/usr/local/go/src/crypto/tls/handshake_server_tls13.go:475\ncrypto/tls.(*serverHandshakeStateTLS13).handshake\n\t/usr/local/go/src/crypto/tls/handshake_server_tls13.go:61\ncrypto/tls.(*Conn).serverHandshake\n\t/usr/local/go/src/crypto/tls/handshake_server.go:54\ncrypto/tls.(*Conn).handshakeContext\n\t/usr/local/go/src/crypto/tls/conn.go:1568\ncrypto/tls.(*Conn).HandshakeContext\n\t/usr/local/go/src/crypto/tls/conn.go:1508\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:1971",
    "env": "production",
    "cos.googleapis.com/stream": "stderr",
    "error": "deleting object acme/acme.zerossl.com-v2-dv90/challenge_tokens/redacted.com.json: context deadline exceeded",
    "logger": "app.https.tls.certmagic.acme_issuer.acme_client",
  }
}
{
  "insertId": "19ucu8ye3zmts",
  "jsonPayload": {
    "env": "production",
    "stacktrace": "github.com/mholt/acmez/v2.(*Client).solveChallenges.func1\n\t/go/pkg/mod/github.com/mholt/acmez/[email protected]/client.go:340\ngithub.com/mholt/acmez/v2.(*Client).solveChallenges\n\t/go/pkg/mod/github.com/mholt/acmez/[email protected]/client.go:380\ngithub.com/mholt/acmez/v2.(*Client).ObtainCertificate\n\t/go/pkg/mod/github.com/mholt/acmez/[email protected]/client.go:136\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/acmeissuer.go:371\ngithub.com/aplr/redacted/tlsx.(*conditionalIssuer).Issue\n\t/app/tlsx/issuer.go:111\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).obtainOnDemandCertificate\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:531\ngithub.com/caddyserver/certmagic.(*Config).getCertDuringHandshake\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:369\ngithub.com/caddyserver/certmagic.(*Config).GetCertificateWithContext\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:92\ngithub.com/caddyserver/certmagic.(*Config).GetCertificate\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:49\ncrypto/tls.(*Config).getCertificate\n\t/usr/local/go/src/crypto/tls/common.go:1196\ncrypto/tls.(*serverHandshakeStateTLS13).pickCertificate\n\t/usr/local/go/src/crypto/tls/handshake_server_tls13.go:475\ncrypto/tls.(*serverHandshakeStateTLS13).handshake\n\t/usr/local/go/src/crypto/tls/handshake_server_tls13.go:61\ncrypto/tls.(*Conn).serverHandshake\n\t/usr/local/go/src/crypto/tls/handshake_server.go:54\ncrypto/tls.(*Conn).handshakeContext\n\t/usr/local/go/src/crypto/tls/conn.go:1568\ncrypto/tls.(*Conn).HandshakeContext\n\t/usr/local/go/src/crypto/tls/conn.go:1508\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:1971",
    "ts": 1729163825.757464,
    "identifier": "redacted.com",
    "caller": "[email protected]/client.go:340",
    "level": "error",
    "time": "2024-10-17T11:17:05.757641208Z",
    "cos.googleapis.com/stream": "stderr",
    "authz": "https://acme.zerossl.com/v2/DV90/authz/redacted",
    "logger": "app.https.tls.certmagic.acme_issuer.acme_client",
    "msg": "deactivating authorization",
    "error": "attempt 1: https://acme.zerossl.com/v2/DV90/authz/redacted: context deadline exceeded",
  },
}

How do you think this should be fixed?

Allow to provide a long-running context for cleanup routines, which is passed to acmez, if this makes sense.

Bonus: What do you use CertMagic for, and do you find it useful?

Creating on-demand certificates for parked domains

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions