C#中对GRPC的TLS支持

我对C#很新,我需要在TLS上使用GRPC。

作为一个干运行,我正在修改主grpc仓库中提供的示例以使用TLS。 要做到这一点,我发现了另一个SO问题似乎是一个很好的答案: 如何为gRPC启用服务器端SSL? 。 但是,我得到一个错误Unhandled Exception: Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Connect Failed") (下面的完整跟踪)。

如果我在原始的非tls代码中指定了错误的端口或者只是不启动服务器,我会得到相同的错误。 我在Ubuntu上使用dotnet核心。

代码的重要部分如下所示,也可以在github上的fork中找到。

客户:

  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(); 

服务器:

  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() {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(); 

程序的完整输出:

 $ 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) 

和服务器:

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

我做了一些愚蠢的错误,还是不能在非Windows机器上运行? 有没有办法调试问题来弄清楚发生了什么?

您的代码正在使用自签名证书正确实现Mutual TLS – 我能够在Windows netcore上运行它而不做任何更改。

我确实需要稍微调整证书生成脚本:

  • CLIENT-COMPUTERNAME添加环境变量定义,用于客户端/CN (公用名)
  • 添加-config选项以摆脱unable to find 'distinguished_name' in config错误中unable to find 'distinguished_name' in config (可能是Windows上的openssl)

我能够重现与客户端连接的主机( 127.0.0.1而不是localhost )故意不匹配的错误消息。 所以,也许您只需要使用localhost作为客户端的通用名称来重新生成密钥。