publishlab / node-acme-client

Simple and unopinionated ACME client for Node.js
MIT License
265 stars 52 forks source link

How to renew #9

Closed mhemrg closed 5 years ago

mhemrg commented 5 years ago

Hi, great job :+1: How can I renew my certificates? Is calling auto method to issue and renew certificates the right way? Should I store CSR? Do I need it to renew my certificates?

nmorsman commented 5 years ago

Hey @mhemrg and thanks,

Yes you are correct, to re-issue a certificate just call auto() again. If you use the exact same set of hostnames Let's Encrypt will consider it a certificate renewal[1].

Storing and reusing the CSR (and the certificate key-pair) is up to you, but it is not required to renew a certificate. It has it's pros and cons[2][3]. If you don't plan on using HTTP Public Key Pinning, the most secure option is probably to create a new key and CSR every time you re-issue the certificate.

Hope this helps!

[1] https://letsencrypt.org/docs/rate-limits/ [2] https://community.letsencrypt.org/t/do-new-private-keys-get-regenerated-on-certificate-renewal/21486/4 [3] https://security.stackexchange.com/questions/27810/should-i-change-the-private-key-when-renewing-a-certificate

7c commented 5 years ago

thanks for great library, after having very bad experience with other big library last 3 days this one has worked immediately...

I have a question about renewing... do i need to save account private key? Does acme consider it renewing if the account key matches and domain matches?

nmorsman commented 5 years ago

Hey @7c, glad you found the library useful! :)

Good question regarding account private keys and certificate renewal. I'm not sure about the inner workings of Let's Encrypt, but I'm guessing it would still count as a renewal as long as the hostnames in the CSR match the previous certificate exactly.

Found some discussion about the topic here: https://community.letsencrypt.org/t/why-would-i-want-to-keep-account-keys-around/4123

The idea is that, once you’ve passed a Proof of Possession (PoP) challenge for a given FQDN and issued a cert, subsequent authorizations on the same account would not need to pass a PoP challenge again. PoP challenges are not yet implemented, so I can see why account keys may seem extraneous.

Note that if you generate a new account on every certificate order you could end up hitting the max accounts per IP address rate limit. I would hold on to the account key and re-use it for this reason.

cpu commented 5 years ago

Good question regarding account private keys and certificate renewal. I'm not sure about the inner workings of Let's Encrypt, but I'm guessing it would still count as a renewal as long as the hostnames in the CSR match the previous certificate exactly.

:wave: Happened to be lurking and wanted to drop a note to say that you're correct. Let's Encrypt exclusively looks at the names in certificates to decide if one is a renewal. To be a renewal of an old certificate the new certificate needs to have the exact same set of subject domain names. If you add or remove one it will not be a renewal. The ACME account used isn't considered. The expiration warning email docs also say this authoritatively.

Found some discussion about the topic here: https://community.letsencrypt.org/t/why-would-i-want-to-keep-account-keys-around/4123

Be careful, that's an ancient thread :older_man: :book: The "PoP" challenge terminology is long gone for example.

Note that if you generate a new account on every certificate order you could end up hitting the max accounts per IP address rate limit. I would hold on to the account key and re-use it for this reason.

Seconded. Let's Encrypt recommends large integrators use one account for similar reasons. Your ACME account key will also let you revoke a certificate if you lose its private key.

silverwind commented 3 years ago

Note that if you generate a new account on every certificate order you could end up hitting the max accounts per IP address rate limit. I would hold on to the account key and re-use it for this reason.

Is it enough to store and re-use the account private key without calling createAccount like in this example? Or maybe I have also have to store accountUrl?

silverwind commented 3 years ago

It seems to re-use my account when setting both accountKey and accountUrl.

I find it quite odd that these options are absent in auto mode and that the manual mode example also creates a new account for each request, which should mean each request will create a new account (which probably consumes unnecessary resources on Let's Encrypt's side) and I imagine they may eventually want to ban such abusive clients.

nmorsman commented 3 years ago

Hi @silverwind,

Is it enough to store and re-use the account private key without calling createAccount like in this example? Or maybe I have also have to store accountUrl?

It all depends on the application you are creating. If it's a long running process, supplying only the private key should be sufficient, as the account URL will be retrieved using createAccount once when placing the first certificate order and stored in memory for future orders. This is only true for auto mode, if you are doing it manually you would have to implement this logic yourself. An example of how auto mode does this can be found here.

If it's a short lived process that is invoked several times, like a CLI tool or something placed in crontab, you should supply both the account private key and URL, to avoid the repeated initial request to createAccount every time you fire up the script.

I find it quite odd that these options are absent in auto mode

Not quite sure if I follow you here, both the accountKey and accountUrl are supplied to the client constructor, which will then be used when calling auto():

const client = new acme.Client({
    accountKey: '...',
    accountUrl: '...'
});

await client.auto({});

...and that the manual mode example also creates a new account for each request

Agreed. I'll take a look at updating the manual mode example and documentation regarding this topic so that, hopefully, it becomes more clear.

Thanks for raising this issue, and sorry about the confusion - hope this helps clear things up.

silverwind commented 3 years ago

if it's a long running process, supplying only the private key should be sufficient, as the account URL will be retrieved using createAccount

I think generally createAccount should be avoided in both short and long-running processes. I actually have created my account using another client and am using that so both accountKey and accountUrl are stored in application configuration options. I think there should be some warning in the docs regarding this so users can avoid unnecessary account creations, so users don't hit this rate limit imposed by LetsEncrypt:

"You can create a maximum of 10 Accounts per IP Address per 3 hours"

Not quite sure if I follow you here, both the accountKey and accountUrl are supplied to the client constructor

My bad, I was only looking at .auto, you're right, it's all there.

nmorsman commented 3 years ago

"You can create a maximum of 10 Accounts per IP Address per 3 hours"

As long as the account private key stays the same, I don't believe this should happen. This is because ACME createAccount functions as both an account generator (when the private key is new and unused) and as an existing account URL lookup (when the private key is already tied to an account).

So if the private key is already registered to an account, calling createAccount with that key will not create a new account. It will return the existing one, and therefore not trigger the new account per IP rate limit.

As per https://tools.ietf.org/html/rfc8555#section-7.3.1:

If the server receives a newAccount request signed with a key for which it already has an account registered with the provided account key, then it MUST return a response with status code 200 (OK) and provide the URL of that account in the Location header field. The body of this response represents the account object as it existed on the server before this request; any fields in the request object MUST be ignored. This allows a client that has an account key but not the corresponding account URL to recover the account URL.

silverwind commented 3 years ago

Right, with that kind of handling it should be fine. I wasn't aware of this inner working of createAccount. It's name seems a bit misleading in that regard.