natemcmaster/LettuceEncrypt

[Question] Getting an A+ in Qualys SSL Lab

shoe-diamente opened this issue · 5 comments

Hello,
I'm trying to follow this issue in order to set up HTTPS and get an A+ in Qualys SSL Lab (https://www.ssllabs.com/index.html). I'm specifically following this comment which appears to yield an A+.

Unfortunately by using the suggested configurations and Lettuce Encrypt I still get a B because some cyphers appear to be enabled even though they are explicitly disabled by the above issue's suggested solution.

I currently have this in my Program.cs:

        // Ciphersuit policy for this server:
        static readonly System.Net.Security.CipherSuitesPolicy cipherSuitesPolicy = new System.Net.Security.CipherSuitesPolicy
            (
                new System.Net.Security.TlsCipherSuite[]
                {
                    // Cipher suits as recommended by: https://wiki.mozilla.org/Security/Server_Side_TLS
                    // Listed in preferred order.

                    // Highly secure TLS 1.3 cipher suits:
                    System.Net.Security.TlsCipherSuite.TLS_AES_128_GCM_SHA256,
                    System.Net.Security.TlsCipherSuite.TLS_AES_256_GCM_SHA384,
                    System.Net.Security.TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256,

                    // Medium secure compatibility TLS 1.2 cipher suits:
                    System.Net.Security.TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                    System.Net.Security.TlsCipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                    System.Net.Security.TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                    System.Net.Security.TlsCipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
                    System.Net.Security.TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
                    System.Net.Security.TlsCipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
                    System.Net.Security.TlsCipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
                    System.Net.Security.TlsCipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
                }
            );

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureKestrel((context, options) =>
                {
                    var appServices = options.ApplicationServices;
                    options.ConfigureHttpsDefaults(httpsOptions =>
                    {
                        httpsOptions.OnAuthenticate = (conContext, sslAuthOptions) =>
                        {
                            sslAuthOptions.CipherSuitesPolicy = cipherSuitesPolicy;
                        };
                        httpsOptions.UseLettuceEncrypt(appServices);
                    });
                })
                .ConfigureAppConfiguration((builderContext, config) =>
                {
                    var env = builderContext.HostingEnvironment;
                    config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
                        .AddEnvironmentVariables();
                })
                .UseStartup<Startup>();

and in my Statup.cs I have the following:

        public void ConfigureServices(IServiceCollection services)
        {
            if (Environment.IsProduction())
            {
                var certificatesPath = Path.Combine(AppContext.BaseDirectory, "certificates");
                var certificatesDir = new DirectoryInfo(certificatesPath);
                services.AddLettuceEncrypt()
                    .PersistDataToDirectory(certificatesDir, null);
            }

            // ...
        }

and:

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();

            if (env.IsProduction())
                app.UseHttpsRedirection();
            
            // ...
        }

The SSL Lab shows that the certificate is the one issued by Lettuce Encrypt and the .NET Core logs seems to corroborate that Lettuce Encrypt is working correctly.

But I still get these errors:

Screen Shot 2020-09-11 at 10 52 31

Is Lettuce Encrypt by chance overriding these configurations?

The conflict is here:

httpsOptions.OnAuthenticate = tlsAlpnChallengeResponder.OnSslAuthenticate;

In theory that could be changed to check for an existing callback and wrap it.

@Tratcher Yes. Could it also work the other way around? Calling LettuceEncrypt first and then overriding the on authenticate method to wrap the one LettuceEncrypt specified?

By the way the main problem is that I was using APIs that were introduced in .NET Core 3.1 but will be effective only in .NET 5.

Actully I'll leave it open for the OnAuthenticate problem.

So what's the correct solution to this problem?
I don't have configure/usekestrel. So i added those calls and the code here, but capture the OnAuthenticate callback first. Still, won't work. Net Core 3.1


 .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureKestrel(options =>
                    {
                        var appServices = options.ApplicationServices;
                        options.ConfigureHttpsDefaults(httpsOptions =>
                        {
                            httpsOptions.SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13;
                            httpsOptions.UseLettuceEncrypt(appServices);
                            var LettuceAuthenticate = httpsOptions.OnAuthenticate;
                            httpsOptions.OnAuthenticate = (conContext, sslAuthOptions) =>
                            {
                                sslAuthOptions.CipherSuitesPolicy = cipherSuitesPolicy;
                                LettuceAuthenticate(conContext, sslAuthOptions);
                            };
                        });    
                    });
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseKestrel();

For me just upgrading to .NET 5 resulted in a A grade, which is good enough for my use case at the moment.