Code Monkey home page Code Monkey logo

acmez's People

Contributors

commonism avatar dtchanpura avatar grahamedgecombe avatar hslatman avatar mailbaoer avatar maraino avatar mholt avatar n0cloud avatar orangepizza avatar teleclimber avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

acmez's Issues

Enable http keep-alive

I am currently trying to use caddy with a corporate acme endpoint that is behind an AWS ELB.

Due to the round-robin nature of the ELB, I am unable to do a full http challenge going to the same backend server.

We need either https keep-alive or cookie support to allow caddy to connect to the same server at each stage of the request.

possible issue with wildcard DCV record

Hello! I apologize if this is not the correct repo impacted here. I have an issue that I believe is related to this library:

I have an inhouse-developed batch processing app that allows us to standardize processing of potentially large batches of public certificates.

I noticed in my last few batches that there is an issue when certificates such as the below are BOTH specified in the same batch. The issue is related to the DCV challenge record, I believe.

For example - both requested in sequence one after the other:
*.example.eu.domain.app
example.eu.domain.app

From my perspective, there are potentially 4 different libraries that could be involved: acmez, certmagic, libdns/route53 or the code I've added for the batch processing.

Could you please briefly review this log output I captured and see if you may have an "Aha!" moment? If not... I'm happy to dig deeper on my code assembly and see if I can narrow down the issue. Also I'm currently using an older version of libdns/route53 due to a possible issue with the latest version.

(As a sidenote: I use multiple libdns providers but it seems I occasionally run into a variance with the provider outputs. I've thought about writing a way to validate these outputs. Ideally all providers should accept the same inputs and produce identical-format outputs. A tool could help certify the providers as equivalent.)

2023/08/30 11:56:21 ca.go:236: Issue certificate #5/7 from Digicert: *.example.eu.domain.app [route53]
1.693418181555955e+09	info	obtain	acquiring lock	{"identifier": "*.example.eu.domain.app"}
1.6934181815623481e+09	info	obtain	lock acquired	{"identifier": "*.example.eu.domain.app"}
1.6934181815624409e+09	info	obtain	obtaining certificate	{"identifier": "*.example.eu.domain.app"}
1.693418181639694e+09	info	waiting on internal rate limiter	{"identifiers": ["*.example.eu.domain.app"], "ca": "https://acme.digicert.com/v2/acme/directory/", "account": "[email protected]"}
1.693418181639717e+09	info	done waiting on internal rate limiter	{"identifiers": ["*.example.eu.domain.app"], "ca": "https://acme.digicert.com/v2/acme/directory/", "account": "[email protected]"}
1.69341818190844e+09	info	acme_client	trying to solve challenge	{"identifier": "*.example.eu.domain.app", "challenge_type": "dns-01", "ca": "https://acme.digicert.com/v2/acme/directory/"}
1.693418194070356e+09	error	acme_client	cleaning up solver	{"identifier": "*.example.eu.domain.app", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for \"_acme-challenge.example.eu.domain.app\" (usually OK if presenting also failed)"}
1.6934181940704799e+09	info	acme_client	authorization finalized	{"identifier": "*.example.eu.domain.app", "authz_status": "valid"}
1.6934181940705001e+09	info	acme_client	validations succeeded; finalizing order	{"order": "https://acme.digicert.com/v2/acme/order/__redacted__/LxJadUh43yM1kfS9fUA3UQixZbc-dfbWNCOFxlDlOn0"}
1.693418229275489e+09	info	acme_client	successfully downloaded available certificate chains	{"count": 1, "first_url": "https://acme.digicert.com/v2/acme/cert/__redacted__/12CAC69ADA26CE504BA8C09F7F60AA523E434265"}
1.6934182292897239e+09	info	obtain	certificate obtained successfully	{"identifier": "*.example.eu.domain.app"}
1.693418229289839e+09	info	obtain	releasing lock	{"identifier": "*.example.eu.domain.app"}
1.693418229464159e+09	warn	stapling OCSP	{"error": "no OCSP stapling for [*.example.eu.domain.app]: parsing OCSP response: ocsp: error from server: unauthorized", "identifiers": ["*.example.eu.domain.app"]}

2023/08/30 11:57:09 ca.go:236: Issue certificate #6/7 from Digicert: example.eu.domain.app [route53]
1.693418229483319e+09	info	obtain	acquiring lock	{"identifier": "example.eu.domain.app"}
1.693418229489676e+09	info	obtain	lock acquired	{"identifier": "example.eu.domain.app"}
1.693418229489938e+09	info	obtain	obtaining certificate	{"identifier": "example.eu.domain.app"}
1.693418229590105e+09	info	waiting on internal rate limiter	{"identifiers": ["example.eu.domain.app"], "ca": "https://acme.digicert.com/v2/acme/directory/", "account": "[email protected]"}
1.693418229590131e+09	info	done waiting on internal rate limiter	{"identifiers": ["example.eu.domain.app"], "ca": "https://acme.digicert.com/v2/acme/directory/", "account": "[email protected]"}
1.693418229828408e+09	info	acme_client	trying to solve challenge	{"identifier": "example.eu.domain.app", "challenge_type": "dns-01", "ca": "https://acme.digicert.com/v2/acme/directory/"}
1.693418230415124e+09	error	acme_client	cleaning up solver	{"identifier": "example.eu.domain.app", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for \"_acme-challenge.example.eu.domain.app\" (usually OK if presenting also failed)"}
1.6934182304475899e+09	error	acme_client	deactivating authorization	{"identifier": "example.eu.domain.app", "authz": "https://acme.digicert.com/v2/acme/authz/__redacted__/R1sy_q1Yqiee_-vI", "error": "attempt 1: https://acme.digicert.com/v2/acme/authz/__redacted__/R1sy_q1Yqiee_-vI: HTTP 400 urn:ietf:params:acme:error:malformed - payload field of the JWS object must be the empty string"}
1.693418230447774e+09	error	obtain	could not get certificate from issuer	{"identifier": "example.eu.domain.app", "issuer": "acme.digicert.com-v2-acme-directory", "error": "[example.eu.domain.app] solving challenges: presenting for challenge: adding temporary record for zone \"eu.example.app.\": InvalidChangeBatch: operation error Route 53: ChangeResourceRecordSets, https response error StatusCode: 400, RequestID: bf7444c3-887f-40ea-b785-71f239086bb6, InvalidChangeBatch: [Tried to create resource record set [name='_acme-challenge.example.eu.domain.app.', type='TXT'] but it already exists] (order=https://acme.digicert.com/v2/acme/order/__redacted__/EpJ5lOMdCripOFtpT4rhyc8SbxJq7fALZMMbcLSQ8sc) (ca=https://acme.digicert.com/v2/acme/directory/)"}
1.693418230447844e+09	info	obtain	releasing lock	{"identifier": "example.eu.domain.app"}
2023/08/30 11:57:10 logic.go:82: example.eu.domain.app: obtaining certificate: [example.eu.domain.app] Obtain: [example.eu.domain.app] solving challenges: presenting for challenge: adding temporary record for zone "eu.example.app.": InvalidChangeBatch: operation error Route 53: ChangeResourceRecordSets, https response error StatusCode: 400, RequestID: bf7444c3-887f-40ea-b785-71f239086bb6, InvalidChangeBatch: [Tried to create resource record set [name='_acme-challenge.example.eu.domain.app.', type='TXT'] but it already exists] (order=https://acme.digicert.com/v2/acme/order/__redacted__/EpJ5lOMdCripOFtpT4rhyc8SbxJq7fALZMMbcLSQ8sc) (ca=https://acme.digicert.com/v2/acme/directory/)

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

If

  • only one solver is defined (e.g. dns-01)
  • ObtainCertificate is called with multiple SAN's (e.g. "a.example.com", "b.example.com", "c.example.com", "d.example.com")
  • validation of one of the "not-first" SAN fails on the ACME server (not in the client) (e.g. c.example.com),

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:

[email protected]/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"}
[email protected]/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"}
[email protected]/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"}
[email protected]/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"}
[email protected]/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"}
[email protected]/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"}
[email protected]/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"}
[email protected]/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"}
[email protected]/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/[email protected]/client.go:512
github.com/mholt/acmez.(*Client).solveChallenges
        /home/simon/go/pkg/mod/github.com/mholt/[email protected]/client.go:368
github.com/mholt/acmez.(*Client).ObtainCertificateUsingCSR
        /home/simon/go/pkg/mod/github.com/mholt/[email protected]/client.go:127
github.com/mholt/acmez.(*Client).ObtainCertificate
        /home/simon/go/pkg/mod/github.com/mholt/[email protected]/client.go:235
...
daemon/main.go:90       cleanup {"id": "d.example.com", "record": "_acme-challenge.d.example.com", "value": "g3NU4vF2SSNEWWaYHcJ7STO6zU5eQB02drvadyc75UQ"}
[email protected]/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/[email protected]/client.go:143
github.com/mholt/acmez.(*Client).ObtainCertificate
        /home/simon/go/pkg/mod/github.com/mholt/[email protected]/client.go:235
...
[email protected]/client.go:461      no solver configured    {"challenge_type": "tls-alpn-01"}
[email protected]/client.go:461      no solver configured    {"challenge_type": "http-01"}
[email protected]/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"}
[email protected]/client.go:461      no solver configured    {"challenge_type": "tls-alpn-01"}
[email protected]/client.go:461      no solver configured    {"challenge_type": "http-01"}
[email protected]/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"}
[email protected]/client.go:461      no solver configured    {"challenge_type": "tls-alpn-01"}
[email protected]/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.

Support for new crypto/ecdh?

I'm trying to update my API that uses acmez to use crypto/ecdh instead of crypto/elliptic. See this issue for more information about the rationale for deprecating crypto/elliptic. And this comment:

// Direct use of this package is deprecated, beyond the P224(), P256(), P384(),
// and P521() values necessary to use the crypto/ecdsa package. Most other uses
// should migrate to the more efficient and safer crypto/ecdh package.

The problem is: it doesn't implement signer so I can't use it for my PrivateKey in my acme.Account struct:

accountPrivateKey, err := ecdh.P256().GenerateKey(rand.Reader)
if err != nil {
	return resp, fmt.Errorf("generating account key: %v", err)
}
// Doesn't work because accountPrivateKey doesn't implement Signer
account := acme.Account{
	Contact:              []string{req.AccountContactEmailUrl},
	TermsOfServiceAgreed: true,
	PrivateKey:           accountPrivateKey,
}

Do you have any suggestions for this? Should I type alias it and implement Signer or something along those lines?

同学,您这个项目引入了29个开源组件,存在2个漏洞,辛苦升级一下

检测到 mholt/acmez 一共引入了29个开源组件,存在2个漏洞

漏洞标题:go-yaml < 2.2.8拒绝服务漏洞
漏洞编号:CVE-2019-11254
漏洞描述:gopkg.in/yaml.v2是go语言中用于处理yaml格式的包。
在2.2.8之前的版本中,处理恶意的yaml数据时,会导致CPU资源耗尽。
漏洞由Kubernetes开发者在fuzz测试中发现并提交修复补丁。
国家漏洞库信息:https://www.cnvd.org.cn/flaw/show/CNVD-2020-35519
影响范围:(∞, 2.2.8)
最小修复版本:2.2.8
缺陷组件引入路径:github.com/mholt/acmez@->go.uber.org/[email protected]>github.com/stretchr/[email protected]>gopkg.in/[email protected]

另外还有2个漏洞,详细报告:https://mofeisec.com/jr?p=n6cb08

Valid Retry-after Headers are rejected and cause error

I have been experimenting with certmagic and a let's encrypt Pebble server and have gottne things to work overall but there I had been getting this error:

Nov 30 09:58:26 dsdev ds-host[1363]: 1.6698311064858541e+09        error        obtain        could not get certificate from issuer        {"identifier": "sub.domain.develop", "issuer": "127.0.0.1:14000-dir", "error": "[sub.domain.develop] finalizing order https://127.0.0.1:14000/my-order/WkaEgtUJEiIT4hysbU7u5WbAHQiH9wJh8afKlt_iAEU: response had invalid Retry-After header: Wed, 30 Nov 2022 17:58:31 GMT (ca=https://127.0.0.1:14000/dir)"}

After some digging I found that Pebble recently added some Retry-After headers: letsencrypt/pebble@6538ad0

It turns out that it flips a coin and sends the header either as seconds or as a full date time. This is per-spec: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After

Looking at where the error is thrown shows the problem: acmez expects only seconds and doesn't handle the full date-time case:

acmez/acme/http.go

Lines 376 to 383 in d79cc20

raSeconds := resp.Header.Get("Retry-After")
if raSeconds == "" {
return fallback, nil
}
ra, err := strconv.Atoi(raSeconds)
if err != nil || ra < 0 {
return 0, fmt.Errorf("response had invalid Retry-After header: %s", raSeconds)
}

I'm working on a PR.

ACME 'invalid signature on JWS request'

What version of the package are you using?

acmez v1.1.0 (bundled via certmagic v0.17.2)

What are you trying to do?

We're trying to obtain an SSL certificate on demand with certmagic via the ZeroSSL ACME issuer.

What steps did you take?

We've installed certmagic as documented and are running successfully for thousands of domains. A small percentage of our SSL requests trigger the error Obtain: [XXXX.com] creating new order: attempt 1: https://acme.zerossl.com/v2/DV90/newOrder: HTTP 400 urn:ietf:params:acme:error:malformed - Invalid signature on JWS request

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

We expect that the SSL certificate would be issued.

How do you think this should be fixed?

I'm unsure what the best fix be. It might be a race condition, having multiple orders per domain.

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

We use the S3 storage adapter for certmagic which does support locks via placing files in the bucket but isn't atomic.

Log output

{"level":"error","ts":1680599702.936518,"logger":"obtain","caller":"[email protected]/async.go:117","msg":"will retry","component":"acme","error":"[XXXX.com] Obtain: [XXXX.com] creating new order: attempt 1: https://acme.zerossl.com/v2/DV90/newOrder: HTTP 400 urn:ietf:params:acme:error:malformed - Invalid signature on
JWS request (ca=https://acme.zerossl.com/v2/DV90)","attempt":2,"retrying_in":120,"elapsed":66.086730116,"max_duration":2592000,"stacktrace":"github.com/caddyserver/certmagic.doWithRetry\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/async.go:117\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/config.go:611\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/config.go:462\ngithub.com/caddyserver/certmagic.(*Config).obtainOnDemandCertificate\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:447\ngithub.com/caddyserver/certmagic.(*Config).getCertDuringHandshake\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:314\ngithub.com/caddyserver/certmagic.(*Config).GetCertificate\n\t/go/pkg/mod/github.com/caddyserver/[email protected]/handshake.go:77\ncrypto/tls.(*Config).getCertificate\n\t/usr/local/go/src/crypto/tls/common.go:1079\ncrypto/tls.(*serverHandshakeState).processClientHello\n\t/usr/local/go/src/crypto/tls/handshake_server.go:229\ncrypto/tls.(*serverHandshakeState).handshake\n\t/usr/local/go/src/crypto/tls/handshake_server.go:67\ncrypto/tls.(*Conn).serverHandshake\n\t/usr/local/go/src/crypto/tls/handshake_server.go:61\ncrypto/tls.(*Conn).handshakeContext\n\t/usr/local/go/src/crypto/tls/conn.go:1491\ncrypto/tls.(*Conn).HandshakeContext\n\t/usr/local/go/src/crypto/tls/conn.go:1434\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:1877"}

Enable http cookie jar

I am currently trying to use caddy with a corporate acme endpoint that is behind an AWS ELB.

Due to the round-robin nature of the ELB, I am unable to do a full http challenge going to the same backend server.

I hope we can add a cookie jar to the acme client, so that ELB sticky cookies can route the request back to the same backend server.

When I try to request *.example.com and example.com, it will pending

        client := acmez.Client{
		Client: &acme.Client{
			Directory: constants.DefaultCA,
		},
		ChallengeSolvers: map[string]acmez.Solver{
			acme.ChallengeTypeDNS01: &acme_issuer.DNS01Solver{
				PropagationTimeout: time.Minute * 15,
				PollingInterval:    time.Second * 10,
				TTL:                constants.DefaultDnsRecordTTL,
				DNSProvider:        dnsProvider,
			},
		},
	}
        domains:=[]string{"*.example.com","example.com"}
	log.Println("-----")
	log.Printf("%+v\n", domains)
        certs, err := client.ObtainCertificate(context.Background(), account.AcmeAccount, certPrivateKey, domains)
	if err != nil {
		log.Println(err)
		return nil, fmt.Errorf("obtaining certificate: %v", err)
	}
	log.Println("====")

it use one dns provider, cloudflare.

when i try one domain, it's works fine
domains:=[]string{"*.example.com"} or domains:=[]string{"example.com"}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.