How can Let's Encrypt verify the identity over insecure http?
I just started using Let's Encrypt. The http-01-challenge is simple enough:
- Make a webserver respond to http://example.com
- Ask Let's Encrypt for a challenge-file
- Provide the file unter http://example.com/.well-known/acme-challenge
- Receive the TLS-certificate for example.com
Works like a charm. But how are they making sure that I am really the owner of example.com using an insecure http-connection?
Couldn't some admin in my data center (or at my ISP) just request a certificate and intercept the http-requests, Let's Enrypt sends to check the server's identity?
Indeed, there is no infallible protection against a man-in-the-middle attack for the HTTP-01 challenge.
Someone who can intercept traffic between the Let's Encrypt validation nodes and your server CAN pass the challenge and get a cert issued. If they can pull off BGP trickery they may not necessarily even be in the middle in the normal sense.
This applies to the HTTP-01 challenge and for unsigned domains also the DNS-01 challenge.
It's worth noting that this problem is not unique to Lets Encrypt, the validation done by traditional CAs for DV certificates generally has this same problem; they typically offer HTTP, DNS and Email validation options, all of which are susceptible to a MITM attack.
What Let's Encrypt has done to mitigate the problem, is to run each validation from multiple test nodes in different data centers, requiring that all the test results agree in order to issue the certificate. (Which I suspect makes them less susceptible to this type of abuse than most of the traditional CAs.)
This at least reduces the scope of who might be in "the middle", as large parts of "the middle" will be different as viewed from the different test nodes.
This is all about the default behavior of automated domain-validation by Let's Encrypt (and CAs in general), but the domain owner has been given some additional control with the requirement that public CA's must check CAA
records.
In order to actually take control, the domain owner can take these steps:
- DNSSEC-sign the zone to ensure that the
CAA
data is not tampered with
(Also protects the challenge itself in the case of DNS-01) - Add one or more
CAA
records to limit issuance of certificates
(ParticularlyCAA
records that do not only name the CA that is allowed to issue, but also which account with that CA that is allowed)
With a CAA
record looking something like this:
example.com. IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/12346789"
the problem is much reduced as an impostor cannot trivially initiate the challenge in the first place.
Pay special attention to the accounturi
parameter in the CAA
data, this is what makes the policy specific to the domain owner's account with the specified CA.
A CAA
record that only specifies the CA but not an account, while valid, would be of limited help as such a policy still allows any other customer of that CA to request having certificates issued.
Justification for using http when getting the HTTP-01 challenge is in the spec:
Because many web servers allocate a default HTTPS virtual host to a particular low-privilege tenant user in a subtle and non-intuitive manner, the challenge must be completed over HTTP, not HTTPS.
This challenge is distinct from the ACME protocol messages. The spec mandates https. ACME also has integrity and replay protections on its signed messages. Even if the traffic was captured, there is more to compromising it than just the unencrypted challenge. Of course there is some risk to it, but what's the alternative for a better domain verification procedure?
A more complete approach to monitoring for unauthorized certificates may involve certificate transparency. Search or set up alerts on CT logs for your names. Issuing CA, serial number, and date should all be familiar.