Failure to finalize certificate renewal

My domain is: blogs.eleves.ens.fr

I ran this command: dehydrated -c

It produced this output:

# INFO: Using main config file /etc/dehydrated/config
# INFO: Running /usr/bin/dehydrated as dehydrated/dehydrated-certs
# INFO: Using main config file /etc/dehydrated/config
Processing blogs.eleves.ens.fr
  + Checking domain name(s) of existing cert... unchanged.
  + Checking expire date of existing cert...
  + Valid till Oct  8 12:22:12 2024 GMT (Less than 30 days). Renewing!
  + Signing domains...
  + Generating private key...
  + Generating signing request...
  + Requesting new certificate order from CA...
  + Received 1 authorizations URLs from the CA
  + Handling authorization for blogs.eleves.ens.fr
  + Found valid authorization for blogs.eleves.ens.fr
  + 0 pending challenge(s)
  + Requesting certificate...
ERROR: Problem connecting to server (post for https://acme-v02.api.letsencrypt.org/acme/finalize/86339695/305369762606; curl returned with 56)
EXPECTED value GOT EOF

For more info, when running curl in -vv mode, the last message before failure is:

> POST /acme/finalize/86339695/307363191626 HTTP/1.1
> Host: acme-v02.api.letsencrypt.org
> User-Agent: dehydrated/0.7.0 curl/7.74.0
> Accept: */*
> Content-Type: application/jose+json
> Content-Length: 1642
> 
} [1642 bytes data]
* upload completely sent off: 1642 out of 1642 bytes
* OpenSSL SSL_read: Connection reset by peer, errno 104
* Closing connection 0
} [5 bytes data]
ERROR: Problem connecting to server (post for https://acme-v02.api.letsencrypt.org/acme/finalize/86339695/307363191626; curl returned with 56)
EXPECTED value GOT EOF

My web server is (include version): Apache/2.4.62 (Debian) mod_fcgid/2.3.9 OpenSSL/1.1.1w mod_wsgi/4.7.1 Python/3.9

The operating system my web server runs on is (include version): Debian GNU/Linux 11 (bullseye)

I can login to a root shell on my machine (yes or no, or I don't know): yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): Dehydrated version: 0.7.0

Welcome @Tom-Hubrecht

That is very unusual. For one there should be other requests to that LE endpoint before doing a finalize. So, any error causing the EOF should have occurred earlier.

Let's start by you showing output of this

curl -v https://acme-v02.api.letsencrypt.org/directory
4 Likes

Yeah, the previous requests to LE work fine, this command gives me:

root@blogs:~# curl -v https://acme-v02.api.letsencrypt.org/directory
*   Trying 172.65.32.248:443...
* Connected to acme-v02.api.letsencrypt.org (172.65.32.248) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=acme-v02.api.letsencrypt.org
*  start date: Sep  4 14:46:39 2024 GMT
*  expire date: Dec  3 14:46:38 2024 GMT
*  subjectAltName: host "acme-v02.api.letsencrypt.org" matched cert's "acme-v02.api.letsencrypt.org"
*  issuer: C=US; O=Let's Encrypt; CN=R10
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5630e28821b0)
> GET /directory HTTP/2
> Host: acme-v02.api.letsencrypt.org
> user-agent: curl/7.74.0
> accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200 
< server: nginx
< date: Wed, 25 Sep 2024 14:08:07 GMT
< content-type: application/json
< content-length: 746
< cache-control: public, max-age=0, no-cache
< x-frame-options: DENY
< strict-transport-security: max-age=604800
< 
{
  "CfTa1tGx1Ls": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417",
  "keyChange": "https://acme-v02.api.letsencrypt.org/acme/key-change",
  "meta": {
    "caaIdentities": [
      "letsencrypt.org"
    ],
    "termsOfService": "https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf",
    "website": "https://letsencrypt.org"
  },
  "newAccount": "https://acme-v02.api.letsencrypt.org/acme/new-acct",
  "newNonce": "https://acme-v02.api.letsencrypt.org/acme/new-nonce",
  "newOrder": "https://acme-v02.api.letsencrypt.org/acme/new-order",
  "renewalInfo": "https://acme-v02.api.letsencrypt.org/draft-ietf-acme-ari-03/renewalInfo",
  "revokeCert": "https://acme-v02.api.letsencrypt.org/acme/revoke-cert"
* Connection #0 to host acme-v02.api.letsencrypt.org left intact

As you can see on the full log for my dehydrated run ( PrivateBin ), it only fails at the end, which is very strange

And you get the problem consistently at that step? It seems like some firewall/router/etc. just chose that point to drop the connection, which does seem odd if the other ones work.

The finalize endpoint does have a larger request size than other requests, I think, since it includes the full CSR with your public key. So maybe there's one of those wonky MTU issues where requests over a certain size are failing? Is your server's internet connectivity through any kind of tunnel, or anything out of the "ordinary"?

And while I don't think it's related, you may want to upgrade your version of dehydrated. I vaguely remember some issues with old versions doing weird things when getting responses that the server wasn't expecting (I think back when Let's Encrypt was testing async order finalization). But again, I don't think that's part of the problem you're having.

5 Likes

And you get the problem consistently at that step?
Yes, it always fail at the same point.

I should not be behind a tunnel, but there is a firewall on the way out...
I will investigate this avenue.

2 Likes

If all else fails, you could try:

  • using another free CA
  • using another authentication method [like: DNS]
3 Likes

Totally Agree!
https://letsdebug.net/blogs.eleves.ens.fr/2235372
Option 2 !!!

2 Likes

But the issue looks to be with the finalize call, which would be after the challenges are done. Trying out the DNS challenge might be interesting just to see if something different happens, but I wouldn't expect it to solve this specific problem. (Though it wouldn't be the first time technology surprised me. :wink:)

4 Likes

I do not manage the DNS for this domain, so I can't use the DNS-01 challenge...

The other workaround that @rg305 suggested of trying another CA may be useful too. Try using --ca buypass or --ca zerossl and see if they work any differently. If they work, that might be all you need even though there's the weird mystery of what's happening to your connections to Let's Encrypt's servers. If they fail at the same (or a different) place, then that might help with digging into what network apparatus is breaking it.

5 Likes

Okay, now the error is more clear, from buypass I get :
Curve is not of type secp256r1 or prime256v1 during the finalize call, I guess it is the same issue with Let's Encrypt, but it does not bother to tell why it failed

Guess it wasn't the same issue, as changing the algo to prime256v1 didn't make it work with LE, bit it did finally work with buypass. To Be Continued I guess ? But thanks everyone for your help !

2 Likes

Your previous Let's Encrypt certs were P-384, but it looks like BuyPass only supports P-256 when doing ECDSA. You could try P-256 with Let's Encrypt as well, maybe the slightly smaller public key request would make something work differently there too? *shrug*

3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.