I'm trying to run the official "Hello, World" example with TLS, provided by the gRPC team (code on GitHub).
I've cloned the official repo and checked out tag v1.15.0
.
I've run the installation script as follows (as shown in the documentation):
./gradlew installDist
I've edited the launch scripts for hello-world-server
and hello-world-client
to run the classes io.grpc.examples.helloworldtls.HelloWorldServerTls
and io.grpc.examples.helloworldtls.HelloWorldClientTls
respectively.
I've created the certificates needed for the TLS authentication to happen using the script provided as part of the documentation and stored them in a directory I named cert
.
Finally, I've run the server as follows:
./build/install/examples/bin/hello-world-server localhost 50440 cert/server.crt cert/server.pem
The server starts correctly and outputs the following:
Oct 08, 2018 9:15:10 AM io.grpc.examples.helloworldtls.HelloWorldServerTls start
INFO: Server started, listening on 50440
Finally, I try to start the client on another shell with the following command:
./build/install/examples/bin/hello-world-client localhost 50440 cert/ca.crt
Unfortunately, the client fails with the following output:
Oct 08, 2018 9:25:22 AM io.grpc.examples.helloworldtls.HelloWorldClientTls greet
INFO: Will try to greet localhost ...
Oct 08, 2018 9:25:22 AM io.grpc.examples.helloworldtls.HelloWorldClientTls greet
WARNING: RPC failed: Status{code=UNKNOWN, description=channel closed, cause=java.nio.channels.ClosedChannelException
at io.grpc.netty.Utils.statusFromThrowable(Utils.java:169)
at io.grpc.netty.NettyClientTransport$5.operationComplete(NettyClientTransport.java:260)
at io.grpc.netty.NettyClientTransport$5.operationComplete(NettyClientTransport.java:254)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:485)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424)
at io.netty.util.concurrent.DefaultPromise.setFailure(DefaultPromise.java:112)
at io.netty.channel.DefaultChannelPromise.setFailure(DefaultChannelPromise.java:89)
at io.grpc.netty.ProtocolNegotiators$AbstractBufferingHandler.fail(ProtocolNegotiators.java:564)
at io.grpc.netty.ProtocolNegotiators$BufferUntilTlsNegotiatedHandler.userEventTriggered(ProtocolNegotiators.java:661)
at io.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:329)
at io.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:315)
at io.netty.channel.AbstractChannelHandlerContext.fireUserEventTriggered(AbstractChannelHandlerContext.java:307)
at io.netty.handler.ssl.SslUtils.handleHandshakeFailure(SslUtils.java:318)
at io.netty.handler.ssl.SslHandler.setHandshakeFailure(SslHandler.java:1551)
at io.netty.handler.ssl.SslHandler.channelInactive(SslHandler.java:1023)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1429)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:947)
at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:822)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.nio.channels.ClosedChannelException
at io.netty.handler.ssl.SslHandler.channelInactive(...)(Unknown Source)
}
The error occurs with mutual authentication as well.
I'm not sure what's going wrong or how to find the root cause of this, do you have any pointers?
As it turns out, I was using incompatible versions of gRPC and BoringSSL.
The "Troubleshooting" section of this document contains a table with known compatible versions of the library.
The following is a table with known compatible versions as of October 2018:
grpc-netty version | netty-handler version | netty-tcnative-boringssl-static version
------------------ | --------------------- | ---------------------------------------
1.0.0-1.0.1 | 4.1.3.Final | 1.1.33.Fork19
1.0.2-1.0.3 | 4.1.6.Final | 1.1.33.Fork23
1.1.x-1.3.x | 4.1.8.Final | 1.1.33.Fork26
1.4.x | 4.1.11.Final | 2.0.1.Final
1.5.x | 4.1.12.Final | 2.0.5.Final
1.6.x | 4.1.14.Final | 2.0.5.Final
1.7.x-1.8.x | 4.1.16.Final | 2.0.6.Final
1.9.x-1.10.x | 4.1.17.Final | 2.0.7.Final
1.11.x-1.12.x | 4.1.22.Final | 2.0.7.Final
1.13.x | 4.1.25.Final | 2.0.8.Final
1.14.x- | 4.1.27.Final | 2.0.12.Final