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?
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.
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.
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.
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:
CLIENT-COMPUTERNAME
, used for the client /CN
(Common Name)-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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With