2
votes

I work on a software application that uses gRPC to establish a bi-directional stream between client and a server.

I'm looking for something similar to this ticket's answer only in java: How to enable server side SSL for gRPC?

I would like to configure my application so that they can choose what TLS scenario they want to use:

Scenario 1: plaintext (no encryption)

Scenario 2: Server-side TLS

Scenario 3: Mutual TLS

For TLS setups, I am using Java on non-Android environments, so I will only be considering the OpenSSL installed scenario using https://github.com/grpc/grpc-java/blob/master/SECURITY.md#openssl-statically-linked-netty-tcnative-boringssl-static

Configuring the server side seems pretty straight forward because it is documented quite well: https://github.com/grpc/grpc-java/blob/master/SECURITY.md#mutual-tls

Here would be the steps for the corresponding TLS options:

Sever-side configuration for Scenario 1: Use builder.usePlaintext

Sever-side configuration for Scenario 2: Add a NettyServerBuilder.sslContext built by SSL Context Builder with GrpcSslContexts.forServer and set the cert chain and cert key (and password if needed)

Sever-side configuration for Scenario 3: Add a NettyServerBuilder.sslContext built by SSL Context Builder with GrpcSslContexts.forServer and set the cert chain and cert key (and password if needed), and also set a trustManager on the sslContextBuidler set to the trust cert file.

The server-side part is well documented which is excellent.

Now I want to configure a NettyChannelBuilder on the client side. The only thing I can find information on this is in this unit test: https://github.com/grpc/grpc-java/blob/master/interop-testing/src/test/java/io/grpc/testing/integration/TlsTest.java

Here are the configurations I think are needed, but need to get confirmation on.

Client-side configuration for Scenario 1: Use nettyChannelBuilder.usePlaintext(true). This will disable TLS on the netty channel to grpc.

Client-side configuration for Scenario 2: Set the sslContext using nettyChannelBuilder.negotiationType(NegotiationType.TLS).sslContext(GrpcSslContexts.configure(SslContextBuilder.forClient(), SslProvider.OPENSSL).build()). This will configure the channel to communicate through TLS to grpc server using the default ciphers and application protocol configs.

Client-side configuration for Scenario 3: Set up TLS for the netty channel using nettyChannelBuilder.negotiationType(NegotiationType.TLS).sslContext(GrpcSslContexts.configure(SslContextBuilder.forClient(), SslProvider.OPENSSL).sslContextBuilder.trustManager(clientAuthCertFile) .clientAuth(ClientAuth.OPTIONAL).build()) where clientAuthCertFile is the trust cert file and ClientAuth.OPTIONAL can also be ClientAuth.REQUIRED if you require mutual TLS.

Is there anything incorrect with my client-side configurations? Do I need any tweaks? I will add this as a PR to the security.md file after getting some blessing from the community on this post.

1

1 Answers

1
votes

I added a hello world TLS PR to the grpc-java project here https://github.com/grpc/grpc-java/pull/3992

the latest version of grpc-java as soon as this pr is merged will have a really nice working hello-world example. So all you have to do is git clone that project from master, and look at the example/README.md.