【问题标题】:Unable to establish https connection with gRPC无法与 gRPC 建立 https 连接
【发布时间】:2020-04-07 20:00:53
【问题描述】:

我的 gRPC 客户端/服务器代码使用 ChannelCredentials.Insecure 在我的本地机器上愉快地工作,但需要切换到安全模式。我不需要任何证书检查,只需要加密流量。 我一直找不到可以相互通信的客户端服务器的任何配置。 运行 c# 核心服务器 (gRPC 2.27.0) 和 c# .net 框架客户端 (gRPC 2.28.1)。

服务器说它在 http 和 https 上发布如下:

[20:12:58 DBG] Using development certificate: CN=localhost (Thumbprint: 3EDA2E5BD559D75C9DCF058E0A6994EED859CD34)
[20:12:58 INF] Now listening on: https://localhost:5001
[20:12:58 INF] Now listening on: http://localhost:5000

与客户合作:

 ChannelBase channel = new Channel("localhost:5000", ChannelCredentials.Insecure);
 var client = new MyApp.MyAppClient(channel);
 var response = client.Test(request)

如果我如下将客户端切换到 SslCredentials

 ChannelBase channel = new Channel("localhost:5001", new SslCredentials());
 var client = new MyApp.MyAppClient(channel);
 var response = client.Test(request)

我收到以下错误。

服务器错误

[19:32:53 DBG] Failed to authenticate HTTPS connection.
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
   at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest asyncRequest)

客户端错误

Grpc.Core.RpcException: 'Status(StatusCode=Unavailable, Detail="failed to connect to all addresses")'

我也尝试添加(服务器),但错误没有变化。

   services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
      .AddCertificate(options =>
      {
          options.RevocationMode = X509RevocationMode.NoCheck;
          options.ValidateCertificateUse = false;
          options.AllowedCertificateTypes = CertificateTypes.SelfSigned;
      });

关于我需要做什么来让他们说话的任何建议。

【问题讨论】:

  • 我找到了一种显示所有客户端 grpc 调试语句(GRPC_TRACE 和 GRPC_VERBOSITY)的方法 - 但只记录了放弃。需要为服务器找到类似的。

标签: c# grpc


【解决方案1】:

因此,在创建 SslCredentials 时,您需要指定与您在服务器上使用的开发证书相对应的 root.pem。

如果您使用无参数 SslCredentials(),它将使用默认信任根,该信任根仅适用于已由公开信任的证书颁发机构签名的证书(例如,如果您正在谈论“官方”服务器,例如 googleapis.com 等,您在服务器上使用的开发证书绝对不是这种情况)。所以你需要使用 SslCredentials(yourCustomTrustRootsPem)。

顺便说一句,使用 SSL/TLS,没有“无证书检查”之类的东西。客户端将始终检查它是否连接到正确的服务器(服务器的证书可通过其信任根进行验证) - 否则安全通信将毫无意义,因为它太容易受到中间人攻击。 (虽然服务器检查客户端的真实性是可选的)。

请随时参考https://github.com/jtattermusch/grpc-authentication-kubernetes-examples 以获取更多资源。

【讨论】:

    【解决方案2】:

    我也遇到过类似的问题,终于找到了一个解决办法,可以在两者之间建立HTTPs连接

    • .NET Framework 4.7.2 客户端(WPF 应用)和
    • ASP .NET Core 3.1 gRPC 服务器(控制台)。

    确实,Jan Tattermusch 的回答是正确的。您需要将服务器端证书作为 PEM 提供给 SslCredentials 的构造函数,此外,证书必须包含您通过其联系服务器的 URL 的 DNS 名称或 IP。在您的情况下,我建议为每个服务器手动创建一个自签名证书,而不是使用开发人员证书。这个可以由您的客户端下载,然后作为 SslCredentials 传递。像魅力一样工作。

    在此处对类似问题的回答中查看有关如何执行所有详细信息的更多详细信息:

    https://stackoverflow.com/a/63565090/378415

    【讨论】:

      【解决方案3】:

      尝试在部署后以任何方式检查 Grpc 服务在哪个端口上运行,无论是 windows 服务还是其他服务,然后在客户端中提供相同的服务以使用该服务。例如:如果您的服务在 https://localhost:5000 上运行,那么在客户端中给出相同的值。 它肯定会起作用。

      当你错误地把服务地址与客户端不匹配时,你会得到上面的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-04-25
        • 2020-04-06
        • 1970-01-01
        • 2018-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多