acme icon indicating copy to clipboard operation
acme copied to clipboard

Check expiry

Open chr4 opened this issue 8 years ago • 25 comments

I hacked together a quick check:

  • Check whether .crt is present and readable
  • Parse .crt and check whether it's valid for more than a week
  • Quit exit(1) if so

This solves https://github.com/google/acme/issues/30 (for me) (in a quick way)

chr4 avatar Jun 14 '16 11:06 chr4

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

:memo: Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

googlebot avatar Jun 14 '16 11:06 googlebot

Signed it.

chr4 avatar Jun 14 '16 13:06 chr4

CLAs look good, thanks!

googlebot avatar Jun 14 '16 13:06 googlebot

Been thinking about this. Not sure it's the best way because:

  • "cert is still valid for more than one week, not renewing" is a bit harsh :) I know many people/orgs re-create certs even 1 month prior to expiry, to have higher availability.
  • could be achieved with openssl quite easily, e.g. parse a cert with openssl, check its expiration timestamp and run acme only if needed.

I would think an acme renew, a new sub command, could do this behind a flag, e.g.:

# request a new cert of a previously authorized domain
acme renew example.com
# renew only if expiring within the next 48 hours
acme renew -e 48h example.com

wdyt?

I like readCrt func though. Certainly useful for the future acme renew command.

x1ddos avatar Jun 16 '16 09:06 x1ddos

I'm definitly open on the wording :) I agree, that a flag like -e to specify the renew-timeframe (the default value can be somewhere between 1-4 weeks) is a good idea.

Some thoughts on the external openssl approach: Parsing the expiry date using openssl is not that straightforward, and it requires some shell-scripting (and the openssl binary). Not sure if there's a better way, but I ended up using something like this:

expr $(expr $(date '+%s' --date "$(sudo openssl x509 -enddate -noout -in example.com.crt |grep 'notAfter' |cut -d= -f2)") - $(date '+%s')) / 24 / 3600

Especially since it's only a few lines of Go code, without any further dependencies, I'd vote for doing this internally.

chr4 avatar Jun 16 '16 12:06 chr4

Ok, yeah, there's value in doing it internally but I really want to keep commands behavior to a minimum when it comes to a critical decision (e.g. whether to re-issue a cert or not). So, here's what I would do:

  • leave acme cert as is
  • add new acme renew, which renews an existing cert (there's a specific flow for this in the spec, much easier than new cert), taking into account an -e flag.

how does that sound?

x1ddos avatar Jun 16 '16 12:06 x1ddos

As the official certbot client has a renew sub-command as well, I suppose it's a good idea to follow that, especially if the internal flow is different. So, basically, renew must be implemented first, right?

chr4 avatar Jun 16 '16 12:06 chr4

Precisely. Or, it could also be an option to the acme cert command:

# will renew all existing certs which expire within the next 48 hours
acme cert -renew=48h
# renew only specific domain(s)
acme cert -renew=48h one.example.com two.example.com
# renew all using default value
acme cert -renew

Now that I'm looking at it, seems simpler than adding a new acme renew command. Empty renew, acme cert -renew could have a sensible default, e.g. 1 week or 1 month.

Do you see any scenarios I'm missing, which would require a separate acme renew command?

x1ddos avatar Jun 16 '16 12:06 x1ddos

Not sure if this is an issue, but I can think of one reason to split it into two commands: If you accidently use cert over and over again, you end up re-issuing the certificate as often as your cronjob runs.

If this is an issue, it might be also be solved by requiring a -force if cert is used and the .crt file is already present.

Besides that, I have no personal preference between acme cert -renew or acme renew, unless the preference is to copy the behaviour of certbot.

chr4 avatar Jun 16 '16 12:06 chr4

Ok, let's go with a separate acme renew. The command usage text will be simpler, too, as it'll require less flags.

x1ddos avatar Jun 16 '16 12:06 x1ddos

Sounds great. Thoughts about the "safeguard" for accidently re-issuing an existing certificate with acme cert?

chr4 avatar Jun 16 '16 13:06 chr4

AFAIK re-issuing a cert does not revoke the existing one, so it should be safe. But, like you said, we can always add '-force' arg to acme cert in the future, if this turns out to be an issue.

x1ddos avatar Jun 16 '16 13:06 x1ddos

Yeah, the issue would rather be load on the letsencrypt servers than inaccessibility of our services. Let me know if there's a task that I can help you with!

chr4 avatar Jun 16 '16 18:06 chr4

I just started using acme, discovered renewal wasn't implemented, but then found this lovely pull request! What are the chances of a merge and release before my next renewal? 😉

jdub avatar Oct 02 '16 03:10 jdub

Are these changes likely to land?

jdub avatar Dec 14 '16 10:12 jdub

@jdub what is it exactly that you'd need? acme cert ... using an account which was previously granted the authorization for a domain will create a new certificate, effectively doing the renew.

Could you sum-up what the need is, in a bullet list style.

x1ddos avatar Dec 14 '16 10:12 x1ddos

Hmm, that's odd, acme cert doesn't seem to renew as I'd expect.

  • acme whoami returns sensible information
  • acme cert waugh.id.au -dns waugh.id.au www.waugh.id.au mail.waugh.id.au responds with: waugh.id.au: acme: identifier authorization failed
  • I have another domain for which I need an EC cert and an RSA cert -- it prompts for me to add a new _acme-challenge DNS entry.

jdub avatar Dec 14 '16 11:12 jdub

if you have already issued at least one certificate in the past, the next time invocation of merely acme cert <same list of domains>, i.e. without additional flags like -dns, will give you the new certificates right away.

x1ddos avatar Dec 14 '16 11:12 x1ddos

Oh, without -dns. I thought I should tell it how it had been authorised. Unfortunately, that didn't seem to work either:

$ ls .config/acme/waugh.id.au.*
-rw-r--r-- 1 jdub jdub 3.2K Oct  1 12:23 .config/acme/waugh.id.au.crt
-rw------- 1 jdub jdub  227 Oct  1 12:21 .config/acme/waugh.id.au.key

jdub@node:~$ acme cert waugh.id.au www.waugh.id.au mail.waugh.id.au
waugh.id.au: acme: identifier authorization failed

I can't see a verbose option… is there an environment variable, perhaps?

jdub avatar Dec 14 '16 11:12 jdub

That is strange. I've just done it about 30 min ago. Are you sure you used the same account?

The reason it works is, Let's Encrypt remembers all identifiers (domains) that an account has been previously authorized for. It could be the case though, that by running acme cert -dns ... a completely new authorization was created, overwriting an existing valid one. So, it might be in a "pending" state now.

What should work is:

  1. Request a new certificate(s) in the regular way by fulfilling a challenge, e.g. dns.
  2. Every time you want to renew a cert, just execute acme cert <domains list>, without any other option.

It may be arguable that a command like acme renew could be implemented, actually, as a subset of acme cert command, just to avoid confusion.

x1ddos avatar Dec 14 '16 16:12 x1ddos

Yeah, the new authorisation theory makes sense. D'oh! I'll have to wait for the next renewal period to try it the right way. Thanks for your help!

(I do think a renew command, without any parameters like -dns would help avoid errors like this.)

jdub avatar Dec 14 '16 19:12 jdub

Three months later… unfortunately:

jdub@node:~$ acme cert waugh.id.au www.waugh.id.au mail.waugh.id.au
waugh.id.au: acme: identifier authorization failed

jdub avatar Mar 13 '17 20:03 jdub

I'm getting the same identifier authorization failed message. I suppose this should be a seperate issue?

chr4 avatar Apr 10 '17 14:04 chr4

@chr4 I don't think so. This bug is just a helper to renew the certs easier. But it should already work regardless.

What challenge type are you using?

x1ddos avatar Apr 10 '17 14:04 x1ddos

@x1ddos you're right. This was actually due to a misconfiguration of nginx, the challenges weren't served.

While you're here: Any news on the support for only renewing certificates when they're about to expire? I'm still using my fork to achieve this. Let me know if there's anything that I can help implementing!

chr4 avatar Apr 10 '17 14:04 chr4