caddy: Caddy produces account rate limit errors when compiled with latest certmagic package

1. What version of Caddy are you using (caddy -version)?

Working build: Caddy 0.11.1 (+0684cf8 Wed Dec 19 15:48:39 UTC 2018) (unofficial) Broken build: Caddy 0.11.1 (+0b83014 Thu Dec 20 10:24:39 UTC 2018) (unofficial)

2. What are you trying to do?

I’m trying to run a build of Caddy that has been compiled against the latest commit.

3. What is your entire Caddyfile?

(headers) {

   header / {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-XSS-Protection "1; mode=block"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "sameorigin"
        Referrer-Policy "same-origin"
        Expect-CT "max-age=86400, enforce, report-uri=\"<redacted>""
        Feature-Policy "geolocation 'none'; camera 'none'; microphone 'none'"
        Content-Security-Policy "
          default-src 'none' ;
          script-src 'self' ;
          style-src 'self' ;
          img-src * ;
          font-src 'self' data: ; 
          connect-src 'self' data: ; 
          media-src 'self' data: ; 
          object-src 'none' ; 
          worker-src 'self' ; 
          manifest-src 'self' ; 
          frame-ancestors 'self' ; 
          form-action 'self' ; 
          upgrade-insecure-requests ; 
          block-all-mixed-content ; 
          report-uri <redacted>;"
        -Server
    }
}

(ecc-tls-wildcard) {

   tls {
       protocols tls1.2 tls1.3
       dns gandiv5
	   ciphers ECDHE-ECDSA-AES128-GCM-SHA256 TLS13-AES-128-GCM-SHA256 ECDHE-ECDSA-WITH-CHACHA20-POLY1305 TLS13-CHACHA20-POLY1305-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 TLS13-AES-256-GCM-SHA384
	   key_type	p384
	   must_staple
	   wildcard
    }
}

(whitelist) {

   ipfilter / {
	   rule allow
	   ip <redacted>
    }
}

redacted.domain.tld {

   proxy / <redacted> {
       transparent
       websocket
    }

   import headers
   import ecc-tls-wildcard
   import whitelist
}

4. How did you run Caddy (give the full command and describe the execution environment)?

I’m running Caddy on Debian 9.6 with this command:

caddy -agree -http2 -log /opt/caddy/log -root /opt/caddy/webroot -conf /opt/caddy/Caddyfile

5. Please paste any relevant HTTP request(s) here.

N/A

6. What did you expect to see?

I expect Caddy to either:

a.) use the existing account in my .caddy folder to fetch certificates or b.) successfully register a new account in case none exist in the .caddy folder.

7. What did you see instead (give full error messages and/or log)?

Caddy ignores any existing accounts in the .caddy folder and will always try to register a new account. When trying to register a new account, Caddy produces a rate limit error despite it being the the first registration attempt within 24 hours (i.e., it’s not actually hitting LetsEncrypt’s “10 registrations per 3 hours” rate limit).

Here’s the output from the log file:

Activating privacy features...

Your sites will be served over HTTPS automatically using Let's Encrypt.
By continuing, you agree to the Let's Encrypt Subscriber Agreement at:
  https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
Please enter your email address to signify agreement and to be notified
in case of issues. You can leave it blank, but we don't recommend it.
  Email address:
2018/12/20 11:36:53 registration error: acme: error: 429 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-acct :: urn:ietf:params:acme:error:rateLimited :: Error creating new account :: too many registrations for this IP: see https://letsencrypt.org/docs/rate-limits/, url:

Note: This problem does not occur when you use a build of Caddy that has been compiled against the second latest commit. That build of Caddy can both use existing accounts in the .caddy folder as well as register a new account in case none are present in the .caddy folder.

8. How can someone who is starting from scratch reproduce the bug as minimally as possible?

  1. Install Go.
  2. Compile Caddy against the master branch with the following command:
go get github.com/mholt/caddy/caddy && \
go get github.com/caddyserver/builds && \
cd $GOPATH/src/github.com/mholt/caddy/caddy && \
go run build.go
  1. Run Caddy with the following command:
caddy -agree -http2 -log /opt/caddy/log -root /opt/caddy/webroot -conf /opt/caddy/Caddyfile

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 32 (17 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks for that PR, @crvv. After spending more time investigating, I can confirm you are right. Merged it in, and will update Caddy soon.

There are three bugs around this issue.

  1. In caddy 0.11.1 https://github.com/mholt/caddy/blob/v0.11.1/caddytls/config.go#L207 ObtainCert will check if the certificate already exists. But in caddy 0.11.2, it doesn’t check. https://github.com/mholt/caddy/blob/v0.11.2/vendor/github.com/mholt/certmagic/config.go#L272

  2. ObtainCert calls preObtainOrRenewChecks https://github.com/mholt/caddy/blob/v0.11.2/vendor/github.com/mholt/certmagic/config.go#L352 And calls getEmail https://github.com/mholt/caddy/blob/v0.11.2/vendor/github.com/mholt/certmagic/user.go#L82. If the email is “”, it will create a new user https://github.com/mholt/caddy/blob/v0.11.2/vendor/github.com/mholt/certmagic/user.go#L101 and save it to disk. The previous user is overrided. https://github.com/mholt/caddy/blob/v0.11.2/vendor/github.com/mholt/certmagic/user.go#L141 Then newACMEClient in ObtainCert will read the file again, get a empty user, and register a new Let’s Encrypt account.

  3. email in Caddyfile doesn’t work, which is fixed by #2432

2 only occurs if the email is empty, so #2432 will get rid of the bug if there is an email in Caddyfile.