Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 为什么C#Google.Cloud.Firestore库无法连接到企业MITM防火墙?_.net_Ssl_Google Cloud Firestore_Firewall_Windows Server 2008 R2 - Fatal编程技术网

.net 为什么C#Google.Cloud.Firestore库无法连接到企业MITM防火墙?

.net 为什么C#Google.Cloud.Firestore库无法连接到企业MITM防火墙?,.net,ssl,google-cloud-firestore,firewall,windows-server-2008-r2,.net,Ssl,Google Cloud Firestore,Firewall,Windows Server 2008 R2,来自库的特定错误消息 CompletedListGrpc.Core.rpceException:状态(状态代码=不可用, Detail=“连接失败”) 我特别指的是这个图书馆: 我对google cloud firestore服务有一个特别的问题(尽管这个问题可能发生在另一个依赖库中,可能是身份验证) 问题中的防火墙是Palo Alto Networks。它有一个企业证书,安装在企业工作站上并受信任。防火墙实质上充当了一个MITM,用于解密流量,以便对TLS流量进行更深入的分析 当fires

来自库的特定错误消息

CompletedListGrpc.Core.rpceException:状态(状态代码=不可用, Detail=“连接失败”)

  • 我特别指的是这个图书馆:
  • 我对google cloud firestore服务有一个特别的问题(尽管这个问题可能发生在另一个依赖库中,可能是身份验证)
  • 问题中的防火墙是Palo Alto Networks。它有一个企业证书,安装在企业工作站上并受信任。防火墙实质上充当了一个MITM,用于解密流量,以便对TLS流量进行更深入的分析
当firestore.googleapis.com的防火墙MITM功能被禁用时,库正常工作。当启用MITM功能时,它不工作

子问题:

1) 库代码是否有硬编码证书检查?(我找不到)

见第550行

public static gaxgrpc::ServiceEndpoint DefaultEndpoint { get; } = new gaxgrpc::ServiceEndpoint("firestore.googleapis.com", 443);
  • 硬编码证书是没有意义的,因为证书会被更新,有时旧的证书会被撤销
  • grpc是相当标准的,除了谷歌(Google)使用之外,它还可以共享
  • 假设grpc不包含下游依赖项的显式证书是合理的
  • 如果firestore要断言一个证书,那么可以合理地假设这一行代码将与URL一起断言
2a).Net Framework是否自动信任windows信任存储中的证书?是否需要任何代码来实现此功能

.Net Framework似乎可以与Windows证书存储一起使用-请参阅

2b)可能证书只受信任,但受交互用户信任,而不受整个机器信任,因此服务帐户看不到该证书-我将对此进行检查


3) 如果这是导致“连接失败”的原因,库是否会有关于证书的特定错误?

可能是GRPC和Windows证书存储之间的问题。无论这是GRPC(而不是.Net)的一个根本问题,还是由于在不同的帐户下运行它,将防火墙的正确根CA硬编码到应用程序中肯定会让您完全控制

您可能能够覆盖DefaultEndpoint/通道以使用您自己的ServicePoint,该ServicePoint还包括硬编码证书

创建自己的端点,然后显式提供它,以便它覆盖DefaultEndpoint。这是您将使用频道调用的函数。(见附件)

另外,请仔细查看SslCredentialsTest代码-

注意:通常使用s_channelPool创建通道。如果您手动创建它,它可能不会使用池-可能没有办法做到这一点。这对你来说可能是个问题,也可能不是


您可以对此进行扩展,以便在运行时按名称从Windows证书存储中手动读取公共证书信息,并选择最新的。这意味着您可以使用app.config分配要从Windows证书存储获取的证书的CN,这样您就不需要手动发送软件的更新版本


此链接似乎表明默认情况下“公共受信任的根”是受信任的:

这意味着,尽管firestore没有“硬编码”特定的证书,但它通常不会与Windows证书存储集成,因此任何自定义安装的根CA都不受信任

更仔细地查看库源代码[:

公共频道GetChannel(ServiceEndpoint端点,IEnumerable频道选项) { GaxPreconditions.CheckNotNull(端点,nameof(端点)); var credentials=\u lazyScopedDefaultChannelCredentials.Value.ResultWithUnwrapedExceptions(); 返回GetChannel(端点、通道选项、凭据); } credentials参数是自动填充的,接下来是
\u lazyScopedDefaultChannelCredentials
GoogleCredential.GetApplicationDefaultAsync()
,我们最终到达了
CreateDefaultCredentialAsync
,它指向您可能从firebase某处下载的Google服务文件

注:


这个答案很有可能只会导致自定义客户端凭据,而不是能够拥有自定义服务器端根CA的硬编码凭据。

这可能是GRPC和Windows证书存储之间的问题。这是否是GRPC(而不是.Net)的根本问题或者,由于它是在不同的帐户下运行的,所以将防火墙的正确根CA硬编码到应用程序中肯定会让您完全控制

您可能能够覆盖DefaultEndpoint/通道以使用您自己的ServicePoint,该ServicePoint还包括硬编码证书

创建您自己的端点,然后显式提供它,以便它覆盖DefaultEndpoint。以下是您将使用通道调用的函数。(请参阅)

另外,请仔细查看SslCredentialsTest代码-

注意:通常会使用s_channelPool创建频道。如果您手动创建频道,它可能不会使用该池-可能没有办法这样做。这对您来说可能是问题,也可能不是问题


您可以对此进行扩展,以便在运行时按名称从Windows证书存储中手动读取公共证书信息,选择最新的。这意味着您可以使用app.config分配证书的CN以从Windows证书存储中获取,然后您将不需要手动发送更新版本的证书我们的软件


此链接似乎表明默认情况下“公共受信任的根”是受信任的:

这意味着,尽管firestore没有“硬编码”特定的证书,但它通常不会与Windows证书存储集成,因此
  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("firestore.googleapis.com", 443, ssl);
  //etc..
public static FirestoreClient Create(grpccore::Channel channel, FirestoreSettings settings = null)
{
    gax::GaxPreconditions.CheckNotNull(channel, nameof(channel));
    return Create(new grpccore::DefaultCallInvoker(channel), settings);
}
var channel = new Channel("greeter.googleapis.com", new SslCredentials());  // Use publicly trusted roots.
public Channel GetChannel(ServiceEndpoint endpoint, IEnumerable<ChannelOption> channelOptions)
{
    GaxPreconditions.CheckNotNull(endpoint, nameof(endpoint));
    var credentials = _lazyScopedDefaultChannelCredentials.Value.ResultWithUnwrappedExceptions();
    return GetChannel(endpoint, channelOptions, credentials);
}
ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;