I wanted to give a elastic cloud a try today, but I can't seem to connect from c# app. Everything is working fine with locally deployed version but with cloud I'm always getting this error.
I deployed it to azure (free trial thing).
NEST client version is 7.14
.net 5.0
Error:
The client is unable to verify that the server is Elasticsearch due to an unsuccessful product check call. Some functionality may not be compatible if the server is running an unsupported product
Error2:
Authentication failed because the remote party sent a TLS alert: 'HandshakeFailure'.
this is how I'm setting up client
var cloudId = "cloudid:xxxxxxxx";
var credentials = new BasicAuthenticationCredentials("elastic", "xxxxxxxxxxxx");
var pool = new CloudConnectionPool(cloudId, credentials);
var settings = new ConnectionSettings(pool)
.ThrowExceptions()
.EnableDebugMode();
var client = new ElasticClient(settings);
Looks like an issue with OS, as I'm using Windows 11 Preview as same code is working on Ubuntu 20.04 and Windows server.
Related
I am writing a blazor server side application (.NET6) for my homeautomation and let it run on iis on a home server.
If I run the following code on my local machine in IIS Express everything works fine.
string _urlForecast = "https://api.openweathermap.org/data/2.5/forecast?id=...";
Uri myUri = new Uri(_urlForecast, UriKind.Absolute);
HttpResponseMessage response = await HttpClient.GetAsync(myUri);
var data = await response.Content.ReadAsStringAsync()
If I deploy it to my local homeserver and run it I get the following error:
System.Net.Http.HttpRequestException: No such host is known. (api.openweathermap.org:443)
My 'homeserver' is also running windows 10 and is in the same network as my dev pc.
It is in the same ip range and has the same DNS settings on the network adapter.
I also tried it with turned off firewall with the same result.
I am injecting the httpClient with DI but also tried without DI.
I tried to use http://api... and https://api... as my application is also available in the internal network via https. Unfortunately I have don't have any experience with Http requests and would be thankful if anybody could help.
I have an RDS instance running Postgres which has IAM Authentication enabled. I can successfully connect using an IAM token via powershell, but I'm having trouble with certificates when trying to connect using the Npgsql library with C# (targeting .Net Core 3.1) from Visual Studio 2019 Version 16.8.5 (on .Net Framework 4.8).
Note, I've been referencing this AWS page, which gives download links for the certificates.
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html
I've also been referencing this page to guide me through getting this set up.
https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-connect-using-iam/
I can connect with PowerShell, using:
$ENV:RDSHOST="my-postgres-instance.eu-west-1.rds.amazonaws.com"
$ENV:PGPASSWORD="$(aws rds generate-db-auth-token --hostname $ENV:RDSHOST --port 5432 --region eu-west-1 --username my_db_user)"
psql -h $ENV:RDSHOST -p 5432 "sslmode=verify-full sslrootcert=rds-ca-2019-root.pem dbname=my_db user=my_db_user password=$ENV:PGPASSWORD"
However when I try to open a connection with C# using the Npgsql library with the code below, I get an exception:
var host = "my-postgres-instance.eu-west-1.rds.amazonaws.com";
var port = 5432;
var user = "my_db_user";
var token = RDSAuthTokenGenerator.GenerateAuthToken(RegionEndpoint.EUWest1, host, port, user);
var builder = new NpgsqlConnectionStringBuilder
{
Host = host,
Port = port,
Database = "my_db",
Username = user,
Password = token,
SslMode = SslMode.Require,
RootCertificate = #"C:\Path\To\Cert\rds-combined-ca-bundle.pem",
};
using (var conn = new NpgsqlConnection(builder.ConnectionString))
{
conn.Open();
}
Npgsql.NpgsqlException: 'Exception while performing SSL handshake
AuthenticationException: The remote certificate is invalid according to the validation procedure.
It's worth noting that I can connect setting TrustServerCertificate = true, however as I understand it, this is masking the problem and reducing security, and is not advisable.
The AWS page linked above mentions:
If your application is on Microsoft Windows and requires a PKCS7 file, you can download the PKCS7 certificate bundle. This bundle contains both the intermediate and root certificates at https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.p7b.
I've tried specifying this p7b file as the NpgsqlConnectionStringBuilder.ClientCertificate, but this causes a different exception when opening the connection:
Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'Cannot find the original signer.'
Anyone able to help me understand how to connect? It's worth noting that I'm not very familiar with detting up SSL connections or dealing with certificates, so bear that in mind.
I have a .NET Core 3.1 C# application which is calling an API via HTTPS (and presenting its public key as part of getting the token as that certificate is later used to decrypt information sent back separately). On just about all our machines, it is working, but on one Windows 8.1 machine, we get the following series of exceptions when we try to initially connect for an authentication token:
The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> System.ComponentModel.Win32Exception (0x80090326): The message received was unexpected or badly formatted.
The exception is thrown from System.Net.Http.HttpClient.FinishSendAsyncBuffered so I suspect it is happening at the HTTPS level and our certificate stuff is not really relevant here anyway.
Our code to get the token looks like this:
The constructor for the auth service:
public XXXXAuthService(IXXDbService dbService, XXXXApiConfig config)
{
_dbService = dbService;
_config = config;
// try forcing TLS1.2 for SSL connection exceptions thrown in some operating environments
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
_httpClient = new HttpClient {BaseAddress = new Uri(config.BaseUrl)};
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
Code to get the auth token:
private async Task<string> GetXXXXBearerToken(string userId, DateTime creationTime)
{
var token = await GenerateProviderJwtForXXXX(userId, creationTime);
var kvp = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"),
new KeyValuePair<string, string>("subject_token", token),
new KeyValuePair<string, string>("subject_token_type", "urn:ietf:params:oauth:token-type:jwt")
};
var data = new FormUrlEncodedContent(kvp);
var publicKey = await GetXXXXPublicKey();
_httpClient.DefaultRequestHeaders.Remove("X-XXXX-Public-Cert");
_httpClient.DefaultRequestHeaders.Add("X-XXXX-Public-Cert", publicKey);
var response = await _httpClient.PostAsync("Identity/token", data);
if (!response.IsSuccessStatusCode)
throw new Exception("XXXX Token Server Error: " + response.ReasonPhrase);
var result = await response.Content.ReadAsStringAsync();
var authResponse = JsonConvert.DeserializeObject<OAuthResponse>(result);
if (!string.IsNullOrEmpty(authResponse.access_token))
return authResponse.access_token;
System.Diagnostics.Trace.WriteLine("Token Exchange Result: " + result);
if (!string.IsNullOrEmpty(authResponse.error))
{
var outcome = new XXX.XXXX.Model.OperationOutcome();
outcome.Issue.Add(new XXX.XXXX.Model.OperationOutcome.IssueComponent()
{
//some code to throw an error is here
}
throw new XXX.XXXX.Rest.XXXXOperationException("Bearer Token Exchange failed", response.StatusCode);
}
Unfortunately none of the existing questions/advice anywhere on Stack Overflow, or the rest of the web, for this particular error seems to have helped. They are primarily about version discrepancies between client and server which seems not to be the case here as I am forcing TLS 1.2 (which is active and enabled on the failing machine).
Interestingly, I can visit the server URL in a browser via HTTPS just fine, which suggests there is something about my code that is the problem rather than the machine, but it works everywhere else.
I have confirmed that:
The certificate I am using to authenticate the connection on the machine is valid and has a chain of trust (though as above I don't think we are getting that far as the TLS connection itself is failing)
The server we are calling supports TLS 1.2 (by forcing it)
I can get to the website for the URL independently via the browser
Is there something I need to do either in the code or on the machine to get this call to work everywhere?
Things I have tried to resolve the issue
Installing all Windows 8.1 updates to present day
Forcing TLS 1.2 in the code (see above code sample)
Limiting VM to TLS 1.2 only
I might be able to at least point you in the right direction…
Same Symptoms
I had a .NET Core 3.1 web app running on IIS (Windows Server 2012 R2) that got the exact same error and stacktrace when it tried to connect to another server using TLS 1.2. I also had the symptom where I could connect with the browser (Chrome), but not with the app. (Would have been interesting to see if Internet Explorer browser worked though.)
Root Cause
The TLS handshake was failing because the two servers were unable to agree on a common cipher suite. (Using Wireshark, I discovered that when my app tried to connect it provided a more limited set of cipher suites than when the Chrome browser made the call.)
Solution
In my case, I used IIS Crypto (a small free tool: https://www.nartac.com/Products/IISCrypto/) to enable additional cipher suites on my web app's server. I downloaded and ran IIS Crypto, checkmarked additional cipher suites on its Cipher Suites tab, and then restarted the machine.
One of the new cipher suites worked with my app and the destination server, so the TLS handshake was successful and the error was resolved.
One quick caveat: Some cipher suites are more secure than others, so you'll want to read up on best practices.
Addendum
If you want to further diagnose the failure, I'd recommend installing Wireshark (another free tool: https://www.wireshark.org/#download) on the machine with your .NET Core app. If a TLS Handshake Failure is the issue, you will see a message like: Alert (Level: Fatal, Description: Handshake Failure)
This primer on wireshark output helped me:
https://blog.catchpoint.com/2017/05/12/dissecting-tls-using-wireshark/
I faced a simular issue, and in order to help others here's what I concluded:
Sucessfully executing this code doesn't mean that your application supports the specified protocol version, and the "SSL Error" can still occur later on when trying to establish a connection:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
In my case I was trying to force Tls13 and found out that my app configuration didn't actually support it:
net core 3.0 running on a Windows Server Datacenter 2019, version 1809
So I had to change my configuration to the following which provides support for the protocol version I needed:
Net framework 5.0 on a Windows Server Datacenter 2022, OS build 20348.288
I was trying to connect to an endpoint that suddenly dropped Tls 1.2 support (not sure why) and from then on only accepted Tls 1.3.
My setup is similar to this SO post
My ASP.NET Web App connects to a third party service which requires client certificates. Begin a multitenant application, I've a client certificate for each customer, stored inside a database. Skipping the code to retrieve the certificate from database, I do something like this:
HttpClientHandler httpClientHandler = new HttpClientHandler();
X509Certificate2 customerCertificate = new X509Certificate2(certificateFromDatabase, "", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
httpClientHandler.ClientCertificates.Add(customerCertificate);
httpClientHandler.ServerCertificateCustomValidationCallback += ServerCertificateValidationCallback;
httpClient = new HttpClient(httpClientHandler);
This code works flawlessly on my Windows 10 development PC.
When published to an Azure Web App it fails 20% of time with the following error:
System.Net.Http.HttpRequestException: An error occurred while sending the request. System.Net.Http.WinHttpException: The client certificate credentials were not recognized.
I've written a test method which calls the third party service as fast as it can, switching certificate every time. This one works on my PC, and fails 80% of times on Azure (same error as above).
The solution proposed on the SO post above does not apply to me: I should have to load hundreads of certificates.
To troubleshoot the issue it could be usefull to execute a packet capture.
But, AFAIK, this is not possibile with Azure Web Apps (can be done with Virtual Machines and Network Watcher).
I'm using Amazon .NET SDK, and adding file from my ASP.NET MVC app is working fine from my dev machine, when I`m deploying the app (on AppHarbor) I get the following error:
Could not establish trust relationship for the SSL/TLS secure channel.
Here is the code I`m using:
var config = new Amazon.S3.AmazonS3Config();
config.CommunicationProtocol = Amazon.S3.Model.Protocol.HTTPS;
using (var client = Amazon.AWSClientFactory.CreateAmazonS3Client("key", "secret", config))
{
var putRequest = new Amazon.S3.Model.PutObjectRequest();
putRequest.BucketName = "media.bunkerapp.com";
putRequest.CannedACL = Amazon.S3.Model.S3CannedACL.PublicRead;
putRequest.ContentType = file.ContentType;
putRequest.InputStream = file.InputStream;
putRequest.Key = "mykey";
Amazon.S3.Model.S3Response response = client.PutObject(putRequest);
response.Dispose();
}
I know that EU bucket cannot contains ., as seen on this question but I'm using a US Standard bucket. And again, the issue here is that it's not working on AppHarbor. I tried to roll-back to a 1 instance app, but it throw the same error, here is the stack trace:
at Amazon.S3.AmazonS3Client.ProcessRequestError(String actionName, HttpWebRequest request, WebException we, HttpWebResponse errorResponse, String requestAddr, WebHeaderCollection& respHdrs, Type t)
at Amazon.S3.AmazonS3Client.Invoke[T](S3Request userRequest)
at Amazon.S3.AmazonS3Client.PutObject(PutObjectRequest request)
at MyController...
Any pointer would be greatly appreciated.
I can't reproduce this issue locally or on AppHarbor. I'm using similar code, bucket name (in US) and the newest AWS SDK.
I tried downgrading to version 1.3.4.1 and got an error similar to the one you describe ("The remote certificate is invalid according to the validation procedure").
Upgrading to the newest version of the AWS SDK for .NET (currently 1.4.3.0) may be the solution.