Support for Opportunistic TLS for Netty Server Builder #11117
Labels
enhancement
Waiting on reporter
there was a request for more information without a response or answer or advice has been provided
Is your feature request related to a problem?
Opportunistic TLS is a really useful feature for RPC servers because it eases the process of mass migrations/ upgrading plaintext traffic to TLS by temporarily allowing both Plaintext and TLS traffic on the same port. This feature is supported in Netty in two separate ways:
Unfortunately, we're unable to properly take advantage of either of these in gRPC
ServerTlsHandler#handlerAdded
always sets startTls to false, regardless of the value on thesslContext
it's passed. This has two consequences: (a) if usingServerCredentials
for TLS configuration, there is absolutely no way of settingstartTls
to true, and (b) if usingNettyServerBuilder#sslContext
for TLS configuration, you may setstartTls
to true on your context, but that value is not propagated to your configuration.NettyServerCredentials
advertise full control over the security handshake, so theoretically this (or rather the publicInternalNettyServerCredentials
) can be used to drop in theOptionalSslHandler
, but this, too has some issues: (a)InternalNettyServerCredentials
usage is discouraged outside of grpc internal, (b) Ideally, we would want all the behavior we get when using native settings (i.e. both Plaintext and TLS traffic haveGrpcNegotiationHandler
andWaitUntilActiveHandler
in their channel pipelines, both of which are package private or access and modify private members, likeProtocolNegotiationEvent
attributes, so they cannot be used directly nor copy-pasted).Describe the solution you'd like
We would specifically like to add support for the second option, the
OptionalSslHandler
(though the first should be pretty easy to add support for in gRPC, the latter just works a little better for our needs in that we don't need to update our clients /servers to send starttls requests/responses). The proposed changes include:TlsServerCredentials
to have anopportunistic
boolean on the class, which can be configured in viaTlsServerCredentials.newBuilder().opportunistic(true);
. For SslContext, this can be done via an overloaded sslContext method on NettyServerBuilder (defaults tofalse
if not supplied s.t. this is not a breaking change):NettyServerBuilder.forPort(8662).sslContext(sslContext, opptls)
(startTls is private on the sslContext, and therefore cannot be grabbed directly from there without changes to Netty)opportunistic
is true,ProtocolNegotiator#newHandler()
will add aServerOpportunisticTlsHandler
instead of the existingServerTlsHandler
; these will differ only in that the former adds anOptionalSslHandler
to the pipeline instead of a traditionalSslHandler
We have a (rough) proof of concept here that includes a few other implementation details (e.g. the
CustomOptionalSslHandler
instead of using the Netty one directly). Happy to clean this up and submit it to you folks formally, but want to get a feel for whether this is an approach you folks would be open to before doing so.Describe alternatives you've considered
One alternative would be to make some of the pieces we'd need to reuse public, specifically
NettyServerCredentials
(or else we can use the Internal one),GrpcNegotiationHandler
andWaitUntilActiveHandler
. We'd be able to use this on the client side as well to plug inNettyClientCredentials
with custom ProtocolNegotiator (which on the client side is at least slightly better for us). We're not at all opposed to this approach!The text was updated successfully, but these errors were encountered: