Thanks! I use acme-tiny quite successfully for my servers; I found it the easiest way to arrange privilege isolation between the ACME process getting a certificate signed and the server that needs access to the private key.
Thanks for your (past and future) work on those clients!
In case you haven't seen it yet, Let's Encrypt is working on a testing-only server implementation called pebble[1] that's based on the latest ACME draft. Might come in handy if you want to start working on this before the production ACME server (boulder) is ready.
The rationale put forward was that validating wildcards is hard, because public suffixes, etc. (So if the server checks a few subdomains randomly, a quick attacker can register those subdomains at the provider (eg at a site like github), and then get a cert for the whole domain.
Of course, a DNS based validation scheme would work flawlessly for wildcards. (Something like put a TXT at the zone apex on the SOA nameserver.)
But for some reason LE doesn't want to offer wildcards.
If I request a certificate for "* .github.com", how do you propose that Let's Encrypt check all of the infinitely-many possible subdomains?
> Why would requesting a wildcard for a subdomain (i.e. pas.github.com) give me a cert that works for the root domain (i.e. github.com)?
The issue here is that it's only safe to issue a wildcard certificate to someone who already has full control over all of the domains covered by the wildcard, now and in the future. This is impossible to prove using only an HTTP challenge-response.
For example, let's say an attacker requests a wildcard certificate for "* .github.io". Hypothetically, LE could say: "OK, to prove that you control all possible subdomains, place a particular nonce at http://e9cd20b9c359939c.github.io/.well-known/acme-challenge... Our attacker quickly registers the username "e9cd20b9c359939c" on Github, satisfies the challenge, and gets a cert that allows them to impersonate other Github users.
Alternatively, you could require validation of "github.io" itself, and say that anyone with control over the top-level domain is assumed to be authorized to get wildcard certs as well. But this weakens security for everyone else. For example, Google probably wouldn't be happy if a compromise of their search engine at "google.com" was escalated to a compromise of "accounts.google.com" which handles user sign-in.
These aren't fundamentally unsolvable problems, but there are enough edge cases that the ACME folks decided to postpone wildcards until all the details can be carefully figured out. See https://github.com/letsencrypt/acme-spec/pull/97 for some of the messy details.
> If I request a certificate for "* .github.com", how do you propose that Let's Encrypt check all of the infinitely-many possible subdomains?
They check you have the authority for github.com and you're done. It is a well understood practice that if you control the parent, you control the children.
> For example, let's say an attacker requests a wildcard certificate for "* .github.io". Hypothetically, LE could say: "OK, to prove that you control all possible subdomains, place a particular nonce at http://e9cd20b9c359939c.github.io/.well-known/acme-challenge.... Our attacker quickly registers the username "e9cd20b9c359939c" on Github, satisfies the challenge, and gets a cert that allows them to impersonate other Github users.
Why would they ask you to verify e9cd.. and not just http://github.io/.well-known/acme-challenge ? How can the opposite be true - i.e. I control github.io but I don't control something-else.github.io ?
I think we can both agree that HTTP challenge-response has flaws and DNS verification is the way forward.
> For example, Google probably wouldn't be happy if a compromise of their search engine at "google.com" was escalated to a compromise of "accounts.google.com" which handles user sign-in.
If I compromise the DNS of google.com, I probably get accounts.google.com and all google.com children in the process.
> How can the opposite be true - i.e. I control github.io but I don't control something-else.github.io ?
This is easily possible, because control over the host pointed to by the A record for "github.io" says nothing about your level of control over the DNS nameservers.
To use another example (mentioned in the pull request that I linked to above), somebody from MIT described a setup where they issue arbitrary subdomains that may contain periods, such that "x.y.scripts.mit.edu" and "y.scripts.mit.edu" may both be valid hostnames controlled by different users. Currently, there's nothing that the owner of "y" could do to get a certificate for "x.y"; your proposal would break that guarantee.
This is not intended to prohibit wildcard issuance. It just makes clear that identifiers in authorizations (and therefor challenges) are always actual FQDNs. You may still submit CSRs that include wildcard identifiers, and whether they're issued, which identifiers will have to be validated and what challenge type is required is up to CA policy. This is mentioned in section 10.5 of the spec[1].
To me, Let's Encrypt not supporting wildcards seems mostly like a policy decision where they're choosing not to support some use-cases in exchange for a security win: Not having the compromise of one domain affect certificate issuance for all of its subdomains, less overall complexity and preventing users from getting into the habit of using one wildcard certificate with the same key across multiple services.
TL;DR
Security risk to utility tradeoff doesn't make sense.
Cert acquisition for new domains should be so lightweight that the API should meet most needs. If you hit the rate limit for new subdomains, buy a wildcard cert.
Risk: google.com------------------x.mydomain.com
Etc.
Domain specific certainly allow for easier audit and revocation.
Is there some tiny ACME client implementation with DNS validation and CSR support? Basically: I don't want to make my private keys accessible for acme software and I don't want to rotate them, so I want to generate CSR once and re-use them to generate new certificates. So far I didn't like other implementations, probably will make my own, but may be I missed something.
It sounds like Dehydrated[0] suits your usecase - it's meant to be truly tiny so it doesn't bundle DNS validation; that's generally handled by the DNS Tool Lexicon[1], which includes an example config for use with Dehydrated.
27 comments
[ 3.4 ms ] story [ 64.1 ms ] threadFound the repo were development is being managed: https://github.com/ietf-wg-acme/acme
In case you haven't seen it yet, Let's Encrypt is working on a testing-only server implementation called pebble[1] that's based on the latest ACME draft. Might come in handy if you want to start working on this before the production ACME server (boulder) is ready.
[1]: https://github.com/letsencrypt/pebble
You could also bring functionality similar to Caddy, for other CAs.
> Wildcard domain names (with "*" as the first label) MUST NOT be included in authorization objects.
Of course, a DNS based validation scheme would work flawlessly for wildcards. (Something like put a TXT at the zone apex on the SOA nameserver.)
But for some reason LE doesn't want to offer wildcards.
Are you suggesting only random checks are completed? Why wouldn't it check all of them?
> a quick attacker can register those subdomains at the provider (eg at a site like github), and then get a cert for the whole domain.
Why would requesting a wildcard for a subdomain (i.e. pas.github.com) give me a cert that works for the root domain (i.e. github.com)?
If I request a certificate for "* .github.com", how do you propose that Let's Encrypt check all of the infinitely-many possible subdomains?
> Why would requesting a wildcard for a subdomain (i.e. pas.github.com) give me a cert that works for the root domain (i.e. github.com)?
The issue here is that it's only safe to issue a wildcard certificate to someone who already has full control over all of the domains covered by the wildcard, now and in the future. This is impossible to prove using only an HTTP challenge-response.
For example, let's say an attacker requests a wildcard certificate for "* .github.io". Hypothetically, LE could say: "OK, to prove that you control all possible subdomains, place a particular nonce at http://e9cd20b9c359939c.github.io/.well-known/acme-challenge... Our attacker quickly registers the username "e9cd20b9c359939c" on Github, satisfies the challenge, and gets a cert that allows them to impersonate other Github users.
Alternatively, you could require validation of "github.io" itself, and say that anyone with control over the top-level domain is assumed to be authorized to get wildcard certs as well. But this weakens security for everyone else. For example, Google probably wouldn't be happy if a compromise of their search engine at "google.com" was escalated to a compromise of "accounts.google.com" which handles user sign-in.
These aren't fundamentally unsolvable problems, but there are enough edge cases that the ACME folks decided to postpone wildcards until all the details can be carefully figured out. See https://github.com/letsencrypt/acme-spec/pull/97 for some of the messy details.
They check you have the authority for github.com and you're done. It is a well understood practice that if you control the parent, you control the children.
> For example, let's say an attacker requests a wildcard certificate for "* .github.io". Hypothetically, LE could say: "OK, to prove that you control all possible subdomains, place a particular nonce at http://e9cd20b9c359939c.github.io/.well-known/acme-challenge.... Our attacker quickly registers the username "e9cd20b9c359939c" on Github, satisfies the challenge, and gets a cert that allows them to impersonate other Github users.
Why would they ask you to verify e9cd.. and not just http://github.io/.well-known/acme-challenge ? How can the opposite be true - i.e. I control github.io but I don't control something-else.github.io ?
I think we can both agree that HTTP challenge-response has flaws and DNS verification is the way forward.
> For example, Google probably wouldn't be happy if a compromise of their search engine at "google.com" was escalated to a compromise of "accounts.google.com" which handles user sign-in.
If I compromise the DNS of google.com, I probably get accounts.google.com and all google.com children in the process.
This is easily possible, because control over the host pointed to by the A record for "github.io" says nothing about your level of control over the DNS nameservers.
To use another example (mentioned in the pull request that I linked to above), somebody from MIT described a setup where they issue arbitrary subdomains that may contain periods, such that "x.y.scripts.mit.edu" and "y.scripts.mit.edu" may both be valid hostnames controlled by different users. Currently, there's nothing that the owner of "y" could do to get a certificate for "x.y"; your proposal would break that guarantee.
To me, Let's Encrypt not supporting wildcards seems mostly like a policy decision where they're choosing not to support some use-cases in exchange for a security win: Not having the compromise of one domain affect certificate issuance for all of its subdomains, less overall complexity and preventing users from getting into the habit of using one wildcard certificate with the same key across multiple services.
[1]: https://ietf-wg-acme.github.io/acme/#rfc.section.10.5
Cert acquisition for new domains should be so lightweight that the API should meet most needs. If you hit the rate limit for new subdomains, buy a wildcard cert.
Risk: google.com------------------x.mydomain.com Etc.
Domain specific certainly allow for easier audit and revocation.
Going from $0 to $200 is quite a big step though.
So many of the things we use today use custom APIs that can change on a whim. That makes me sad.
0: https://dehydrated.de/ 1: https://github.com/AnalogJ/lexicon
[0]: https://github.com/xenolf/lego