pebble
pebble copied to clipboard
Implement the "dns-account-01" Challenge in Pebble
Objective
Implement the "dns-account-01" challenge in Pebble, setting the groundwork for subsequent Boulder alignment (referencing boulder#7240).
Rationale
Establishing this feature in Pebble first is crucial for a consistent and forward-compatible testing framework.
I found that it's nontrival for pebble to do this: because accountURL needed to calculate this is dependent to domain of ACME uses, which pebble doesn't configed and not known. and just listen on everything: Edit: solved with wfe send to what domain name it got
In addition to the ongoing work from @orangepizza, I have prepared two changes to support Pebble integration tests using dns-account-01
.
- https://github.com/certbot/certbot/pull/9887
- https://github.com/letsencrypt/pebble/pull/432
In conjunction with my proposed change to https://github.com/letsencrypt/pebble/pull/430 (see https://github.com/letsencrypt/pebble/pull/430#issuecomment-1928497141), the preceding changes to certbot/acme
and pebble/test/chisel2.py
enable a successful integration test between pebble, challtestsrv and chisel2.
Example run:
REQUESTS_CA_BUNDLE=pebble/test/certs/pebble.minica.pem \
python3 -c 'import pebble.test.chisel2; pebble.test.chisel2.auth_and_issue(["foo.com"],"dns-account-01")'
…
DEBUG:urllib3.connectionpool:https://localhost:14000 "POST /authZ/AFDXL5tMBBi6GTDqetoTuPArYOTXi7_GGL0CQWCh6Qs HTTP/1.1" 200 440
DEBUG:acme.client:Received response:
HTTP 200
Cache-Control: public, max-age=0, no-cache
Content-Type: application/json; charset=utf-8
Link: <https://localhost:14000/dir>;rel="index"
Replay-Nonce: BAMHTKcD2aNAyopsB-9zZg
Date: Tue, 06 Feb 2024 00:29:17 GMT
Content-Length: 440
{
"status": "valid",
"identifier": {
"type": "dns",
"value": "foo.com"
},
"challenges": [
{
"type": "dns-account-01",
"url": "https://localhost:14000/chalZ/lV0CIU0zxaGkt5Ib7og8d1vkQo1A2EHzMREKbgdsZOI",
"token": "01Wsj3RQfOinMJ7-lbKRBeElrLBI8OaUv99Jioem0_w",
"status": "valid",
"validated": "2024-02-06T00:29:14Z"
}
],
"expires": "2024-02-06T01:29:17Z"
}
…
…
pebble-challtestsrv - 2024/02/05 19:29:14 Added DNS-01 TXT challenge for Host "_f75qxvkvtswybx6u._acme-challenge.foo.com." - Value "jjxuv--W5N1o1TujkI12Db6jakJfAXLFfDEpjsEYVGA"
pebble-challtestsrv - 2024/02/05 19:29:18 Removed DNS-01 TXT challenge for Host "_f75qxvkvtswybx6u._acme-challenge.foo.com."
I thought that suggestion was shot down be LE employee: https://github.com/aarongable https://github.com/aaomidi/draft-ietf-acme-dns-account-challenge/issues/13#issuecomment-1456568409
At no point do the Baseline Requirements constrain what the Authorization Domain Name may be.
This is incorrect. The Authorization Domain Name is defined as the FQDN used to obtain authorization, which sounds like a wide-open definition, but there are restrictions on what FQDNs can be used to obtain authorization, and therefore there are restrictions on what FQDNs can be Authorization Domain Names (all following quotes from the definition of Authorization Domain Name in Section 1.6.1 of the BRs):
The CA may use the FQDN returned from a DNS CNAME lookup as the FQDN for the purposes of domain validation.
i.e. the Authorization Domain Name may be the FQDN to be included in the Certificate
The CA may prune zero or more Domain Labels of the FQDN from left to right until encountering a Base Domain Name and may use any one of the values that were yielded by pruning (including the Base Domain Name itself) for the purpose of domain validation.
i.e. you can convert the Certificate FQDN into an Authorization Domain Name by pruning labels from left to right.
In other words, you cannot go the other direction: you cannot convert an Authorization Domain Name into a Certificate FQDN by trimming labels from left to right.
Therefore, if the TXT Record is
_foo._bar.example.com
, then the Authorization Domain Name is_bar.example.com
, and you can issue for*._bar_example.com
but not forexample.com
. well I'm only looking at RFC draft IETF side so I don't know about at all. I think it'd caught by there too
Added a comment at https://github.com/aaomidi/draft-ietf-acme-dns-account-challenge/issues/13#issuecomment-1928640871
The dns-account-01
Python client implementation is ready for review in:
- https://github.com/certbot/certbot/pull/9887
After that is approved and merged the chisel2
changes will be readied in:
- https://github.com/letsencrypt/pebble/pull/432
Hi all, we're getting close to publishing a new draft. Here is a preview: https://aaomidi.github.io/draft-ietf-acme-scoped-dns-challenges/
Sorry for adding a ton of changes here, but ultimately we felt like we need to incorporate the teachings in https://datatracker.ietf.org/doc/draft-ietf-dnsop-domain-verification-techniques/
I believe https://github.com/certbot/certbot/pull/9887 might need to be updated to follow up with this new draft as well.
Because subdomain auth is not yet implemented in Boulder (per https://github.com/letsencrypt/boulder/issues/7050), this implementation would be:
"_" || base32(SHA-256(<ACCOUNT_RESOURCE_URL>)[0:10]) || "._acme-" || <SCOPE> || "-challenge"
for SCOPE in
- "host"
- "wildcard"
NOT SCOPE in
- "domain"
based on https://github.com/aaomidi/draft-ietf-acme-scoped-dns-challenges/blob/0058e0800056698fb37f3b2cb31a727c826675fb/draft-ietf-acme-scoped-dns-challenges.mkd
I have a fork of https://github.com/eggsampler/acme with dns-account-01
support implemented per the latest draft (https://github.com/aaomidi/draft-ietf-acme-scoped-dns-challenges/blob/0058e0800056698fb37f3b2cb31a727c826675fb/draft-ietf-acme-scoped-dns-challenges.mkd). This will be useful for the Go integration tests.
https://github.com/sheurich/eggsampler-acme/tree/add-dns-account-01
The validation label computation is:
acctHash := sha256.Sum256([]byte(acct.URL))
acctLabel := strings.ToLower(base32.StdEncoding.EncodeToString(acctHash[0:10]))
scope := "host"
if auth.Wildcard {
scope = "wildcard"
}
host := "_" + acctLabel + "._acme-" + scope + "-challenge." + auth.Identifier.Value + "."
as seen in https://github.com/sheurich/eggsampler-acme/blob/18317c3a082d1ab3e2db62df0808ec39e09318e7/utility_test.go#L325-L332
Solved by https://github.com/letsencrypt/pebble/pull/435