【问题标题】:TLS support for GRPC in C#C# 中对 GRPC 的 TLS 支持
【发布时间】:2018-04-26 13:35:16
【问题描述】:

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

作为试运行,我正在修改main grpc repo 中提供的示例以使用 TLS。为此,我发现了另一个 SO 问题,答案似乎很好:How to enable server side SSL for gRPC?。但是,我收到一个错误Unhandled Exception: Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Connect Failed")(下面的完整跟踪)。

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

代码的重要部分如下,在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 机器上运行的?有什么方法可以调试问题以弄清楚发生了什么?

【问题讨论】:

    标签: c# grpc


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 是的,您要连接的主机的名称需要与客户端通道目标匹配(因此您可能需要重新生成证书以使其匹配)。您可以通过设置环境变量 GRPC_VERBOSITY=debug 启用更多日志记录来获得更多洞察力
    猜你喜欢
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多