How can I change the available cipher suites available to OpenSSL/Kestrel from within a Linux docker container?
First, lets start with some environment details:
My Program.cs looks something like this, which sets up kestrel:
builder.UseKestrel(o => o.UseHttps(new HttpsConnectionFilterOptions
{
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11,
CheckCertificateRevocation = true,
ClientCertificateMode = ClientCertificateMode.AllowCertificate
ServerCertificate = new X509Certificate2(certificate.Pfx, certificate.Password)
}))
.UseUrls(bindTo);
The key line being this:
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11,
No matter what values I set here (Tls12, Tls11, Tls, or any subset of these), it doesn't seem to have an impact on what cipher suites are available to connections. I'm going by the sslLabs report for my URL, which is capped at Grade B due to the availability of RC4 ciphers on old protocols. Which is the issue what I want to sort, and I believe supporting just TLS1.1 and 1.2 should solve this.
But for example, as you can see above, I don't mention TLS 1.0, and yet its available in the report, which has kind of stumped me.
Is it actually using the code, or is it getting the available ciphers from somewhere else? Because it certainly looks like the value of the SslProtocols property makes no difference.
When using Apache you can configure the available cipher suites via configuration file (httpd.conf), so I figured that kestrel might have a file to do the same thing, but I've not managed to find one. The general consensus seems to be that it be handled in code. Which as far as I can see, I have done?
I then considered using Apache as the Internet-facing web server to handle the cipher management, which then proxies requests onto kestrel, but this would be in breach of contract for this project, where we specify that all data will remain encrypted during every stage of transit. The process of decrypting the data in Apache before re-encrypting it for transit onto kestrel isn't viable.
I then thought that perhaps OpenSSL has a similar configuration file to Apache, and that I can just change that configuration to achieve what I needed. I found these 2 files in our file system:
/usr/lib/ssl/openssl.cnf
/etc/ssl/openssl.cnf
But neither of them have any lists of cipher suites that I would expect to see when comparing with the Apache configuration file. Or perhaps it did, and I have just misunderstood the file format?
I have also come across this method that can be used to configure available cipher suites 'SSL_CTX_set_cipher_list', but I think this is only available in C++, and there is no similar functionality/wrapper for C# that I have found. I guess it would be possible to write a C++ program to setup the cipher suites when pushing into docker before setting up the website? But this sounds really hacky though, I'd prefer to get the website handling it by itself.
Long story short, I'm rapidly running out of ideas. So any input you have is greatly appreciated. Thanks for any help you can provide!
The ciphers command converts textual OpenSSL cipher lists into ordered SSL cipher preference lists. It can be used as a test tool to determine the appropriate cipherlist.
The purpose is to use the most secure protocols, cipher suites and hashing algorithms that both ends support. To use the strongest ciphers and algorithms it's important to disable the ciphers and algorithms you no longer want to see used.
It seems like it solved in ASP.NET Core 3.0, you can see it under "CipherSuitesPolicy" https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With