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

Add async ServerOptionsSelectionCallback UseHttps overload #25390

Merged
merged 2 commits into from
Sep 1, 2020

Conversation

halter73
Copy link
Member

The changes to HttpsConnectionMiddleware to support this UseHttps overload were made in #24286. I didn't want to slow down that PR with public API considerations, but now is the time to review the API.

This not only allows async SNI configuration, but allows configuring nearly any part of SslServerAuthenticationOptions asynchronously after getting the ClientHello.

Initially, I was a little concerned that this doesn't respect configuration made via ConfigureHttpsDefaults or EndpointDefaults in config, but then I noticed that this not unique to this UseHttps overload. UseHttps(HttpsConnectionAdapterOptions) has this same limitation, because unlike UseHttps(Action<HttpsConnectionAdapterOptions>) and like this new overload, there are no incoming options to pre-populate with defaults.

Addresses #20981

@davidfowl @Tratcher

@halter73 halter73 added area-servers feature-kestrel api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Aug 29, 2020
@halter73 halter73 added this to the 5.0.0-rc1 milestone Aug 29, 2020
@halter73 halter73 added api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Aug 31, 2020
@ghost
Copy link

ghost commented Aug 31, 2020

Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:

  • The PR contains changes to the reference-assembly that describe the API change. Or, you have included a snippet of reference-assembly-style code that illustrates the API change.
  • The PR describes the impact to users, both positive (useful new APIs) and negative (breaking changes).
  • Someone is assigned to "champion" this change in the meeting, and they understand the impact and design of the change.

@pranavkm pranavkm added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews labels Aug 31, 2020
Copy link
Member

@Tratcher Tratcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No tests or samples?

@Pilchie Pilchie added the Servicing-approved Shiproom has approved the issue label Aug 31, 2020
@Pilchie
Copy link
Member

Pilchie commented Aug 31, 2020

Approved for RC1 pending CI completion if merged before 10am Pacific on 2020-09-01.

@Pilchie Pilchie merged commit 04f23ec into release/5.0 Sep 1, 2020
@Pilchie Pilchie deleted the halter73/20981 branch September 1, 2020 00:13
@davidfowl
Copy link
Member

I'm not here, I'm on vacation but @halter73 can you take over my PR #24935

@nitinag
Copy link

nitinag commented Mar 25, 2021

Thanks for adding this. We're using ServerOptionsSelectionCallback and SslStreamCertificateContext to enable hosting thousands of domains and selecting the right ssl certificates with Kestrel. Though X509Certificate2 on Windows does have temporary file creation issues that don't disappear with dispose that we have to deal with.

I had to spend some time to figure this out and to get it working with HTTP/2. Posting some sample code here for the benefit of others trying to use ServerOptionsSelectionCallback, for inclusion in documentation, and if anything with the sample code triggers changes/improvements.

We needed ConfigureAlpn to enable HTTP/2. Maybe this method should be made public in HttpsConnectionMiddleware or called internally in HttpsConnectionMiddleware for us?

Also would be great to have access to ConnectionContext so we can get the connecting ip, listening port, etc. to make certain decisions at this stage or to abort the connection if we didn't find a matching certificate or for any other reasons. If there is a best practice there on how to drop the connection when a matching certificate is not found, would be glad to hear it. Right now, we just return null as the certificate and let Kestrel drop the connection.

listenOptions.UseHttps(ServerOptionsSelectionCallback, state: listenOptions.Protocols);

ValueTask<SslServerAuthenticationOptions> ServerOptionsSelectionCallback(
	SslStream stream,
	SslClientHelloInfo clientHelloInfo,
	object state,
	CancellationToken cancellationToken)
{
	var serverOptions = new SslServerAuthenticationOptions
	{
		EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
		CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
		ServerCertificateContext = SslStreamCertificateContext.Create(certificate, intermediateCertificates, offline: true)
	};

	//ConfigureAlpn / Enable Http2
	var httpProtocols = (HttpProtocols)state;
	ConfigureAlpn(serverOptions, httpProtocols);

	return new ValueTask<SslServerAuthenticationOptions>(serverOptions);
}

//Copy of method from:
//https://github.com/dotnet/aspnetcore/blob/main/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs
void ConfigureAlpn(SslServerAuthenticationOptions serverOptions, HttpProtocols httpProtocols)
{
	serverOptions.ApplicationProtocols = new List<SslApplicationProtocol>();

	// This is order sensitive
	if ((httpProtocols & HttpProtocols.Http2) != 0)
	{
		serverOptions.ApplicationProtocols.Add(SslApplicationProtocol.Http2);
		// https://tools.ietf.org/html/rfc7540#section-9.2.1
		serverOptions.AllowRenegotiation = false;
	}

	if ((httpProtocols & HttpProtocols.Http1) != 0)
	{
		serverOptions.ApplicationProtocols.Add(SslApplicationProtocol.Http11);
	}
}

@ghost
Copy link

ghost commented Mar 25, 2021

Hi @nitinag. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context.

@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 join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-approved API was approved in API review, it can be implemented area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions feature-kestrel Servicing-approved Shiproom has approved the issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants