使用证书和私有RSA密钥

时间:2017-07-13 20:18:04

标签: c# .net elasticsearch nest client-certificates

所以我一直在构建一个后端工作来收集来自给定ElasticSearch集群的信息,现在我的问题是我不确定如何初始化ElasticClient,以便我可以访问只读方法,例如" client。 CatIndices()"

我已经阅读了这段时间的Nest文档, (https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/working-with-certificates.html)但老实说,我仍然不确定如何在我的具体情况下这样做。我知道我试图访问的Uri需要证书验证,我在本地文件中有这些密钥和密码,但我仍然不确定如何在ElasticClient对象中实例化它们。

基本上我的问题是我该怎么做:

var node = new Uri("(my uri)");

var settings = new ConnectionSettings(node);

//settings.ClientCertificate(new X509Certificate("filepath"); ???
var client = new ElasticClient((whatever args I need));

能够执行:

var result = client.CatIndices();

我在.net核心1.1上运行。非常感谢任何帮助,谢谢!

编辑:

通过将客户端证书文件和相应的client-key.pem组合到一个pfx文件中,我在此问题上取得了一些进展 Openssl运行:

openssl pkcs12 -export -out merged-cert-and-key.pfx -in client.pem -inkey client-key.pem

然后我用这个新的输出文件创建了一个新的X509Certificate2。接下来,我将证书添加到connection_settings.ClientCertificate属性/方法,该属性/方法应使用此证书密钥对验证所有请求(这是我想要发生的)

我还设置了connection_settings.servercertificatevalidationcallback属性,以便始终返回true(现在绕过CA证书验证要求):     settings.ServerCertificateValidationCallback((sender,cert,chain,errors)=> true);

现在,只需执行:     var x = client.Ping();

以下是我得到的回复(x.debugInformation)......

调试信息:
由HEAD上的不成功低级别调用构建的无效NEST响应:/

此API调用的审计跟踪:

  • [1] BadResponse:节点:" 我的URI节点"异常:PipelineException Took:00:00:00.5747770

    OriginalException:Elasticsearch.Net.ElasticsearchClientException:发生一个或多个错误。 (无法通过指定节点进行身份验证。请尝试验证您的凭据或检查您的Shield配置。)---> System.AggregateException:发生一个或多个错误。 (无法通过指定节点进行身份验证。请尝试验证您的凭据或检查您的Shield配置。)---> Elasticsearch.Net.PipelineException:无法使用指定的节点进行身份验证。尝试验证您的凭据或检查您的Shield配置。

    在Elasticsearch.Net.RequestPipeline.ThrowBadAuthPipelineExceptionWhenNeeded(IApiCallDetails响应) 在Elasticsearch.Net.RequestPipeline.CallElasticsearch [TReturn](RequestData requestData) 在Elasticsearch.Net.Transport 1.Request[TReturn](HttpMethod method, String path, PostData 1个数据,IRequestParameters requestParameters) ---内部异常堆栈跟踪结束--- ---内部异常堆栈跟踪结束---

    步骤1中的审核异常BadResponse:

Elasticsearch.Net.PipelineException:无法使用指定的节点进行身份验证。尝试验证您的凭据或检查您的Shield配置。    在Elasticsearch.Net.RequestPipeline.ThrowBadAuthPipelineExceptionWhenNeeded(IApiCallDetails响应)    在Elasticsearch.Net.RequestPipeline.CallElasticsearch [TReturn](RequestData requestData)    在Elasticsearch.Net.Transport 1.Request[TReturn](HttpMethod method, String path, PostData 1个数据,IRequestParameters requestParameters)

请求:

响应:

编辑2:

有趣的是,我在client.Ping()的响应中显示的错误消息实际上与我从client.CatIndices()的response.debugInformation获得的错误消息不同。

CatIndices的此错误消息显示为:

调试信息:在GET上对不成功的低级别调用构建的无效NEST响应:/ _cat / indices

此API调用的审计跟踪:

  • [1] BadResponse:节点:我的URI(省略)例外:PipelineException Took:00:00:00.7875970

    ServerError:ServerError:401Type:security_exception原因:"缺少REST请求的身份验证令牌[/ _cat / indices]"

OriginalException:Elasticsearch.Net.ElasticsearchClientException:发生一个或多个错误。 (无法通过指定节点进行身份验证。请尝试验证您的凭据或检查您的Shield配置。)---> System.AggregateException:发生一个或多个错误。 (无法通过指定节点进行身份验证。请尝试验证您的凭据或检查您的Shield配置。)---> Elasticsearch.Net.PipelineException:无法使用指定的节点进行身份验证。尝试验证您的凭据或检查您的Shield配置。

在Elasticsearch.Net.RequestPipeline.ThrowBadAuthPipelineExceptionWhenNeeded(IApiCallDetails响应)    在Elasticsearch.Net.RequestPipeline.CallElasticsearch [TReturn](RequestData requestData)    在Elasticsearch.Net.Transport 1.Request[TReturn](HttpMethod method, String path, PostData 1个数据,IRequestParameters requestParameters)    ---内部异常堆栈跟踪结束---    ---内部异常堆栈跟踪结束---

步骤1中的审核异常BadResponse:

Elasticsearch.Net.PipelineException:无法使用指定的节点进行身份验证。尝试验证您的凭据或检查您的Shield配置。    在Elasticsearch.Net.RequestPipeline.ThrowBadAuthPipelineExceptionWhenNeeded(IApiCallDetails响应)    在Elasticsearch.Net.RequestPipeline.CallElasticsearch [TReturn](RequestData requestData)    在Elasticsearch.Net.Transport 1.Request[TReturn](HttpMethod method, String path, PostData 1个数据,IRequestParameters requestParameters)

请求:

响应:

{"错误" {" ROOT_CAUSE":[{"类型":" security_exception""理由&#34 ;:"缺少REST请求的身份验证令牌[/ _cat / indices]"," header":{" WWW-Authenticate":" Basic realm = \"安全\"字符集= \" UTF-8 \""}}],"类型":" security_exception""理由&#34 ;: "缺少REST请求的身份验证令牌[/ _cat / indices]"," header":{" WWW-Authenticate":" Basic realm = \ "安全\"字符集= \" UTF-8 \""}},"状态":401}

我不确定这些附加信息是否有帮助,但值得一提的是,我真正关心的唯一响应是client.CatIndices(),而不是client.Ping()。我只是假设Ping需要与CatIndices相同的节点认证,因此可以互换用于测试目的。

编辑3:

我回溯并尝试使用相同的pfx证书在我的ElasticSearch uri和HttpClient之间建立一个基本的HttpConnection。我实际上成功地在_cat / indices上发出了我的请求,这告诉我这里的问题是NEST ElasticClient实际上并没有验证/验证我在弹性搜索uri上添加的pfx证书!这可能表明当使用客户端证书时,当前的NEST版本存在一些错误。

这有点让人失望,因为我很遗憾已经完成了我的指定工作,假设我可以访问NEST图书馆提供给我的客户的CatIndices响应......哦,好吧!

编辑4: 我解决这个问题的方法是创建一个HttpClient和HttpClientHandler的实例,然后手动传递我原本打算运行的CAT查询&#34; / _ cat / indices?format = json&amp; pretty&#34;。< / p>

步骤1:我初始化了httpclienthandler并修改了某些属性......

pfxCert = new X509Certificate2(_pfxCertFileName);//where the pfx file is the combined client cert and private rsa key from the openssl command I mentioned earlier


HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
clientHandler.SslProtocols = SslProtocols.Tls12;
clientHandler.ServerCertificateCustomValidationCallback = delegate {return true;};
clientHandler.ClientCertificates.Add(pfxCert);

client = new HttpClient(clientHandler);

步骤2:现在客户端已经完成了弹性搜索请求所需的全部内容,因此我创建了一个新的requestMessage并为我的查询定义了必要的字段......

var message = new HttpRequestMessage();
message.Method = System.Net.Http.HttpMethod.Get;
message.RequestUri = new Uri(uri + CAT_QUERY); //where uri is obviously my elasticsearch cluster and the query is the /_cat/indices

通过让客户端发送消息来获取响应......这是最终满足证书危机的工作!!

var resp = client.SendAsync(message).GetAwaiter().GetResult();

string jsonIWanted = resp.Content.ReadAsStringAsync().GetAwaiter().GetResult();

附加信息--- 我尝试在.net核心版本1.1.0上使用NEST库,在Mac OS X El Capitan v 10.11.6上运行(由于我已经在docker中构建和运行程序,这不应该太重要了), docker community edition v 17.03.1-ce-mac12,NEST和Elasticsearch.net版本5.4.0

我尝试将证书添加到NEST中的客户端的方式与我使用HttpClient的方式类似...

X509Certificate2 pfxCert= new X509Certificate2(pfxFileName);//Same as loading pfx file before  

var node = new Uri(myURI); //same as before
var settings = new ConnectionSettings(node);

settings.ClientCertificate(pfxCert);//I tried loading this pfx in many other ways than just this, this just happens to be what remains in my sandbox code where I was troubleshooting this


settings.ServerCertificateValidationCallback( 
CertificateValidations.AllowAll);
ElasticClient  client = new ElasticClient(settings);

然后我尝试按照我之前在编辑中提到的那些客户端调用给出了那些调试消息...希望这可以帮助那些想要进一步研究这个用例的人!

0 个答案:

没有答案