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

SNI cert selection support #86

Closed
davidni opened this issue Apr 23, 2020 · 5 comments
Closed

SNI cert selection support #86

davidni opened this issue Apr 23, 2020 · 5 comments
Labels
Type: Idea This issue is a high-level idea for discussion.
Milestone

Comments

@davidni
Copy link
Contributor

davidni commented Apr 23, 2020

What should we add or change to make your life better?

In Island Gateway, we added support for SNI cert binding. If there is interest, I can submit a PR to contribute that here. Note that we have not tackled Linux scenarios.

Our design is roughly the following:

  1. A background task periodically scans all reasonable certs from a given cert store. More on what is a reasonable cert below
  2. Extract all SAN entries from each reasonable cert, and build a dictionary mapping acceptable host names to certs. Wildcard entries are supported per RFC6125 section 6.4.3.
  3. Deterministic logic selects the best cert for a host name out of all available certs. More on the definition of best below.
  4. When any changes are detected, atomically swap the old dictionary with the new one
  5. We expose an interface that can be called from Kestrel's server cert selection callback to produce the appropriate cert for a given host name, or null if none match. Cert selection is always O(1) w.r.t number of bound host names, including for wildcard matches.

Why is this important to you?

Frontend gateways such as those using YARP often host multi-tenant workloads serving multiple host names. Automatic SNI TLS cert binding reduces a lot of devops friction, ensuring the right certificates are picked up without human intervention. Cert rotation also becomes trivial, as the background update loop takes care of finding and using the best certs available at all times.

Other notes

  • Definition of reasonable cert: Similar to Kestrel's existing logic:

    • 1.3.6.1.5.5.7.3.1 Enhanced Key Usage oid when the extension is present
    • Private key is available
    • Additional validity + revocation checks. we call X509Certificate2.Verify() to also check for revocation, whereas X509CertificateStore.Find(... validOnly: true) (used in Kestrel's defaults) does not check revocation.
  • Definition of best cert: The most recently-issued certificate that is reasonable. We use most recently issued rather than furthest expiration to properly handle situations where due to a policy change cert expiration times may be reduced (maybe someone used to issue certs good for 2 years, but now switched to 6 months. We wouldn't want to keep using the old certs once the new ones are available).

@davidni davidni added the Type: Idea This issue is a high-level idea for discussion. label Apr 23, 2020
@Tratcher
Copy link
Member

There's nothing YARP specific about this except being more likely to have multiple certs. It's probably best addressed directly in Kestrel.

I hadn't envisioned directly scanning the store, but rather specifying the certs in config and then making config reloadable.

Related issues:

@analogrelay
Copy link
Member

It might be best to explore making this change in ASP.NET Core. For example, dotnet/aspnetcore#15144 is really close to what you described @davidni. The design we landed on in that issue was a config-based system, but I could also see an option to just load directly from the cert store. That's only applicable on Windows, which is why we've generally hesitated away from it being the only solution, but supporting both a configured list of certs and auto-scanning from the store seems reasonable.

@analogrelay
Copy link
Member

analogrelay commented Apr 28, 2020

Triage: We'll move this down to dotnet/aspnetcore#15144 and dotnet/aspnetcore#21300.

@analogrelay
Copy link
Member

We may decide that the automatic cert store stuff is too much complexity for ASP.NET Core, so I'll leave this open and in our 1.0 backlog since we should consider doing something like this in the proxy for 1.0.

@karelz
Copy link
Member

karelz commented Mar 24, 2021

Duplicate of dotnet/aspnetcore#21300

@karelz karelz marked this as a duplicate of dotnet/aspnetcore#21300 Mar 24, 2021
@karelz karelz closed this as completed Mar 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Idea This issue is a high-level idea for discussion.
Projects
None yet
Development

No branches or pull requests

4 participants