Cert hot-reloading

David Arnold dar at xoe.solutions
Mon Aug 31 02:24:13 UTC 2020

Should aspects of an implementation be configurable behavior with a 
sane default? I'd guess so...

Hot-plugging the pointer seems to force atomicity considerations 
down-stream, which might be
educationally a good thing for openssl to press for. It also addresses 
Jordan's use case, for however
application specific it might be. For compat reasons, a "legacy" mode 
which creates a new context
for *new* connections might be the necessary "bridge" into that 

For change detection: I think "on next authentication" has enough (or 
even better) guarantees over a periodic loop.

For file read atomicity: What are the options to keep letsencrypt & co 
at comfort? Although the hereditary
"right (expectation) for comfort" is somewhat offset by a huge gain in 
functionality. It still feels like a convincing deal.

- add a staleness check on every change detection? (maybe costly?)
- consume a tar if clients want those guarantees? (opt-out or opt-out?)

On Sun, Aug 30, 2020 at 19:54, Kyle Hamilton <aerowolf at gmail.com> wrote:
> I'm not sure I can follow the "in all cases it's important to keep 
> the key and cert in the same file" argument, particularly in line 
> with openat() usage on the cert file after privilege to open the key 
> file has been dropped.  I agree that key/cert staleness is important 
> to address in some manner, but I don't think it's necessarily 
> appropriate here.
> I also don't think it's necessarily okay to add a new requirement 
> that e.g. letsencrypt clients reconcatentate their keys and certs, 
> and that all of the Apache-style configuration guides be rewritten to 
> consolidate the key and cert files. On a simple certificate renewal 
> without a rekey, the best current practice is sufficient.  (As well, 
> a letsencrypt client would possibly need to run privileged in that 
> scenario to reread the private key file in order to reconcatenate it, 
> which is not currently actually necessary.  Increasing the privileges 
> required for any non-OS service for any purpose that isn't related to 
> OS kernel privilege requirements feels a bit disingenuous.)
> Of course, if you want to alter the conditions which led to the best 
> current practice (and impose retraining on everyone), that's a 
> different matter.  But I still think increasing privilege 
> requirements would be a bad thing, under the least-privilege 
> principle.
> -Kyle H
> On Sun, Aug 30, 2020, 18:36 Viktor Dukhovni 
> <openssl-users at dukhovni.org <mailto:openssl-users at dukhovni.org>> 
> wrote:
>> On Sun, Aug 30, 2020 at 05:45:41PM -0500, David Arnold wrote:
>>  > If you prefer this mailing list over github issues, I still want 
>> to ask
>>  > for comments on:
>>  >
>>  > Certificate hot-reloading #12753
>>  > <<https://github.com/openssl/openssl/issues/12753>>
>>  >
>>  > Specifically, my impression is that this topic has died down a 
>> bit and
>>  > from the linked mailing list threads, in my eye, no concrete 
>> conclusion
>>  > was drawn.
>>  >
>>  > I'm not sure how to rank this motion in the context of OpenSSL
>>  > development, but I guess OpenSSL is used to producing ripple 
>> effects,
>>  > so the man-hour argument might be a genuinely valid one.
>>  >
>>  > Please inform my research about this issue with your comments!
>>  This is a worthwhile topic.  It has a few interesting aspects:
>>      1.  Automatic key+cert reloads upon updates of key+cert chain 
>> PEM
>>          files.  This can be tricky when processes start privileged,
>>          load the certs and then drop privs, and are no longer able
>>          to reopen the key + cert chain file.
>>          - Here, for POSIX systems I'd go with an approach where
>>            it is the containing directory that is restricted to
>>            root or similar, and the actual cert files are group
>>            and or world readable.  The process can then keep
>>            the directory file descriptor open, and then openat(2)
>>            to periodically check the cert file, reloading when
>>            the metadata changes.
>>          - With non-POSIX systems, or applications that don't
>>            drop privs, the openat(2) is not needed, and one
>>            just checks the cert chain periodically.
>>          - Another option is to use passphrase-protected keys,
>>            and load the secret passphrase at process start from
>>            a separate read-protected file, while the actual
>>            private key + cert chain file is world readable,
>>            with the access control via protecting the passphrase
>>            file.
>>          - In all cases, it is important to keep both the private
>>            key and the cert in the same file, and open it just
>>            once to read both, avoiding races in which the key
>>            and cert are read in a way that results in one or
>>            the other being stale.
>>      2.  Having somehow obtained a new key + cert chain, one
>>          now wants to non-disruptively apply them to running
>>          servers.  Here there are two potential approaches:
>>          - Hot plug a new pointer into an existing SSL_CTX structure.
>>            While the update itself could be made atomic, the readers
>>            of such pointers might read them more than once to 
>> separately
>>            extract the key and the cert chain, without checking that
>>            they're using the same pointer for both operations.
>>            This is bound to be fragile, though not necessarily
>>            impossible.
>>          - Build a new SSL_CTX, and use it to accept *new* 
>> connections,
>>            while existing connections use whatever SSL_CTX they 
>> started
>>            with.  I believe this can work well, because "SSL" handles
>>            increment the reference count of the associated SSL_CTX
>>            when they're created, and decrement it when destroyed.
>>            So when you create a replacement SSL_CTX, you can just
>>            SSL_CTX_free() the old, and it will only actually
>>            be deleted when the last SSL connection tied to that
>>            SSL_CTX is destroyed.
>>            It is true that typical SSL_CTX construction is modestly
>>            expensive (loading CA stores and the like) but some of
>>            that could be handled by sharing and reference-counting
>>            the stores.
>>  So my preferred approach would be to create a new SSL_CTX, and get 
>> new
>>  connections using that.  Now in a multi-threaded server, it could 
>> be a
>>  bit tricky to ensure that the SSL_CTX_free() does not happen before 
>> all
>>  threads reading the pointer to the latest SSL_CTX see the new 
>> pointer
>>  installed.  Something equivalent to RCU may be needed to ensure 
>> that the
>>  free only happens after the new pointer is visible in all threads.
>>  Designs addressing various parts of this would be cool, provided 
>> they're
>>  well thought out, and not just single-use-case quick hacks.
>>  --
>>      Viktor.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20200830/635c3cc5/attachment-0001.html>

More information about the openssl-users mailing list