本文介绍了在C#中对GRPC的TLS支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C#的新手,我需要在TLS上使用GRPC.

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

作为试运行,我将主grpc存储库中提供的示例修改为使用TLS.为此,我找到了另一个SO问题,似乎是一个很好的答案:如何为gRPC启用服务器端SSL?.但是,我得到一个错误Unhandled Exception: Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Connect Failed")(下面有完整的跟踪).

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

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

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.

下面是代码的重要部分,也可以在 github .

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

客户:

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

程序的完整输出:

$ 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计算机上运行?有什么方法可以调试问题以弄清楚是怎么回事?

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?

推荐答案

您的代码正在正确地实现带有自签名证书的Mutual TLS-我能够在Windows netcore上运行它而无需进行任何更改.

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:

  • 为客户端/CN(通用名称)使用的CLIENT-COMPUTERNAME添加环境变量定义
  • 添加-config选项以消除unable to find 'distinguished_name' in config错误(在Windows上可能是openssl)
  • 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)

通过故意不匹配客户端连接到的主机(127.0.0.1而不是localhost),我能够重现与您相同的错误消息.因此,也许您只需要使用例如重新生成密钥即可. localhost作为客户的通用名称.

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.

这篇关于在C#中对GRPC的TLS支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-29 13:33
查看更多