Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support cipher suite configuration #4776

Closed
vcsjones opened this issue May 26, 2017 · 33 comments
Closed

Support cipher suite configuration #4776

vcsjones opened this issue May 26, 2017 · 33 comments
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions feature-kestrel
Milestone

Comments

@vcsjones
Copy link
Member

As I understand, Kestrel 2 will be considered "safe" for edge deployments with HTTPS. Currently, there is no way to easily configure many desirable parameters of HTTPS. Mainly, the cipher suites that are supported, the algorithm and key size of the key exchange, etc.

For Windows, the functionality is configured the same as it was with IIS - with the registry / group policy. For Linux, I'm not exactly sure how to change the configuration, or if it can be done at all. I suspect it will just use OpenSSL's default in the distribution. If that is not the case, then I would be keen in knowing how to do it.

The Windows configuration by registry for SChannel leaves a lot to be desired. Changing SChannel's default configuration is not just for IIS or Kestrel - it affects anything that uses SChannel (remote desktop for example).

For edge deployments, it is naturally desirable to want to configure the cipher suites. There is a lot of pressure and mandate to start turning off old versions of TLS and strengthening cipher suite configuration, ensuring poor symmetric cipher are disabled, like 3DES, etc. Setting a preferred order is also important. Most web servers will prioritize AES128 over AES256 for performance, while some customers may wish to trade off the performance for security.

Even for internal traffic use, this is still very useful. Internal TLS is important, and because the traffic is internal to my infrastructure, I can mandate it to be whatever I want, such as TLS 1.2 only and ECDHE-AES-GCM-128 and not have to worry about client compatibility.

@Drawaes
Copy link
Contributor

Drawaes commented May 26, 2017

On Linux you can do it by configuring OpenSSL (not cURL). For windows you are stuck with the Registry/Policy story, which is an issue I have raised. It means that every site on a machine has to run with the same config. SSLStream delegates all of the processing to SChannel so you have no option

@vcsjones
Copy link
Member Author

vcsjones commented May 26, 2017

@Drawaes

On Linux you can do it by configuring OpenSSL (not cURL)

How? OpenSSL is just a library, it doesn't really have a configuration file other than openssl.cnf which is, as far as I know, it not used to set the protocols and cipher suites - just when you use bin/openssl in the CLI to do things like CSRs or run a CA.

@davidfowl
Copy link
Member

Our TLS support currently comes via SSLStream, we'll need to file an issue on corefx.

@Drawaes
Copy link
Contributor

Drawaes commented May 26, 2017

For windows, it's a non starter, as it relies on SChannel, which has a registry level config that is machine wide only (eg both client and server uses will be effected). OpenSsl has a possibility but it needs code, and it would change everything in process that uses SslStream,

@vcsjones
Copy link
Member Author

vcsjones commented May 26, 2017

@Drawaes

For windows, it's a non starter, as it relies on SChannel, which has a registry level config that is machine wide only

I want to dispel this statement because I keep hearing it. SChannel in usermode is quite capable of configuring protocols and cipher suites at pretty much any level you want, such as the socket. Here is some awful C++ code I wrote that does that: https://gist.github.com/vcsjones/7687d2a764836b40300d15fea07510f8 (it gets interesting around line 92)

This just sets up a little dummy TLS handshake server that uses TLS v1.1, regardless of what the registry is set to. It isn't enough code to try it in a browser (because I was too lazy to finish the handshake), but if you compile this code, run it, and point openssl to it, you get something like this:

screen shot 2017-05-26 at 3 30 15 am

Using openssl s_client -connect 127.0.0.1:21213

You can configure the cipher suites in SCHANNEL_CRED - the example is just set to "use whatever".

So I would argue that Kestrel is capable of using SChannel on Windows and allow cipher suite / protocol selection. Well, actually I would argue that CoreFX is capable of implementing SslStream in such a way, but the machinery is there for Windows.

@Drawaes
Copy link
Contributor

Drawaes commented May 26, 2017

I know you can set the protocol version, my schannel prototype did that. Was unaware you could set curves and ciphers?

@vcsjones
Copy link
Member Author

vcsjones commented May 26, 2017

Sure, I updated it to limit it to cipher suites with AES-128. Change it to AES-256 and it will pick AES-256.

The API for this is very, very strange, but it's doable, I think.

@SteveSyfuhs
Copy link

Nice! The API isn't that bad. 😄 Good ol' SSPI's.

I guess the question now is whether IIS relies on calls to AcceptSecurityContext in the kernel to handle this bit (I think it does?), or whether it does it in usermode. At one point it was advantageous to do it in the kernel for perf reasons.

@Tratcher
Copy link
Member

IIS delegates HTTPS to Http.Sys in kernel mode. So does WebListener.

@Drawaes
Copy link
Contributor

Drawaes commented May 26, 2017 via email

@vcsjones
Copy link
Member Author

vcsjones commented May 26, 2017

IIS delegates HTTPS to Http.Sys in kernel mode. So does WebListener.

OK, I'll digress from the specifics of this, but rather want to point out that as someone that is in charge of deploying and managing TLS in an infrastructure, there are several gaps that need to be filled before I would be comfortable even considering terminating TLS with Kestrel. I'm raising the issues because I think they are important, and if the intention is for this to be a real scenario for Kestrel, there needs to be some discussion around this.

I'll put aside the Windows / SChannel issue because there is at least a functioning work around with Group Policy / registry since we are using SChannel in kernel mode, apparently.

The issue still stands that I do not know how to do this on Linux and it is a requirement for any practical deployment of HTTPS on the edge.

@Drawaes
Copy link
Contributor

Drawaes commented May 26, 2017

You can use the same trick for openssl. There is 1 instance per process. You can change the cipherlist before an tls connection starts u are good.
https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_cipher_list.html
Call that and you can do a similar thing. This time there is no kernel in play.

@Drawaes
Copy link
Contributor

Drawaes commented May 26, 2017

You can also compile out TLS levels .. you need to ensure you only call methods on the lib after .net did it's openssl init or you need to do it, otherwise you won't have ciphers loaded.

@vcsjones
Copy link
Member Author

You can use the same trick for openssl. There is 1 instance per process. You can change the cipherlist before an tls connection starts u are good.

Ah. That would work... but platform invoking openssl on process startup should be viewed as a work around at best, but that's good thinking.

@davidfowl
Copy link
Member

davidfowl commented May 31, 2017

Also /cc @blowdart

@sandersaares
Copy link
Contributor

sandersaares commented Jun 9, 2017

It would be desirable to configure TLS options via some platform-neutral .NET API that the process using Kestrel can apply before starting up the listener (with potentially reduced functionality compared to OpenSSL/SChannel configuration API).

Right now we use nginx both on Windows and Linux for certain roles, exactly to avoid having to maintain two different configuration paths. There are some parts of this infrastructure that are a good fit for potential replacement with Kestrel in the near future but any moment where we need to think about "Kestrel on Windows" versus "Kestrel on Linux" is a deal-killer for us.

@muratg
Copy link
Contributor

muratg commented Jun 26, 2017

@joshfree, we think this should be an SSLStream feature. Perhaps we should talk about this in our next sync-up.

cc @davidfowl

@Drawaes
Copy link
Contributor

Drawaes commented Aug 22, 2017

It will need to be supported from SslStream to work. There is an open issue to change SslStream's API to have an option bag, which hopefully will mean we can add more config options easier ;)

@muratg
Copy link
Contributor

muratg commented Nov 10, 2017

This is an SSLStream feature ask. Assigning to @shirhatti in case he wants to follow-up or close it.

@shanselman
Copy link
Contributor

shanselman commented Feb 15, 2018

Apparently this is starting to get hit as iPhone/iOS clients try to hit Kestrel and it's not possible. @MattCotterellNZ hit this recently. Can we get this triaged and moved to Corefx? Or is this already coming in 2.1 with this? dotnet/corefx#25985 @stephentoub

@stephentoub
Copy link
Member

stephentoub commented Feb 15, 2018

If there's a feature request for SslStream, someone should open an issue in corefx with a proposal.

Is it https://github.com/dotnet/corefx/issues/24588?

@vcsjones
Copy link
Member Author

vcsjones commented Feb 15, 2018

There are two "things" in this request: the cipher suites, and the protocol version.

As I understand, SslStream already supports configuring the protocol in AuthenticateAsServer and AuthenticateAsClient. I think for the protocol version then, it's just a matter of Kestrel allowing those values to be configured.

For cipher suites, yes - that will require work as SslStream does not expose setting that.

/cc @stephentoub

https://msdn.microsoft.com/en-us/library/ms145065(v=vs.110).aspx

@Drawaes
Copy link
Contributor

Drawaes commented Feb 15, 2018

Yes https://github.com/dotnet/corefx/issues/24588

Will satisfy the requirement from sslstream.

@davidfowl
Copy link
Member

Putting this into the backlog for now.

@halter73
Copy link
Member

@vcsjones Kestrel already allows the protocol version to be configured. https://stackoverflow.com/a/46833019/719967

@vcsjones
Copy link
Member Author

vcsjones commented Feb 15, 2018

@halter73 oh wow, OK - that's good to know. I apparently missed this (is it new?). Would it make sense to update the title and description of this issue to make it about cipher suites specifically then?

@halter73 halter73 changed the title Support TLS version and cipher suite configuration Support cipher suite configuration Feb 15, 2018
@halter73
Copy link
Member

The SslProtocols config has been in Kestrel since 1.0, but back in 1.x it was on the HttpsConnectionFilterOptions type instead of the HttpsConnectionAdapterOptions type. I updated the title.

@zhaoyunED
Copy link

so now kestrel still does not support cipher suite configuration ?

@vcsjones
Copy link
Member Author

so now kestrel still does not support cipher suite configuration ?

I believe the upstream issue at dotnet/corefx#24588 needs to be resolved first. If this is important to you, give it a 👍 so that folks are better able to understand how many people want this feature.

@ryan2clw
Copy link

I'd like to use Kestrel as an edge server. I wrote an article how to deploy it as a non-sudo user here: https://medium.com/@ryan.dines/asp-net-core-aws-rhel-kestrel-14ce07a852ff. Then I started thinking about the TLS layer, I always configure to get an A+ rating from Qualsys with Apache or Nginx, so that would be awesome if you could pre-configure out of the box for me. To me should be part of the server config, here is my nginx config, if you were looking for inspiration on what other features to add besides the cipher suite order (by far the most important). Some are probably already implemented I imagine. Cool software by the way, love the direction ASP.NET is headed, keep up the good work.

server {
    server_name seniordevops.com;
    listen 443 ssl http2;
    ssl_certificate /etc/ssl/certs/seniordevops_com.crt;
    ssl_certificate_key /etc/ssl/certs/seniordevops.key;
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 180m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5;
    ssl_dhparam /etc/nginx/cert/dhparam.pem;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/certs/seniordevops_com.crt;
    resolver 8.8.8.8 8.8.4.4;
    add_header Strict-Transport-Security "max-age=31536000" always;
    root /opt/workTracker/workTracker;
    index clockin/templates/registration/login.html;
    keepalive_timeout 5;
    client_max_body_size 4G;

@aspnet-hello aspnet-hello transferred this issue from aspnet/KestrelHttpServer Dec 13, 2018
@aspnet-hello aspnet-hello assigned shirhatti and unassigned shirhatti Dec 13, 2018
@aspnet-hello aspnet-hello added this to the Backlog milestone Dec 13, 2018
@ghost
Copy link

ghost commented Mar 8, 2019

Is there any feedback on this?

@avenema
Copy link

avenema commented Apr 13, 2019

Is this unblocked now that https://github.com/dotnet/corefx/issues/24588 is resolved?

@shirhatti
Copy link
Contributor

@avenema Yes. We've filed #9349 to track this work.

Closing this discussion issue in favor of the new issue

@shirhatti shirhatti removed their assignment Apr 15, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2019
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Jun 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions feature-kestrel
Projects
None yet
Development

No branches or pull requests