繁体   English   中英

在C#中对GRPC的TLS支持

[英]TLS support for GRPC in C#

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

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

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

代码的重要部分在下面,也可以在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<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计算机上无法运行? 有什么方法可以调试问题以弄清楚是怎么回事?

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

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

  • CLIENT-COMPUTERNAME/CN (通用名称)添加CLIENT-COMPUTERNAME环境变量定义
  • 添加-config选项以摆脱unable to find 'distinguished_name' in config错误中unable to find 'distinguished_name' in config (在Windows上可能是openssl)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM