JWS has no anti-replay nonce

I’m getting error when I try to register and accept terms. I’ve already check that I’m using just one IP address. I’m using version 0.6.5

Using main config file /shared/dehydrated/config

declare – CA=“https://acme-staging.api.letsencrypt.org/directory
declare – CERTDIR="/shared/dehydrated/certs"
declare – ALPNCERTDIR="/shared/dehydrated/alpn-certs"
declare – CHALLENGETYPE=“http-01”
declare – DOMAINS_D=""
declare – DOMAINS_TXT="/shared/dehydrated/domains.txt"
declare – HOOK="/shared/dehydrated/hook.sh"
declare – HOOK_CHAIN=“no”
declare – RENEW_DAYS=“30”
declare – KEYSIZE=“2048”
declare – WELLKNOWN="/shared/dehydrated"
declare – PRIVATE_KEY_RENEW=“yes”
declare – OPENSSL_CNF="/etc/pki/tls/openssl.cnf"
declare – CONTACT_EMAIL=""
declare – LOCKFILE="/shared/dehydrated/lock"

VERSION
Dehydrated by Lukas Schauer
https://dehydrated.io

Dehydrated version: 0.6.5
GIT-Revision: unknown

OS: BIG-IP 14.1.0.3 Build 0.0.6
Used software:
bash: 4.2.46(2)-release
curl: curl 7.47.1
awk: GNU Awk 4.0.2
sed: sed (GNU sed) 4.2.2
mktemp: mktemp (GNU coreutils) 8.22
grep: grep (GNU grep) 2.20
diff: diff (GNU diffutils) 3.3
openssl: OpenSSL 1.0.2p-fips 14 Aug 2018

./dehydrated --register --accept-terms

Details:
HTTP/2.0 400
server:nginx
date:Wed, 02 Oct 2019 21:15:32 GMT
content-type:application/problem+json
content-length:100
cache-control:public, max-age=0, no-cache
replay-nonce:0002_xoIBQHkeneUKKhLjCGvLu2pNl-Me7aP-dTwuVkTtBU

{
“type”: “urn:acme:error:badNonce”,
“detail”: “JWS has no anti-replay nonce”,
“status”: 400
}

Error registering account key. See message above for more information.

Account registrations are completely disabled on acme-staging.api.letsencrypt.org - though that does not explain the nonce error whatsoever.

What happens if you update to:

CA=https://acme-staging-v02.api.letsencrypt.org/directory

Can you also take the sha256sum of the dehydrated script? I’m surprised to see this in 0.6.5 …

1 Like

Hello Az! Thank you for your attention!

We get the same error:

Details:
HTTP/2.0 400
server:nginx
date:Thu, 03 Oct 2019 13:00:21 GMT
content-type:application/problem+json
content-length:112
cache-control:public, max-age=0, no-cache
link:https://acme-staging-v02.api.letsencrypt.org/directory;rel=“index”
replay-nonce:0001IFhLT1nTS2VScBoScffkJaVl81zs3XwVdXEchGF_5MI

{
“type”: “urn:ietf:params:acme:error:badNonce”,
“detail”: “JWS has no anti-replay nonce”,
“status”: 400
}

Error registering account key. See message above for more information.

sha256sum ab5e8fb9acae9f938c6bba7becb7361d8927a975d17d357ae733106ac79d6105 dehydrated

I wonder if Dehydrated is falling into the same trap a few of the other shell based ACME clients (getssl, acme.sh, etc) hit since the CDN switch: case sensitive HTTP header matching that fails with H2’s all-lowercase headers.

From an external perspective just based on the error messages it seems like behaviour that could happen if the code pulling the replay nonce from the HTTP response header from the ACME server didn’t fail when it couldn’t extract a nonce to use.

1 Like

The HTTP/2 header case sensitivity was fixed in 0.6.3, which is what surprised me.

1 Like

Doing some testing, with dehydrated 0.6.3, I get the following on a cert that needs renewal:

 + Requesting new certificate order from CA...
 + ERROR: An error occurred while sending post-request to https://acme-v02.api.letsencrypt.org/acme/new-order (Status 400)

Details:
HTTP/2.0 400
server:nginx
date:Tue, 08 Oct 2019 12:13:22 GMT
content-type:application/problem+json
content-length:112
boulder-requester:34257164
cache-control:public, max-age=0, no-cache
link:<https://acme-v02.api.letsencrypt.org/directory>;rel="index"
replay-nonce:0001 [   ] V99NYWw

{
  "type": "urn:ietf:params:acme:error:badNonce",
  "detail": "JWS has no anti-replay nonce",
  "status": 400
}

Then in 0.6.4 and 0.6.5 I get:

+ Fetching account ID...
  + ERROR: An error occurred while sending post-request to https://acme-v02.api.letsencrypt.org/acme/new-acct (Status 400)

Details:
HTTP/2.0 400
server:nginx
date:Tue, 08 Oct 2019 12:16:36 GMT
content-type:application/problem+json
content-length:112
cache-control:public, max-age=0, no-cache
link:<https://acme-v02.api.letsencrypt.org/directory>;rel="index"
replay-nonce:0002 [...] RLKbE0UKE

{
  "type": "urn:ietf:params:acme:error:badNonce",
  "detail": "JWS has no anti-replay nonce",
  "status": 400
}

The version of cURL:

curl 7.47.1 (x86_64-redhat-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2p zlib/1.2.7 libidn/1.28 libssh2/1.4.3 nghttp2/1.31.1

I added an extra configuration file with the following contents:

CURL_OPTS="--http1.1"

No longer seem to get the “JWS has no anti-replay nonce” error.

1 Like

I’m seeing the “JW has no anti-replay nonce” error since yesterday on a system with dehydrated 0.6.5 and curl 7.47.0 that doesn’t even have HTTP2 support.

not experiencing problems on the staging server though.

Created:

@ joe_h_punkt, what is the full version output of your cURL?

$ curl --version
curl 7.47.1 (x86_64-redhat-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2p zlib/1.2.7 libidn/1.28 libssh2/1.4.3 nghttp2/1.31.1
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp     smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets

Also it failed producing a SAN certificate with 99 hosts (as my production cert that failed first had 88 hosts in it) but succeeds with only 20 FQDN in it.

Worked like a charm!!! Thank you so much!

My curl version:

curl 7.47.1 (x86_64-redhat-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2p zlib/1.2.7 libidn/1.28 libssh2/1.4.3 nghttp2/1.31.1
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets

This is a bandaide though (IMHO).

What in the code “broke” with the switch from HTTP/1.1 to HTTP/2. I would think/hope that the tranposrt layer would have no effect over the application layer data.

Doesn’t seem to help joe_h_punkt either.

here is where it actually goes wrong: when connecting to /acme/new-nonce the TLS handshake failes and the client (dehydrated) goes on trying with an empty nonce. guess it’s still a bug within boulder or the CDN or should the client retry fetching the nonce in these cases?

https://pastebin.com/2VWLpgth

edit: also guessing the other trending issues in this forum are actually the same error with the boulder/the CDN not handing out nonces and clients that aren’t equipped with dealing with that.

There’s no Boulder bug related to this. It sounds like it’s the same problem with the CDN edge that is being investigated in other threads (e.g. https://community.letsencrypt.org/t/curl-tcp-connection-reset-by-peer/ )

Yes, definitely.  

thanks for the feedback. if Lukas Schauer doesn’t have time maybe i’ll give it a try.

FYI, it TLS handshakes fail not only at the nonce-retrieving stage (which I guess would be even stranger) but also earlier in the process (although not that often for me).
https://pastebin.com/GvpS89MY
this happened while sending the signed request.

1 Like

so the issue with the empty nonce is actually a small logic bug in dehydrated that has just been fixed in master (see ticket https://github.com/lukas2511/dehydrated/issues/684)

here is a quickfix that implements retry when connecting to the CDN failes
https://pastebin.com/igFHAp6D

Just to be clear: The underlying issue hasn’t been completely fixed yet. This error occurs due to connection issues with the CA and there currently is no retry-logic in dehydrated. The only thing the last commit fixed should be the type of the error message, instead of failing with “no nonce” dehydrated should (at least in theory…) now notice the broken HEAD request and fail early with a correct error message, but I think there is another issue which again prevents this from working correctly. I’ll have to do some work on it, until then you can always just rerun the script, at least with ACME it at least kinda keeps the state and doesn’t have to rerun everything again.

1 Like

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