microsoft / service-fabric-aspnetcore

This repo contains ASP.NET Core integration for Service Fabric Reliable Services.
Other
152 stars 49 forks source link

Service Fabric Kestrel 3.1 Https certificate through load balanser #85

Closed MatthewDavidCampbell closed 4 years ago

MatthewDavidCampbell commented 4 years ago

Describe the bug See a detailed description on Stackoverflow as well the stateless service definition gist. In short, our cluster load balanser accessing an HTTPS endpoint on 443 through 8443 worked fine when the service was using Fabric 1 on Net with Owin. After moving our service to Kestrel 3.1 on Fabric 2 the primary certificate needs to be explicit defined. The load balanser is closing the request to 8443 (thus 443) prematurely. Not finding any examples of using a primary certificate defined on the cluster and mapped into the endpoint policy in the application manifest. Expected some example online of using the thumbprint supplied in the manifest to find the certificate in the X509 store and using that cert in the UseHttps configuration.

To Reproduce

Expected behavior Some log of why the load balanser can't pass through to the service which is up and running according the the logging sent to Insights

Additional context

amanbha commented 4 years ago

Have you tried this: https://docs.microsoft.com/azure/service-fabric/service-fabric-tutorial-dotnet-app-enable-https-endpoint

MatthewDavidCampbell commented 4 years ago

Couple issues with that tutorial.

1) Not Kestel 3.0+ ready. The NoDelay options have moved to SocketTransportOptions which default to true (i.e. disable Nagle's algorithm for all connections). Would be great if there was clarification about the use or non-use of Nagle plus the impact on HTTPS cert.

2) Bad download reference to source code. Which means there is no example of the GetHttpsCertificateFromStore method showing how the certificate is looked-up. Assumption is that the FindMatchingCertificateBySubject example is a possible way to access the correct cert by subject.

3) Not cluster friendly. The tutorial talks about importing certificates into storage on the remote cluster. Our setup uses the Azure Portal to create primary (cluster) | administrative (client) certificates rather than importing. This puts the certificates in each node's context (i.e. accessible to the X509Store as shown in the FindMatchingCertificateBySubject).

The tutorial mentions access to the certificate's private key. Thought that was the whole point of the following article and what is mirrored in the my gist. Namely, that the Certificates section in ApplicationManifest.xml and binding that certificate to a particular endpoint in the Policies.EndpointBindingPolicy. This should give permission to the certificate's private key.

So the configuration I have tried should tell Kestrel to use https and use a specific certificate and that certificate (primary) is defined in the cluster plus permitted in the application manifest for the https endpoint. What is not right about this?

MatthewDavidCampbell commented 4 years ago

Solved. Had set the protocol to HTTP2 instead of forcing HTTP1.

 `options.Listen(
                    IPAddress.IPv6Any,
                    description.Port,
                    listenOptions => {
                        listenOptions.Protocols = HttpProtocols.Http1;

                        if (description.Protocol == System.Fabric.Description.EndpointProtocol.Https)
                        {
                            var certificate = GetFabricCertificate(loggerFactory);  

                            if (certificate != null) { 
                                listenOptions.UseHttps(certificate);
                            }
                        }
                    }
                );`