Wandering Thoughts archives


I now think you should have lots of Let's Encrypt accounts

Part of setting up and using Let's Encrypt is creating an account, which is really just a public keypair. When I was just starting out with LE and using it on test machines, I was careful to save (and restore) the account information when I reinstalled machines, and I worried about things like how to arrange it so that we'd use the same account on multiple machines. This seemed like the right thing to do and it's certainly what you do with many other services; you really only want to have one account registered with them, not a huge morass of separate registrations from different machines at different times and so on.

I now believe that this is a mistake. The core problem is that authorized accounts have a surprisingly large amount of power. Compromise of an account's keys means that an attacker can get 90-day certificates for any host or domain that the account is authorized for without having to prove they do or still have control over the host, for up to 60 days.

(If the attacker is reasonably clever, you will have real problems getting these certificates revoked.)

So this leads us to the standard security idea of least privilege for your Let's Encrypt accounts. In the LE context, this means that your LE account should have authorization for as few hosts as possible. The best way to get this is to not to carefully reuse LE accounts but instead to make new ones every time you can reasonably separate the security contexts of the two accounts. Do you have ten machines, each getting certificates for a different set of hosts? Then each machine should have its own account, so that compromise of the account only gives (60-day) control over certificates for that set of hosts, not all of your hosts. Are you reinstalling a machine? Deliberately destroy the old account keys, rather than saving and reusing them.

I don't think it's harmful to keep on using the same account (keys) on a single server for a long amount of time, and it's probably more friendly on Let's Encrypt's backend servers and so on. But I now feel that we definitely should not reuse accounts between different machines (including a reinstalled version of the same machine). Conveniently this makes canned setup instructions for Let's Encrypt clients easier, because you don't have to work out how to save and restore account keys; you can just let each client (re)install generate a new account, which pretty much every client is going to have good support for.

Sidebar: Accounts and certificate revocation

If I'm reading the draft protocol specification correctly, you probably don't have to preserve your account key in order to be able to revoke a certificate later. What matters is that you have an account (any account) that is currently authorized for all of the names in the certificate (or that you hold the private key for the certificate itself).

The requirement that you have authorization for all names in the certificate is perfectly reasonable, but it's also going to cause real heartburn for revoking certificates generated from stolen keys. A canny attacker will immediately authorize the account key for some completely unrelated domain, then attach this name to all of the certificates they get. This extra name will block you from revoking these certificates because while you can demonstrate authorization for your own domain(s), you can't get it for this outside domain.

(This also suggests that you should not normally get cross-domain certificates, ones for hosts from multiple (sub)domains, even if you currently control all of the domains. Get separate certificates for the separate domains, just in case, so that if you wind up transferring control of one (sub)domain you don't have certificates that need the cooperation of all parties involved to revoke.)

PS: The usual disclaimers about practical problems with certificate revocation almost certainly apply here. In practice you're probably just going to have to let those 90 days run out on the certificates before they turn off.

sysadmin/LetsEncryptManyAccounts written at 17:55:59; Add Comment

Understanding the Let's Encrypt authorization process

Up until quite recently, I would have confidently told you that I understood the broad flow of how Let's Encrypt's authorization process for getting certificates worked (although not the fine details). It went something like this:

  1. you registered an account with Let's Encrypt, giving them a public key along with your ritual agreement to their TOS and perhaps an email address for eg account recovery.

  2. using your registered account, you asked Let's Encrypt for a certificate for host or domain X.
  3. Let's Encrypt said 'okay, prove that you control domain X' with one of their various challenges.
  4. when you'd satisfied the challenge, Let's Encrypt gave you a 90-day certificate back.

When you wanted to renew the certificate, you repeated the second through fourth steps.

It turns out that this is not how the process actually works, and how the process works has some implications. The actual process is clearly documented by Let's Encrypt (and then there's always the more formal version). Instead of the above, the actual process is:

  1. register an account with Let's Encrypt.
  2. assert to Let's Encrypt that your account controls one or more domains.
  3. Let's Encrypt challenges you to prove this, and you satisfy the challenges. Your account is now authorized for those domains.

  4. ask Let's Encrypt for a certificate for domains that you're authorized for. Let's Encrypt gives you your 90-day certificate.

When you want to renew a certificate, you repeat step 4 alone.

The important difference is as long as your authorization for a domain remains valid, you don't have to re-prove your control of that domain. Let's Encrypt doesn't require you to go through a challenge, it'll just give you a certificate. Also, the lifetime of the resulting certificates are not limited by the lifetime of the authorization; if you request a new certificate or renew an old one on the last day that an authorization is valid, you still get a 90-day certificate.

(Ask one day later, and you'd have to re-prove your control to create a new authorization before you could get a certificate.)

This means that a compromised account key gives an attacker the ability to get certificates for all domains the account is authorized for, and to do so for as long as those authorizations remain valid. The protocol allows for authorizations to be deactivated (cf), but the clients I looked at don't expose support for this. There's also deactivating an entire account, which is what the current protocol draft recommends in reaction to compromise of the account's key, but the clients I looked at don't seem to support this either.

(There are some indications that this is not yet implemented in LE's server even though it's in the protocol, which would explain why even the official client doesn't support doing this. Possibly LE is rethinking and iterating how they want to do this.)

At the moment, Let's Encrypt appears to be using a 60 day lifetime on domain authorizations (the expiry time is returned in the protocol and at least acmetool saves this information in its on-disk state). The net effect of this is that if you renew certificates after just short of 60 days (when they have just over 30 days left), you will only be challenged to prove domain control once every other certificate renewal, or roughly about once every 120 days. Or maybe less. My own server logs say that I was challenged only twice this year for my personal site, once in February and once in December.

(It's possible that Let's Encrypt shortened the authorization expiry recently.)

I have opinions about what this means for managing Let's Encrypt client setups across multiple machines in your fleet, but that's for another entry.

tech/LetsEncryptAuthorizations written at 01:32:39; Add Comment

Page tools: See As Normal.
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.