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

[Feature request] Avoid interruptions of the HTTP & HTTPS services when renewing the letsencrypt certificate #76

Open
kit-ty-kate opened this issue Nov 13, 2022 · 3 comments · May be fixed by #77

Comments

@kit-ty-kate
Copy link
Contributor

As far as i understand, right now, the way to renew the letsencrypt certificate for a given mirage application for example is to:

  1. stop the current HTTP/80 server
  2. restart it with LE.request_handler
  3. restart HTTP/80 with its normal operation (usually redirect)
  4. restart the HTTPS service with the new certificate

As far as I see, it should be possible to:

  • Keep the same HTTP/80 service by having LE.request_handler take a follow-up handler called for all the cases that are not /.well-known/acme-challenge/<token>
  • Avoid interruptions in the HTTPS service by modifying the certificate in place, by, for example, changing the expected type of Paf.https_service from tls:Tls.Config.server -> ... to tls:Tls.Config.server ref -> ...
@kit-ty-kate kit-ty-kate changed the title [Feature request] Be able to replace the letsencrypt certificate in place [Feature request] Avoid interruptions of the HTTP & HTTPS services when renewing the letsencrypt certificate Nov 13, 2022
@dinosaure
Copy link
Owner

Yes, this question appeared for contruno which is a TLS termination proxy. The main issue is about the *:80 server. We probably can compose the user's request_handler with the LE.request_handler and allow such path if we want to renew the certificate.

Then, for the TLS part, ocaml-tls has the reneg functions which is able to reset the underlying Tls.Config.server with a new one for a alive connection. Then, I create a Tls.Config.server in-the-fly (for every requests, I reload all available and non-experied certificates and create the Tls.Config.server at the "handshake".

@hannesm
Copy link
Contributor

hannesm commented Nov 16, 2022

Hello,

so for what is worth, my impression/idea is:

  • since paf does the TLS handshake, it could use the ALPN challenge (and analyze the ALPN field in the client hello)
  • this means there's no need for switching forth and back between let's encrypt and normal traffic
  • for updating the certificate (and keeping the old TCP connections alive), what can be done is registering a new listener on the https port with the updated certificate. no need for mutable data

Since usually you'd do a let's encrypt renegotiation ahead of time (1 week before expiry or so), I wouldn't bother with rekey/reneg of existing sessions, but instead assume they'll be fine (and there's no connection that outlives an expired certificate). :)

WDYT?

@kit-ty-kate
Copy link
Contributor Author

As long as the user/dev experience doesn't become overcomplicated I'm all for it.
Do you have an API change in mind for that to work?

See also this somewhat related work to make the API higher-level: #75, which would have to be rewritten probably.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants