This took me some head scratching to figure out, so I thought I would post it here. We are using a reverse proxy where we send the request to 443 SSL port (load balanced in azure to three client nodes) using a cert to authenticate, then forward that to the local client node to scatter to the data nodes. The cert is self signed, and is in the local store (Current User > Personal) on the server housing our api. The thumbprint is in our web.config.
public class ConnectionWithCert : Elasticsearch.Net.HttpConnection
{
protected override HttpWebRequest CreateHttpWebRequest(RequestData requestData)
{
var handler = base.CreateHttpWebRequest(requestData);
string certThumbprint = System.Configuration.ConfigurationManager.AppSettings["ElasticsearchCertificateThumbprint"];
X509Certificate2 certificate =
GetCertificateByThumbprint(certThumbprint);
handler.ClientCertificates.Add(certificate);
return handler;
}
/// <summary>
/// Get the certificate using the certificate thumbprint
/// </summary>
/// <param name="certificateThumbprint">Thumbprint of certificate</param>
/// <returns>Certificate object</returns>
public static X509Certificate2 GetCertificateByThumbprint(string certificateThumbprint)
{
Ensure.ArgumentNotEmpty(certificateThumbprint, nameof(certificateThumbprint));
// Open the certificate store
X509Store certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
certificateStore.Open(OpenFlags.ReadOnly);
// Get the certificates
var matchingCertificates = certificateStore.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false);
if (matchingCertificates.Count == 0)
{
// No certificate found
return null;
}
else
{
// Return first certificate
return matchingCertificates[0];
}
}
}
Once I have this, I can set that on my connectionSettings in my helper class:
public ElasticSearchHelper(string elasticSearchUrl, OcvElasticSearchDataProvider dataProvider, int elasticSearchConflictRetryCount)
{
// Parameters
this.elasticSearchConflictRetryCount = elasticSearchConflictRetryCount;
this.dataProvider = dataProvider;
// Create the ElasticSearch client and configure
var node = new Uri(elasticSearchUrl);
var pool = new SingleNodeConnectionPool(node);
var settings = new ConnectionSettings(pool, new ConnectionWithCert());
this.client = new ElasticClient(settings);
}
Now all operations carried out through my helper have the client cert attached, and is granted access through my reverse proxy.