Why does kestrel keep throwing this debug ssl exception? - azure

I have a Service Fabric Setup and I have a microservice that registers on port 443 and uses https. I have a reverse proxy in my cluster setup. The reverse proxy is secured with a certificate.
I also use the same certificate when starting up my microservice:
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "EndpointHttps", (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel(x =>
{
int port = serviceContext.CodePackageActivationContext.GetEndpoint("EndpointHttps").Port;
x.Listen(IPAddress.IPv6Any, port, listenOptions =>
{
listenOptions.UseHttps(transportCertificate);
listenOptions.NoDelay = true;
});
})
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseEnvironment(environment)
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.UseSerilog(Logger.Serilog)
.Build();
}))
};
Everything seems to work fine and my site is secure in the browser and the api works. However my log is getting filled up with the following statements (these are just debug messages but they are filling up my log):
133649 Failed to authenticate HTTPS connection. Debug System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
133643 Connection id ""0HLPCETMP8DKM"" started. key='SourceContext'>Microsoft.AspNetCore.Server.Kestrel
133642 Connection id ""0HLPCETMP8DKL"" received FIN. key='SourceContext'>Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
133641 Connection id ""0HLPCETLEPLQ7"" stopped. key='SourceContext'>Microsoft.AspNetCore.Server.Kestrel
133640 Connection id ""0HLPCETLEPLQ7"" sending FIN. key='SourceContext'>Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
The exception is:
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslState.ThrowIfExceptional()
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult asyncResult)
at System.Net.Security.SslStream.<>c.<AuthenticateAsServerAsync>b__51_1(IAsyncResult iar)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionAdapter.InnerOnConnectionAsync(ConnectionAdapterContext context)
Does anyone have any idea why it would do this? Any other logs I can look at or suggestions on how to debug?
Thanks.

This is very likely due to the fact that you're running Service Fabric with the standard template, which sets up a Azure Load Balancer with a health probe for the ports that you've set up to use. The standard probe is generally TCP and will probe the endpoint every 5 seconds. You can remove the probe if that's a viable option. I personally use a less aggressive probe interval.
Note that changing the load balancer rules generally takes a long time, anything from a few minutes to near half an hour.

Related

System.Net.Http.HttpRequestException on download multiple files from Azure Datalake V2

I am downloading a large amount of files >1000 from Azure Datalake V2 and I am continuously getting exception:
The SSL connection could not be established, see inner exception.
<--- Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
<--- An existing connection was forcibly closed by the remote host.
Stacktrace:
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
--- End of inner exception stack trace ---
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
at System.Net.FixedSizeReader.ReadPacketAsync(Stream transport, AsyncProtocolRequest request)
at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
The code:
var downloadTasks = job.Files.AsParallel().Select(x => Download(x));
await Task.WhenAll(downloadTasks);
private async Task Download(DownloadableFile file)
{
try
{
var options = new BlobRequestOptions
{
ParallelOperationThreadCount = 8,
DisableContentMD5Validation = true,
StoreBlobContentMD5 = false
};
var xzBlob = await _cloudBlobFileService.GetBlockBlobReference(file.FilePath);
await xzBlob.DownloadToFileAsync(file.LocalFilePath, FileMode.Create, null, options, null);
}
catch (Exception e)
{
_log.LogCritical(e, "Error downloading " + file.FilePath);
}
}
I have also added this:
ServicePointManager.DefaultConnectionLimit = Environment.ProcessorCount * 8;
ServicePointManager.Expect100Continue = false;
Using .Net core 3.1 and WindowsAzure.Storage 9.3.3
to program.cs main method in webjob
We used to have a blobstorage configured without datalake, but after switching to datalake this has appeared. It doesn't affect the application to much as skipped downloads are retried later. It would however be nice to know whats causing it.
You could start by trying the new storage SDK that hit GA in November, though I can't guarantee that would solve the issue. It is a complete rewrite
While its not possible to pinpoint exactly just from the error message, there are a couple things to look at:
Network errors. It is the by far most likely cause, though it is interesting that it works consistently with your old blob storage account. Increasing the timeout may lower the frequency of network errors, and retry logic will help overcome them.
Using unbounded parallelism is not recommended. ParallelOperationThreadCount is for uploads not downloads, so it isn't throttling the requests in this case. The default limit for server-side connections in .NET is 10, and it is recommended to increase this when using .NET Core, it is something to consider. If you are accessing the same blob or partition too many times concurrently you can start to bump into the concurrent connections limits in Storage.

HTTPS not working with Kestrel 3.2.187/ASPNET Core 2.1.5 running on the Service Fabric with a custom domain

We are running a Service Fabric application on our remote dev cluster. It consists of several stateful and stateless services and is fronted by several front-end APIs running on Kestrel.
Until now, since it was not used for production, Kestrel was configured to use a self-signed certificate, which was also used for the reverse proxy and the cluster itself and the service was running directly on the default domain provided by Azure, <app>.<region>.cloudapp.azure.com.
We are now getting to the point in development where the self-signed certificate errors are becoming problematic, with third party callbacks rejecting the connection, so it was seen as the time to start using a proper domain and certificate for it.
So far, I have done the following:
Added an A record for devcluster.somexampledomain.com -> our public IP for the service.
Created a Wildcard Azure Application certificate for *.someexampledomain.com.
Imported the certificate to Azure Key Vault.
Bound the certificate to the Vault Secrets of the cluster, pulling the certificate to Cert:/LocalMachine/My/
Modified the application config to use this certificate when initialising Kestrel and verified that it is found when it is initialising.
Have tried with and without UseHsts() and UseHttpsRedirection()
Kestrel is configured with Listen(IPAddress.IPv6Any, endpoint.Port, ...) and UseHttps(X509Certificate2) on the options object.
UseUrls(string) is used with the default Url, which is https://+:<port> but tried manually adding https://*:<port> and even the actual hostname itself.
No matter what I have tried, no HTTPS connection can be established to the server. Trying the endpoints of the other staging servers that still use the old certificate, it works as expected.
Using openssl s_client -connect devcluster.someexampledomain.com:<port> -prexit, I get:
---
no peer certificate available
---
No client certificate CA names sent
---
There are no errors or exceptions being logged on ETW, everything seems to be in order. I suspect that this might have something to do with the CN of the certificate but I have run out of ideas to try and find out what is going on and how to fix it.
Been trying to look into this using Fiddler and I am not getting much out of it, the session just ends with fiddler.network.https> HTTPS handshake to <myhost> (for #191) failed. System.IO.IOException Authentication failed because the remote party has closed the transport stream.
Does anybody know how to add some logging on the Kestrel side? I don't think installing Fiddler on the Azure VMs running my cluster is a viable solution.
After delving into the Kestrel source, I found that it logs under "Microsoft-AspNetCore-Server-Kestrel" and "Microsoft-Extensions-Logging", so adding transfer of those I found what was happening.
Connections were terminating with the following exception:
System.ComponentModel.Win32Exception (0x8009030D): The credentials supplied to the package were not recognized
at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface secModule, String package, CredentialUse intent, SCHANNEL_CRED scc)
at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage, SCHANNEL_CRED secureCredential)
at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)
at System.Net.Security.SecureChannel.AcquireServerCredentials(Byte[]& thumbPrint, Byte[] clientHello)
at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output)
at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionAdapter.InnerOnConnectionAsync(ConnectionAdapterContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.HttpConnection.ApplyConnectionAdaptersAsync()
This makes it a manifestation of Certificate problem with a new machine - credentials supplied to package not recognized.
I spent some time trying to figure out what the best way to sort this out would be, the Service Fabric documentation has a script to modify the permissions but that just did not sound right.
As it turns out, this can be done directly in the ApplicationManifest as follows:
<Principals>
<Users>
<User Name="NETWORK SERVICE" AccountType="NetworkService" />
</Users>
</Principals>
<Policies>
<SecurityAccessPolicies>
<SecurityAccessPolicy ResourceRef="HttpsCert2" PrincipalRef="NETWORK SERVICE" ResourceType="Certificate" />
</SecurityAccessPolicies>
</Policies>
<Certificates>
<SecretsCertificate X509FindValue="[HttpsCertThumbprint]" Name="HttpsCert" />
</Certificates>
For the SecurityAccessPolicy to find the ResourceRef it had to be a SecretsCertificate, not an EndpointCertificate. Since the EndpointBindingPolicy requires an EndpointCertificate, I just added both a SecretsCertificate and an EndpointCertificate, with different names. They are both referring to the same certificate, so it worked. It doesn't feel particularly clean having to double them up but that is the solution I have for now.

rabbitmq con connect after published on iis

I am hosting asp.net core 2.0 webapi application on iis. but after host my application, rabbitmq host Broker unreachable. i have test this with vs debug mode and it's working fine. so my uri is correct.
here is my code.
services.AddSingleton(provider => Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host(new Uri("rabbitmq://192.168.100.239:15672/"), "/", h =>
{
h.Username("vinit");
h.Password("vinit");
h.Heartbeat(10);
});
cfg.ReceiveEndpoint(host, "TestQ", e =>
{
e.LoadFrom(provider);
});
}));
in iis i am getting this error.
Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor[9]
An error occurred starting the application
System.AggregateException: One or more errors occurred. (Broker unreachable: vinit#192.168.100.239:15672/) ---> MassTransit.RabbitMqTransport.RabbitMqConnectionException: Broker unreachable: vinit#192.168.100.239:15672/ ---> RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> System.IO.IOException: connection.start was never received, likely due to a network timeout
at RabbitMQ.Client.Framing.Impl.Connection.StartAndTune()
at RabbitMQ.Client.Framing.Impl.Connection.Open(Boolean insist)
at RabbitMQ.Client.Framing.Impl.ProtocolBase.CreateConnection(IConnectionFactory factory, Boolean insist, IFrameHandler frameHandler, String clientProvidedName)
at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
--- End of inner exception stack trace ---
at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
at MassTransit.RabbitMqTransport.Integration.ConnectionContextFactory.<CreateConnection>d__9.MoveNext()
--- End of inner exception stack trace ---
at MassTransit.RabbitMqTransport.Integration.ConnectionContextFactory.<CreateConnection>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
is i am missing some thing or need to do any additional setting?
Please suggest me.
Thank you
After reading RabbitMQ Document, i got answer that we can manage port from rabbitmq.config file in our system, and there are different port for transport.
Thank you

Solr Not Working after Publishing it on Godaddy

I built a website on visual studio using c# language, I used solrnet on my website and I connected to its server by http://localhost:8983/solr, everything were OK until I published the website on godaddy, I wasn't able to connect to solr anymore.
On Godaddy I replaced localhost:8983/solr/temp with publicIp:8983/solr
Error:
SolrNet.Exceptions.SolrConnectionException: Unable to connect to the remote server ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 00.00.00.00:8983 at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception) --- End of inner exception stack trace --- at System.Net.HttpWebRequest.GetResponse() at HttpWebAdapters.Adapters.HttpWebRequestAdapter.GetResponse() at SolrNet.Impl.SolrConnection.GetResponse(IHttpWebRequest request) at SolrNet.Impl.SolrConnection.Get(String relativeUrl, IEnumerable`1 parameters) --- End of inner exception stack trace --- at SolrNet.Impl.SolrConnection.Get(String relativeUrl, IEnumerable`1 parameters) at SampleSolrApp.LoggingConnection.Get(String relativeUrl, IEnumerable`1 parameters) at SolrNet.Impl.SolrQueryExecuter`1.Execute(ISolrQuery q, QueryOptions options) at SolrNet.Impl.SolrBasicServer`1.Query(ISolrQuery query, QueryOptions options) at SolrNet.Impl.SolrServer`1.Query(ISolrQuery query, QueryOptions options)
on godaddy server still solr should be on localhost:8983/solr
Try that on godaddy server IE
If you still want to publicly access solr you need to enable ports in Advance Firewall Settings

Configure NGINX / varnish to work with SignalR websockets?

I am using NGINX to offload SSL and then using varnish to load balance/cache responses from IIS8.
i.e. ssl -> nginx -> varnish -> iis8
This works perfectly. SignalR using long polling works fine - all my timeouts etc are properly configured.
Now I'm trying to get SignalR and websockets to work with this config; without success. To simplify things I've tried the following two set ups:
nginx -> iis8 (with these settings)
varnish -> iis8 (with these settings)
Neither of these work. I keep getting this error in Chrome:
WebSocket connection to 'ws://xxxxxxxx' failed: Unexpected response code: 500
and this from IIS:
System.InvalidOperationException: Not a valid web socket request.
at Microsoft.AspNet.SignalR.Owin.ServerRequest.AcceptWebSocketRequest(Func`2 callback)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary`2 environment)
at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()
at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBasehttpContext, AsyncCallback callback, Object extraData)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
It appears that something is not being correctly forwarded to IIS or IIS is being picky about something. Can anyone point me towards a working config for this set up?

Resources