Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Certmagic to generate 'next' private key to allow safe TLSA/DANE deployment and rollover #294

Open
mdbraber opened this issue Jun 20, 2024 · 5 comments
Labels
feature request Request for new feature or functionality

Comments

@mdbraber
Copy link

mdbraber commented Jun 20, 2024

What would you like to have changed?

DANE (DNS-based Authentication of Named Entities) is a protocol that allows X.509 certificates to be bound to DNS names using Domain Name System Security Extensions (DNSSEC). This is done by having TLSA records which publish the public key of a certificate. In this procedure a safe rollover of certificates is needed, to ensure that a the public key for a new certificate already exists in DNS before the TTL is up. This is documented by Viktor Dukhovni at ICANN61: https://imrryr.org/~viktor/ICANN61-viktor.pdf - see especially slides 20+21 for the rollover procedure ('current + next').

To enable this a 'next' private key should be created when the 'current' private is being used for the certificate renewal. Next time the certificate is renewed the 'next' certificate should be used.

The feature request is to implement an option in Certmagic to allow a 'next' private key to be generated when a certificate is requested. Currently the only (somewhat) viable ways to automate a safe DANE/TLSA rollover are provided by acme.sh and certbot. It would be helpful to have Certmagic (and by extension Caddy) to allow for this as well.

From a quick look it seems that generating a 'next' private key would be trivial - as would the checking for the existence of a 'next' private key when generating a certificate. The somewhat more complicated part seems to be saving just the private key to disk as now it seems all certificate resources are saved to disk at once; and here we would only have a private key to save.

Before starting any work on a PR or making changes I'd like to discuss (@mholt) if (1) this would be something in scope for Certmagic and (2) what would be the suggested way forward?

Why is this feature a useful, necessary, and/or important addition to this project?

This allows for the proposed (safest) procedure to offer DANE/TLSA

What alternatives are there, or what are you doing in the meantime to work around the lack of this feature?

Currently the alternatives are:

Please link to any relevant issues, pull requests, or other discussions.

Similar discussion in acme.sh acmesh-official/acme.sh#3096

@mdbraber mdbraber added the feature request Request for new feature or functionality label Jun 20, 2024
@mholt
Copy link
Member

mholt commented Jun 20, 2024

Thanks for the thoughtful feature request!

I have mixed feelings about the effectivness of DNNSEC (and by extension, DANE) -- are you using this to secure SMTP servers? DNSSEC might be better than STARTTLS.

I'd be open to a proposal here (or, if the implementation is not much work, you could submit a PR for review -- but no guarantees it would be merged so I'd feel bad if you put in a lot of effort at first). Curious what kind of complexity it would introduce.

The somewhat more complicated part seems to be saving just the private key to disk as now it seems all certificate resources are saved to disk at once; and here we would only have a private key to save.

A private key can be stored individually as well, just using the Store() method directly. We are also considering a new Storage interface (a "v2" as it were) but this has yet to be designed. Just FYI :)

@mdbraber
Copy link
Author

mdbraber commented Jun 20, 2024

Thanks for the feedback Matt. In some cases DANE is mandatory, e.g. for Dutch government (more information: https://en.internet.nl/faqs/starttls/). I hadn't dug deep enough yet to find Store() but if that exists, it would mean a rather 'simple' PR I would think (I though that maybe the certificate struct would have to be changed, but that wouldn't be necessary). Didn't yet check, but is there also a Load() (or similar?) to retrieve a stored key file?

From an overview I think this would need to be done:

  • Add option (on a per host basis) that allows for generation of a 'next' key (only enable when ReusePrivateKey is disabled?)
  • Check for existence of a 'next' key when obtaining a certificate to be used a a private key
  • Create 'next' key when obtaining a certificate
  • Store 'next' key when obtaining a certificate

If the above would be the general approach I could definitely try looking into a PR

@mholt
Copy link
Member

mholt commented Jun 20, 2024

Yeah, there's a Load() as well.

Interesting, I had no idea governments would require it. But I guess it makes sense, given that DNSSEC is basically government-controlled PKI.

I think that approach is feasible though. I would want to ensure that this is all behind a config setting that's off by default though.

@mdbraber
Copy link
Author

mdbraber commented Jun 20, 2024

Thanks. Agree with offering this as an option on a per host basis (e.g. I only need this for my SMTP server record). I think the option should imply that ReusePrivateKey = false

As an aside if this is implemented, together with libdns I think we could of offer an integrated DANE/TLSA rotation tool in a single binary (which again means easy inclusion in containers or elsewhere) 🎉

On another note: I've skimmed the DNSSEC article you linked, but it's written in 2015; I'd love to get an opinion on this 10 years later (and there sure are issues, but I'm not sure if DNSSEC as part of a security-mix is particularly bad, but I haven't investigated this in-depth as others, including you, probably have)

@mholt
Copy link
Member

mholt commented Jun 20, 2024

One thing I am in favor of is not reusing private keys, so any scaffolding moving us away from key pinning is a win IMO. If what came of this is the ability to generically rotate keys with DNS records then that'd be a huge win for the Internet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Request for new feature or functionality
Projects
None yet
Development

No branches or pull requests

2 participants