-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Mark,
On 12/6/16 4:17 AM, Mark Thomas wrote: > On 05/12/2016 23:03, Christopher Schultz wrote: >> Mark, >> >> On 12/4/16 3:24 PM, Mark Thomas wrote: >>>>>> It looks like the ProtocolHandler is really the place >>>>>> where the TLS configuration is taking effect, and not >>>>>> the Connector, so I'm largely ignoring the Connector for >>>>>> now. Is that the right choice to make, here? >> >>> It depends. What you actually need to do is swap out the >>> SSLContext. This is in the SSLHostConfigCertificate. >> >> It looks like the only place the SSLContext is actually set is >> from Nio(2?)Endpoint.bind(). So that means that, with the current >> Tomcat implementation, changing the SSLContext means an unbind() >> followed by a bind(). Do I have that correct? > > Yes. With changes to the Tomcat code, that answer can obviously change. >> This would be for JSSE only... for OpenSSL/APR, I suspect it will >> be the same thing, but any change would have to take both into >> account. >> >> What I'd really like to be able to do is replace the SSLContext >> without dropping any in-flight requests, while new requests wait >> to be serviced until the new configuration was available. >> Something like this: >> >> 1. Stop processing incoming connections (e.g. still accept(), >> but don't handshake, yet... or at least stay bound to the port, >> but don't yet accept() and allow the TCP stack backlog to queue >> incoming connections) >> >> 2. Load the new TLS configuration >> >> 3. Resume accepting connections with the updated TLS >> configuration >> >> 4. Requests accepted before step #1 continue to use the >> configuration effective at the time >> >> I'm not sure how all that squares with that JSSE is willing to >> do. > > It should be as simple as: > > 1. Construct a new SSLContext > > 2. Replace the old SSLContext with the new one. So if there were a reloadTLSConfiguration method on the Connector (or similar component), it could simply call setSSLContext() on the SSLHostConfigCertificate and wait for the next request to come in? > It gets slightly trickier with APR/native as you need to > explicitly clean up the old one and you can't do that until all the > connections using it have closed. JSSE doesn't have that > requirement. Understood. I'm focusing on JSSE for the moment. I also understand that e.g. websocket makes this even more fun, since the connections are expected to be relatively long-lived. >> Once the TLS handshake occurs, presumably it means that the >> connection will continue to be valid until it's closed. If a >> connection as mentioned in #4 above is long-running, the old >> SSLContext etc. will be GC'd after the connection finally closes. >> If that assumption is not correct, I don't think any of the above >> is even possible. >> >> What probably is possible is pausing all incoming connections, >> waiting X ms for them to complete, then unbind(), then bind(). >> Client observation would be that the service seems to stall, then >> fail. Presumably, immediately re-trying would connect and get the >> new configuration. >> >> How difficult do you think it would be to implement such a >> "graceful" shutdown of the connector? It would be the same as >> "stop" except that it would first allow all in-flight requests to >> complete (with some reasonable timeout... say, as specified by a >> parameter to a gracefulShutdown(int) call?) and then, in the case >> of the bindOnInit="false", it would unbind(). > > I think that is the wrong approach. Just leave everything running > and just replace the SSLContext on the fly. With the caveat that > APR/native is a little trickier. We might need to add usage > counting or similar. Cool. >> That would allow a JMX client to say "shut down gracefully", >> waiting for an OK response (which would indicate that the >> connector had in fact shut down), then immediately request a >> "start" and the connector would come back up. At this point, I'd >> probably argue that we should add a "restart gracefully" to the >> list of JMX-callable actions which just does both of those calls >> on the server without a second HTTP roundtrip from the JMX >> client. > > I think what we need is a refreshTLSConfig() method. Perfect. If such a method were to be on the Connector (at least for the JMX bean representing the Connector), it looks like a fairly simple call (or calls.. for each SSLHostConfig) to AbstractEndpoint.createSSLContext would do the trick. That method seems to not only create the SSLContext but also set that new context on the certificate (SSLHostConfigCertificate) object. I think there might be some thread-safety issues though with the changing configuration of e.g. sslHostConfig.enabledProtocols and sslHostConfig.enabledCiphers before the certificate is updated. As it stands, the code seems to expect that, once initialized, no later re-initializations occur. We'd need to make sure that we swap-out that configuration in an atomic way. The SSLContext is built separately and dropped-onto the certificate object. Finally, even for JSSE, there is a releaseSSLContext() that looks like it should probably be called[1]. So I think for both OpenSSL and JSSE, we'd want to use the same technique. Something like a list of currently in-use SSLContext objects (it should be fairly limited) and when one of them drops-out of the "in-use" list, we properly-dispose of it. That essentially requires reference-counting around connection-management: check-out an SSLContext and then release it afterward. The last release for a shutting-down SSLContext will release that context. Does that sound ... overly complicated or foolish? I'm sensitive to the fact that there will be a performance impact for something like this . WDYT? - -chris [1] After a little more reading, I see that the JSSESSLContext has a no-op implementation of destroy(). So we could be a bit lazy for a first implementation. -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJYRuZ3AAoJEBzwKT+lPKRYejAQALVcIPIXbGOQFxantDBoLgzS +BVZ6ltmRgCihLrQWUunryKr0M0fI5YhhuW72mj2oMidddXjdZubNora2YdMZzAa RppkKTBmSB6sTRGs+DnI5KkbKRFeoidOHW/fWal8A7+vhWghs/wQA+eyxXKTnxBs bEAs8fFoOe83bAU9+NsVv0ROPniDJqajxWDFx/oISUlleucQyD0YKKUWlMpJztvQ tSY3C276Blm7Owbf9fNjEVxdo55+eQB+M06wfZIYmO3dtn80Euv0fbBJIdCZJSOc eKq346MOAR4xoLut6eFwAIYwmHNHL/CURLYtiq906VM/x10PBvFKgoypxr81BMIZ Em2LZ4q3F73kmF/BCxe0XDy1M1WJsiBdFed++m2nnVCqD8m4EQLeq83whA2JgePD XBqHHipeWaJ/omoV25+nAeTprZgpgILSrmjBss1zVGNaLpxw1lo4qqAC0ykEPTcD y/LsNpxWwegiOfjFO5SC7/Pjl6xwLlDlZfEaqQJj1POqs2wCub54IZgjJ5J0oDdE XBbH7lx4Pa4zFndRXEHuyho5rki+rlhcP/q5EcXJqMo/6t6X5uFBoUM1uTjt7Gzc XoolCSgMaJdrzzfGf/yUm5hZ5KtawgTPi6CFMw5f3DLpghXYByUUP22fkR28yCTk BwjVSIHnNBPQZ0qpuzHI =WG0O -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org