Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TLS support for GRPC in C#

Tags:

c#

grpc

I'm rather new to C#, and I need to use GRPC over TLS.

As a dry-run, I'm modifying the example provided in the main grpc repo to use TLS. To do this, I found another SO question with what seemed like a good answer: How to enable server side SSL for gRPC?. However, I get an error Unhandled Exception: Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Connect Failed") (full trace below).

I get the same error if I in the original, non-tls code, specify an incorrect port or just don't start the server. I'm using dotnet core on Ubuntu.

The important parts of the code are below, and also found in full on a fork on github.

Client:

  var cacert = File.ReadAllText(@"../ca.crt");
  var clientcert = File.ReadAllText(@"../client.crt");
  var clientkey = File.ReadAllText(@"../client.key");
  var ssl = new SslCredentials(cacert, new KeyCertificatePair(clientcert, clientkey));
  var channel = new Channel("localhost", 555, ssl);
  var client = new Greeter.GreeterClient(channel);

  String user = "you";

  var reply = client.SayHello(new HelloRequest {Name = user});
  Console.WriteLine("Greeting: " + reply.Message);

  channel.ShutdownAsync().Wait();
  Console.WriteLine("Press any key to exit...");
  Console.ReadKey();

Server:

  var cacert = File.ReadAllText(@"../ca.crt");
  var servercert = File.ReadAllText(@"../server.crt");
  var serverkey = File.ReadAllText(@"../server.key");
  var keypair = new KeyCertificatePair(servercert, serverkey);
  var sslCredentials = new SslServerCredentials(new List<KeyCertificatePair>() {keypair}, cacert, false);

  var server = new Server
  {
    Services = {Greeter.BindService(new GreeterImpl())},
    Ports = {new ServerPort("0.0.0.0", 555, sslCredentials)}
  };
  server.Start();


  Console.WriteLine("Greeter server listening on port " + Port);
  Console.WriteLine("Press any key to stop the server...");
  Console.ReadKey();

  server.ShutdownAsync().Wait();

Full output of the programs:

$ cd GreeterClient
$ dotnet run -f netcoreapp1.0

Unhandled Exception: Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Connect Failed")
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Grpc.Core.Internal.AsyncCall`2.UnaryCall(TRequest msg)
   at Grpc.Core.DefaultCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   at Grpc.Core.Internal.InterceptingCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   at Helloworld.Greeter.GreeterClient.SayHello(HelloRequest request, CallOptions options)
   at Helloworld.Greeter.GreeterClient.SayHello(HelloRequest request, Metadata headers, Nullable`1 deadline, CancellationToken cancellationToken)
   at GreeterClient.Program.Main(String[] args)

And server:

$ cd GreeterServer/
$ dotnet run -f netcoreapp1.0
Greeter server listening on port 50051
Press any key to stop the server...

Did I do some silly mistake, or does this not run on non-windows machines? Is there some way to debug the issue to figure out what is going on?

like image 356
Zut Avatar asked Nov 13 '17 19:11

Zut


People also ask

Does gRPC require TLS?

The gRPC client must also be configured to not use TLS. For more information, see Call insecure gRPC services with . NET Core client. HTTP/2 without TLS should only be used during app development.

What version of TLS does gRPC use?

SSL/TLS: gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, and to encrypt all the data exchanged between the client and the server.

Does gRPC support mTLS?

EOS supports the use of mutual TLS (mTLS) for gRPC, RESTCONF and eAPI services. This allows the use of certificates, signed by a recognized and trusted CA, for authentication to gNMI and other gRPC based services.


1 Answers

Your code is implementing Mutual TLS with self signed certs correctly - I was able to run it on windows netcore without any changes.

I did have to tweak the certificate generation script a little:

  • Adding environment variable definition for CLIENT-COMPUTERNAME, used for the client /CN (Common Name)
  • Adding a -config option to get rid of unable to find 'distinguished_name' in config error (might be a openssl on Windows thing)

I was able to reproduce the same error message that you had by deliberately mismatching the host that the client connects to (127.0.0.1 instead of localhost). So maybe you just need to regenerate your keys with e.g. localhost as the client's common name.

like image 103
Peter Wishart Avatar answered Oct 04 '22 08:10

Peter Wishart