-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Bug Overview
The client correctly fetches a nonce, then successfully creates an account and an order. On the next request to the authorization URL, the client reuses a prior nonce (identical JWS protected header as previous request), and the server responds with urn:ietf:params:acme:error:badNonce
.
Expected Behavior
The client correctly fetches a nonce, then successfully creates an account and an order. On the next request to the authorization URL, the client reuses a prior nonce (identical JWS protected header as previous request), and the server responds with urn:ietf:params:acme:error:badNonce.
Steps to Reproduce the Bug
Use nginx-acme 0.1.1 with adapted example config against Hashicorp pki vault with ACME enabled.
vhost config:
resolver 172.22.30.39;
acme_issuer example {
uri https://vault/v1/muac-pki/roles/muac-pki-configuration/acme/directory;
contact [email protected];
state_path /var/cache/nginx/acme-example;
accept_terms_of_service;
ssl_verify off;
}
acme_shared_zone zone=ngx_acme_shared:1M;
server {
listen 443 ssl;
server_name requestor.me;
acme_certificate example key=rsa:4096;
ssl_certificate $acme_certificate;
ssl_certificate_key $acme_certificate_key;
# do not parse the certificate on each request
ssl_certificate_cache max=2;
}
server {
# listener on port 80 is required to process ACME HTTP-01 challenges
listen 80;
location / {
return 404;
}
}
Environment Details
Client VM: RHEL 9.6 5.14.0-570.24.1.el9_6.x86_64
Client: nginx-acme/0.1.1 on nginx/1.29.1
ACME server: Hashicorp Vault OSS v1.16.1 (6b5986790d7748100de77f7f127119c4a0f78946)
Nginx <-> Vault direct connection, no proxying
Certbot can request certificate successfully
Additional Context
The MITM intercept (mitmproxy, transparent) details:
1) Get fresh nonce
Request
2025-09-03 10:22:36
GET https://vault/v1/muac-pki/roles/muac-pki-configuration/acme/new-nonce
Response 204 No Content
Headers:
Replay-Nonce: dmF1bHQw52bkRgQDO_iPZsGKa1tK11lb3trMp1E8SX9hrO83WtpQMcQ-zb6XMg ; (Nonce A)
Link: <https://vault/v1/muac-pki/roles/muac-pki-configuration/acme/directory>; rel="index"
2) Create account (uses Nonce A)
Request
POST https://vault/v1/muac-pki/roles/muac-pki-configuration/acme/new-account
Content-Type: application/jose+json
Body
{
"payload": "eyJjb250YWN0IjpbIm1haWx0bzphZG1pbi..."],
"protected": "eyJhbGciOiJFUzI1NiIsIm5vbmNlIjoiZG1GMWJIUXc1MmJrUmdRRE9faVBac0dLYTF0SzExbGIzdHJNcDFFOFNYOWhyTzgzV3RwUU1jUS16YjZYTWciLCJ1cmwiOiJodHRwczovL3ZhdWx0L.../YWNtZS9uZXctYWNjb3VudCIsImp3ayI6eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6IjdKY25ESkp6ZDA4LUhmQTJXNlFOeGdMTzNpUks3R1NRYnJTQVdqSTkwdGsiLCJ5IjoiNmp6S3JTMTJ4T2lwUkR1MFlTOVFFdmxZUXg3S3dLTms0c2w5RUxxSFJhRSJ9fQ",
"signature": "roYvvNxOkwrA-6sH...z4YMmQ"
}
Response 200 OK
Headers (selected):
Replay-Nonce: dmF1bHQwwfFNcP9wK-8kFdqWdmEnuPEDO1PZ6IOB3GTeHDv57Uv5cXhGcCwbeA ; (Nonce B)
Location: https://vault/v1/muac-pki/roles/muac-pki-configuration/acme/account/bc869801-4d57-d886-593d-ee268a62372f
Body
{
"contact": ["mailto:[email protected]"],
"orders": "https://vault/v1/.../account/bc869801-.../orders",
"status": "valid"
}
3) Create new order (should use Nonce B; server returns Nonce C)
Request
POST https://vault/v1/muac-pki/roles/muac-pki-configuration/acme/new-order
Content-Type: application/jose+json
Body
{
"payload": "eyJpZGVudGlmaWVycyI6W3sidHlwZSI6ImRucyIsInZhbHVlIjoicmVxdWVzdG9yIn1dfQ==",
"protected": "eyJhbGciOiJFUzI1NiIsIm5vbmNlIjoiZG1GMWJIUXd3ZkZOY1A5d0stOGtGZHFXZG1FbnVQRURPMVBaNklPQjNHVGVIRHY1N1V2NWNYaEdjQ3diZUEiLCJ1cmwiOiJodHRwczovL3ZhdWx0L3YxL211YWMtcGtpL3JvbGVzL211YWMtcGtpLWNvbmZpZ3VyYXRpb24vYWNtZS9uZXctb3JkZXIiLCJraWQiOiJodHRwczovL3ZhdWx0L3YxL211YWMtcGtpL3JvbGVzL211YWMtcGtpLWNvbmZpZ3VyYXRpb24vYWNtZS9hY2NvdW50L2JjODY5ODAxLTRkNTctZDg4Ni01OTNkLWVlMjY4YTYyMzcyZiJ9",
"signature": "rUVZgoe1ae1N5Gw0N1RxOpwi...XWIUmPg"
}
Response 201 Created
Headers (selected):
Replay-Nonce: dmF1bHQwlJ9CxxdvWuIbtDA8T0NhxmEbH0i9ZgVZvRf8sx0X1beF3Lw5OYuJ4w ; (Nonce C)
Location: https://vault/v1/.../acme/order/895107f9-fd75-0808-a098-739d34a4d08d
Body
{
"authorizations": ["https://vault/v1/.../acme/authorization/988040e0-f976-a36c-8eba-aad7e55e4254"],
"expires": "2025-09-04T08:22:37Z",
"finalize": "https://vault/v1/.../acme/order/895107f9-fd75-0808-a098-739d34a4d08d/finalize",
"identifiers": [{ "type": "dns", "value": "requestor" }],
"status": "pending"
}
4) Fetch authorization (client reuses prior JWS protected → badNonce)
Request
POST https://vault/v1/.../acme/authorization/988040e0-f976-a36c-8eba-aad7e55e4254 Content-Type: application/jose+json
Body shows identical protected value as in step 3 (nonce reused):
{
"payload": "",
"protected": "eyJhbGciOiJFUzI1NiIsIm5vbmNlIjoiZG1GMWJIUXd3ZkZOY1A5d0stOGtGZHFXZG1FbnVQRURPMVBaNklPQjNHVGVIRHY1N1V2NWNYaEdjQ3diZUEiLCJ1cmwiOiJodHRwczovL3ZhdWx0L3YxL211YWMtcGtpL3JvbGVzL211YWMtcGtpLWNvbmZpZ3VyYXRpb24vYWNtZS9hdXRob3JpemF0aW9uLzk4ODA0MGUwLWY5NzYtYTM2Yy04ZWJhLWFhZDdlNTVlNDI1NCIsImtpZCI6Imh0dHBzOi8vdmF1bHQvdjEvbXVhYy1wa2kvcm9sZXMvbXVhYy1wa2ktY29uZmlndXJhdGlvbi9hY21lL2FjY291bnQvYmM4Njk4MDEtNGQ1Ny1kODg2LTU5M2QtZWUyNjhhNjIzNzJmIn0",
"signature": "ixdYppdlztOfiAXAP_RDpwmr...w6BUwg"
}
Response 400 Bad Request
Body:
{
"type": "urn:ietf:params:acme:error:badNonce",
"detail": "invalid or reused nonce: The client sent an unacceptable anti-replay nonce",
"subproblems": null
}