<div id="geary-body" dir="auto"><div>Should aspects of an implementation be configurable behavior with a sane default? I'd guess so...</div><div><br></div><div>Hot-plugging the pointer seems to force atomicity considerations down-stream, which might be</div><div>educationally a good thing for openssl to press for. It also addresses Jordan's use case, for however</div><div>application specific it might be. For compat reasons, a "legacy" mode which creates a new context</div><div>for *new* connections might be the necessary "bridge" into that transformation.</div><div><br></div><div>For change detection: I think "on next authentication" has enough (or even better) guarantees over a periodic loop.</div><div><br></div><div>For file read atomicity: What are the options to keep letsencrypt & co at comfort? Although the hereditary </div><div>"right (expectation) for comfort" is somewhat offset by a huge gain in functionality. It still feels like a convincing deal.</div><div><br></div><div>- add a staleness check on every change detection? (maybe costly?)<br>- consume a tar if clients want those guarantees? (opt-out or opt-out?)</div><div><br></div><div><br></div><div><br></div></div><div id="geary-quote" dir="auto"><br>On Sun, Aug 30, 2020 at 19:54, Kyle Hamilton <aerowolf@gmail.com> wrote:<br><blockquote type="cite"><div dir="auto"><div>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.</div><div dir="auto"><br></div><div dir="auto">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.)</div><div dir="auto"><br></div><div dir="auto">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.</div><div dir="auto"><br></div><div dir="auto">-Kyle H<br><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Sun, Aug 30, 2020, 18:36 Viktor Dukhovni <<a href="mailto:openssl-users@dukhovni.org">openssl-users@dukhovni.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Sun, Aug 30, 2020 at 05:45:41PM -0500, David Arnold wrote:<br>
<br>
> If you prefer this mailing list over github issues, I still want to ask <br>
> for comments on:<br>
> <br>
> Certificate hot-reloading #12753<br>
> <<a href="https://github.com/openssl/openssl/issues/12753" rel="noreferrer noreferrer" target="_blank">https://github.com/openssl/openssl/issues/12753</a>><br>
> <br>
> Specifically, my impression is that this topic has died down a bit and <br>
> from the linked mailing list threads, in my eye, no concrete conclusion <br>
> was drawn.<br>
> <br>
> I'm not sure how to rank this motion in the context of OpenSSL<br>
> development, but I guess OpenSSL is used to producing ripple effects,<br>
> so the man-hour argument might be a genuinely valid one.<br>
> <br>
> Please inform my research about this issue with your comments!<br>
<br>
This is a worthwhile topic.  It has a few interesting aspects:<br>
<br>
    1.  Automatic key+cert reloads upon updates of key+cert chain PEM<br>
        files.  This can be tricky when processes start privileged,<br>
        load the certs and then drop privs, and are no longer able<br>
        to reopen the key + cert chain file.<br>
<br>
        - Here, for POSIX systems I'd go with an approach where<br>
          it is the containing directory that is restricted to<br>
          root or similar, and the actual cert files are group<br>
          and or world readable.  The process can then keep<br>
          the directory file descriptor open, and then openat(2)<br>
          to periodically check the cert file, reloading when<br>
          the metadata changes.<br>
<br>
        - With non-POSIX systems, or applications that don't<br>
          drop privs, the openat(2) is not needed, and one<br>
          just checks the cert chain periodically.<br>
<br>
        - Another option is to use passphrase-protected keys,<br>
          and load the secret passphrase at process start from<br>
          a separate read-protected file, while the actual<br>
          private key + cert chain file is world readable,<br>
          with the access control via protecting the passphrase<br>
          file.<br>
<br>
        - In all cases, it is important to keep both the private<br>
          key and the cert in the same file, and open it just<br>
          once to read both, avoiding races in which the key<br>
          and cert are read in a way that results in one or<br>
          the other being stale.<br>
<br>
    2.  Having somehow obtained a new key + cert chain, one<br>
        now wants to non-disruptively apply them to running<br>
        servers.  Here there are two potential approaches:<br>
<br>
        - Hot plug a new pointer into an existing SSL_CTX structure.<br>
          While the update itself could be made atomic, the readers<br>
          of such pointers might read them more than once to separately<br>
          extract the key and the cert chain, without checking that<br>
          they're using the same pointer for both operations.<br>
<br>
          This is bound to be fragile, though not necessarily<br>
          impossible.<br>
<br>
        - Build a new SSL_CTX, and use it to accept *new* connections,<br>
          while existing connections use whatever SSL_CTX they started<br>
          with.  I believe this can work well, because "SSL" handles<br>
          increment the reference count of the associated SSL_CTX<br>
          when they're created, and decrement it when destroyed.<br>
<br>
          So when you create a replacement SSL_CTX, you can just<br>
          SSL_CTX_free() the old, and it will only actually<br>
          be deleted when the last SSL connection tied to that<br>
          SSL_CTX is destroyed.<br>
<br>
          It is true that typical SSL_CTX construction is modestly<br>
          expensive (loading CA stores and the like) but some of<br>
          that could be handled by sharing and reference-counting<br>
          the stores.<br>
<br>
So my preferred approach would be to create a new SSL_CTX, and get new<br>
connections using that.  Now in a multi-threaded server, it could be a<br>
bit tricky to ensure that the SSL_CTX_free() does not happen before all<br>
threads reading the pointer to the latest SSL_CTX see the new pointer<br>
installed.  Something equivalent to RCU may be needed to ensure that the<br>
free only happens after the new pointer is visible in all threads.<br>
<br>
Designs addressing various parts of this would be cool, provided they're<br>
well thought out, and not just single-use-case quick hacks.<br>
<br>
-- <br>
    Viktor.<br>
</blockquote></div></div></div>
</blockquote></div>