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 multiple server TlsCertificates per DownstreamTlsContext #1319

Closed
htuch opened this issue Jul 24, 2017 · 23 comments
Closed

Support multiple server TlsCertificates per DownstreamTlsContext #1319

htuch opened this issue Jul 24, 2017 · 23 comments
Assignees
Milestone

Comments

@htuch
Copy link
Member

htuch commented Jul 24, 2017

In the v2 API, we allow multiple TlsCertificates to be specified per DownstreamTlsContext (https://github.com/lyft/envoy-api/blob/master/api/tls_context.proto#L107). In the current Envoy implementation, each TLS context only supports a single certificate/key (https://github.com/lyft/envoy/blob/master/source/common/ssl/context_impl.cc#L77). This issue will track the design and implementation of multiple cert support. @PiotrSikora

@htuch htuch added the api/v2 label Jul 24, 2017
@htuch htuch changed the title Support multiple server TlsCertificates per TlsContext Support multiple server TlsCertificates per DownstreamTlsContext Jul 24, 2017
@mattklein123
Copy link
Member

This is a dup of #95 right? We should implement SNI in the "v1" world also, as it is trivial to do so. @PiotrSikora if you are going to work on this can we maybe do the v1 work first since it will be used in v2 as well?

@htuch
Copy link
Member Author

htuch commented Jul 24, 2017

I was interested in understanding what it means to have multiple certs here. Piotr pointed out there are a number of different options, e.g. are we doing this with SNI, different cert types. If it's just SNI then it's a dupe.

@mattklein123
Copy link
Member

Yeah that's true, this is beyond SNI, like having both EC and RSA certs potentially I guess? Still, I would like to see us implement SNI ASAP since I'm getting tired of getting asked about it. :)

@PiotrSikora
Copy link
Contributor

This (repeated TlsCertificates in v2 API) is for having different types of certificates for the same context (e.g. RSA and ECDSA), which is different from full SNI support (#95). Let's keep this simple and move SNI discussion back to #95.

@stale
Copy link

stale bot commented Jun 21, 2018

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Jun 21, 2018
@ggreenway ggreenway added the help wanted Needs help! label Jun 21, 2018
@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Jun 21, 2018
@ggreenway
Copy link
Contributor

This is still needed. I'll implement eventually if nobody else has first. I specifically need EC and RSA certs (with the same SANs) on the same context.

@PiotrSikora
Copy link
Contributor

@ggreenway I discussed this on and off with @davidben. The reason why I didn't implement this in Envoy via "userland" certificate selection yet is that the plan is for BoringSSL to eventually re-add the support for multiple certificates of different types in the same context (exactly for the RSA & ECDSA use case).

@ggreenway
Copy link
Contributor

Any idea what the timeline is for that change to BoringSSL?

@ggreenway
Copy link
Contributor

@PiotrSikora is the "userland" approach to create a different SSL_CTX for each cert type, and set the CTX in one of the callbacks based on supported cipher types in the ClientHello?

@davidben
Copy link
Contributor

Sorry about the delay on that feature. I'm kind of running around all over the place right now due to an upcoming move, and a couple of tasks popped up in front of it that took longer than expected. I do intend to finally chew on it this week, though if it's not done by IETF and my move, it might get delayed.

@PiotrSikora
Copy link
Contributor

PiotrSikora commented Jun 27, 2018

@ggreenway yes, pretty much. The "userland" approach isn't a complex change in Envoy, but the support for RSA+ECDSA isn't something frequently requested by the community, and since the proper support for it is going to be added to BoringSSL sooner rather than later, I'd rather not add it now, unless required for a production deployment.

Do you have any deadline for when you need this feature to be available?

@ggreenway
Copy link
Contributor

I don't have a hard date right now, but I'd guess I'll probably need it within 3 months. I'll hold off as long as possible in hopes that BoringSSL adds the functionality we need. But if I need to do it in userland, and then we rip it out later, that's fine. I'll comment here when I have firmer dates, or when I'm going to start working on it.

@htuch htuch assigned htuch and unassigned PiotrSikora Nov 14, 2018
@htuch htuch removed the help wanted Needs help! label Nov 14, 2018
@htuch
Copy link
Member Author

htuch commented Nov 14, 2018

I'm going to take a shot at this one, since we need this sooner than later.

@htuch
Copy link
Member Author

htuch commented Nov 14, 2018

FTR, I've had internal discussions with @PiotrSikora and @davidben. The PoR is to add in explicit client handshake and certificate type detection to Envoy for the initial implementation, as BoringSSL won't add this for some time. When this feature arrives in BoringSSL, we will replace our implementation with that.

@htuch
Copy link
Member Author

htuch commented Nov 14, 2018

Quick design question @mattklein123 @ggreenway @lizan @PiotrSikora. Do we want to do the client handshake capability detection in the TLS inspector or directly in the TLS transport socket?

A reason for TLS inspector include that we're doing ClientHello peaking already for SNI/ALPN. A reason against is that mixed certificate type doesn't necessarily imply SNI use, so we will have additional scenarios for requiring the inspector extension.

I'm thinking we'll be doing it in the inspector, since this is conceptually coherent with what's done for other handshake attributes, but just wanted to check your thoughts.

@htuch
Copy link
Member Author

htuch commented Nov 14, 2018

Oh right, we inject the TLS inspector automatically anyway, so the above is moot, I see.

@mattklein123
Copy link
Member

In general doing it as part of the inspector sounds good to me, and then we can use that data to drive later decisions around which cert to use.

@htuch
Copy link
Member Author

htuch commented Nov 15, 2018

A couple more things to bounce off folks on this issue; the resolution order for certificates. What I'm thinking is:

  1. We keep track of the first ECDSA and first RSA certs in a certificate chain.
  2. For server contexts, we will use the client handshake ECDSA indicators from the group and cipher suite extensions to determine which to use.

Some design choices we can make:

  1. We could skip any certificates that don't validate and only select the first matching one in (1) above. Or, we could maintain existing semantics and reject any invalid cert/key pairs as a config rejection. Which to do?
  2. I'm wondering how best to handle client contexts. Do we just pick the first certificate and call it a day?

There's a tradeoff here between keeping it simple (i.e. the cert list has a cardinality <= 2) vs. being more flexible. Either way, we'll need to document this well, as it's probably going to be confusing to reason about. Ideally we maybe should just have a singleton ECDSA and a singleton RSA option in the config and let the earlier non-Envoy config pipeline do this resolution.

@mattklein123
Copy link
Member

Or, we could maintain existing semantics and reject any invalid cert/key pairs as a config rejection.

Big +1. IMO much less surprising. I would do this until if/when someone complains which I would find very surprising and we can potentially push back on.

I'm wondering how best to handle client contexts. Do we just pick the first certificate and call it a day?

Then what about just continuing to force 1 (with config error for > 1) for client until someone actually needs it and can come up with a sensible way of configuring it?

@lizan
Copy link
Member

lizan commented Nov 15, 2018

IIUC per https://github.com/envoyproxy/envoy/blob/master/source/server/listener_manager_impl.cc#L243
TLS inspector is only injected when you have certain filter_chain_match. So if a listener is configured for pre-knowledge TLS, then it is valid that no TLS inspector is injected.

Also do we want to select filter chain based on ClientHello certificate type? If no perhaps adding in TLS transport is better and it is easier to replace with BoringSSL implementation? (Assuming BoringSSL implementation will be having multiple certificates in same SSL_CTX)

htuch added a commit that referenced this issue Nov 27, 2018
This PR starts to plumb multiple TLS certs from the proto level into the SSL context. We stop short
of enabling multiple TLS certificates, but instead have sufficient mechanism and interface changes
to propagate them to the SSL context. Future PRs will extend this with the SSL context
implementation.

Risk Level: Low
Testing: bazel test //test/...

Part of #1319.

Signed-off-by: Harvey Tuch <htuch@google.com>
@htuch
Copy link
Member Author

htuch commented Nov 28, 2018

After some discussion with @davidben and @PiotrSikora, I think it's clear that we should have the ECDSA detection happen in the TLS socket, rather than TLS inspector. The rationale here is that BoringSSL will eventually subsume this capability, so we should try and localize it rather than plumb deprecated ECDSA details (signature algorithms, cipher suites) across the listener socket objects.

htuch added a commit to htuch/envoy that referenced this issue Nov 28, 2018
This continues the plumbing needed for envoyproxy#1319. In this PR, we add support
to ContextImpl to handle multiple certs during configuration ingestion
and also the skeleton for the certificate switch that occurs following
ClientHello. There is no selection logic yet; this will be a followup
PR.

Risk Level: Low
Testing: bazel test //test/... No new tests, since we are not making a
  major behavioral change, this is refactoring essentially.

Signed-off-by: Harvey Tuch <htuch@google.com>
htuch added a commit that referenced this issue Dec 3, 2018
This continues the plumbing needed for #1319. In this PR, we add support
to ContextImpl to handle multiple certs during configuration ingestion
and also the skeleton for the certificate switch that occurs following
ClientHello. There is no selection logic yet; this will be a followup
PR.

Risk Level: Low
Testing: bazel test //test/... No new tests, since we are not making a
major behavioral change, this is refactoring essentially.

Signed-off-by: Harvey Tuch <htuch@google.com>
htuch added a commit that referenced this issue Dec 9, 2018
This PR adds support to ServerContextImpl::selectTlsContext(), allowing
for the selection of a certificate based on whether the client is RSA
and/or ECDSA capable from a list.

Since the list is still a singleton due to config ingest limitations,
we're still effectively single certificate, but this PR exercises the
logic that will be used in the multi-certificate selection case.
Ideally, there should be no observable behavioral changes.

Risk Level: Low (this should continue to fallback to the default
certificate, even if the ECDSA code is exercised).
Testing: Some new parameterized integration tests.

Part of #1319

Signed-off-by: Harvey Tuch <htuch@google.com>
htuch added a commit to htuch/envoy that referenced this issue Dec 16, 2018
This PR wraps up envoyproxy#1319. The patch enables multiple TLS certificate
ingest for upstream TLS contexts, adds related unit and integration
tests, docs and release notes.

Risk Level: Low
Testing: Additional unit and integration tests. To avoid combinatorial
  explosion, we validate mixed TLS v1.2/1.3 behavior in
  ssl_integration_test only, and have more targeted certificate
  selection tests in ssl_socket_Test.
Docs Changes: Added to architectural overview of TLS support.

Fixes envoyproxy#1319.

Signed-off-by: Harvey Tuch <htuch@google.com>
htuch added a commit that referenced this issue Dec 17, 2018
This PR wraps up #1319. The patch enables multiple TLS certificate
ingest for downstream TLS contexts, adds related unit and integration
tests, docs and release notes.

Risk Level: Low
Testing: Additional unit and integration tests. To avoid combinatorial
explosion, we validate mixed TLS v1.2/1.3 behavior in
ssl_integration_test only, and have more targeted certificate
selection tests in ssl_socket_Test.
Docs Changes: Added to architectural overview of TLS support.

Fixes #1319.

Signed-off-by: Harvey Tuch <htuch@google.com>
fredlas pushed a commit to fredlas/envoy that referenced this issue Mar 5, 2019
…s. (envoyproxy#5090)

While working on envoyproxy#1319, it became clear that just running certs.sh to
regenerate certs does not actually work anymore, since we now have
hardcoded hashes for verify_certificate_hash in various places.

This PR fixes this for test/config/integration/certs. The problem still
exists for test/common/ssl/test_data. I will do a separate PR for that
based on the outcome of the review for this PR.

I also removed the optional private key regeneration in this PR. I think
we should always regenerate everything to prevent the bit rot regression
this PR fixes; long term this should be done by Bazel automagically, but
that would force an openssl dependency in the environment or the
adoption of a tool such as https://github.com/square/certstrap.

Risk Level: Low
Testing: bazel test //test/integration/...

Signed-off-by: Harvey Tuch <htuch@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
fredlas pushed a commit to fredlas/envoy that referenced this issue Mar 5, 2019
…xy#5092)

This makes life easier when debugging SSL handshake issues.

Part of envoyproxy#1319.

Risk Level: Low
Testing: ssl_integration_test with debug and !debug.

Signed-off-by: Harvey Tuch <htuch@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
fredlas pushed a commit to fredlas/envoy that referenced this issue Mar 5, 2019
…nvoyproxy#5096)

Also, some bonus cleanups to improve DRY and maintainability of SSL related test code encountered
while doing this.

Part of envoyproxy#1319.

Risk Level: Low
Testing: bazel test //test/integration/..., new tests for client cipher suites and ECDSA server
  certs added to ssl_integration_test.

Signed-off-by: Harvey Tuch <htuch@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
fredlas pushed a commit to fredlas/envoy that referenced this issue Mar 5, 2019
This PR starts to plumb multiple TLS certs from the proto level into the SSL context. We stop short
of enabling multiple TLS certificates, but instead have sufficient mechanism and interface changes
to propagate them to the SSL context. Future PRs will extend this with the SSL context
implementation.

Risk Level: Low
Testing: bazel test //test/...

Part of envoyproxy#1319.

Signed-off-by: Harvey Tuch <htuch@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
fredlas pushed a commit to fredlas/envoy that referenced this issue Mar 5, 2019
This continues the plumbing needed for envoyproxy#1319. In this PR, we add support
to ContextImpl to handle multiple certs during configuration ingestion
and also the skeleton for the certificate switch that occurs following
ClientHello. There is no selection logic yet; this will be a followup
PR.

Risk Level: Low
Testing: bazel test //test/... No new tests, since we are not making a
major behavioral change, this is refactoring essentially.

Signed-off-by: Harvey Tuch <htuch@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
fredlas pushed a commit to fredlas/envoy that referenced this issue Mar 5, 2019
This PR adds support to ServerContextImpl::selectTlsContext(), allowing
for the selection of a certificate based on whether the client is RSA
and/or ECDSA capable from a list.

Since the list is still a singleton due to config ingest limitations,
we're still effectively single certificate, but this PR exercises the
logic that will be used in the multi-certificate selection case.
Ideally, there should be no observable behavioral changes.

Risk Level: Low (this should continue to fallback to the default
certificate, even if the ECDSA code is exercised).
Testing: Some new parameterized integration tests.

Part of envoyproxy#1319

Signed-off-by: Harvey Tuch <htuch@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
fredlas pushed a commit to fredlas/envoy that referenced this issue Mar 5, 2019
This PR wraps up envoyproxy#1319. The patch enables multiple TLS certificate
ingest for downstream TLS contexts, adds related unit and integration
tests, docs and release notes.

Risk Level: Low
Testing: Additional unit and integration tests. To avoid combinatorial
explosion, we validate mixed TLS v1.2/1.3 behavior in
ssl_integration_test only, and have more targeted certificate
selection tests in ssl_socket_Test.
Docs Changes: Added to architectural overview of TLS support.

Fixes envoyproxy#1319.

Signed-off-by: Harvey Tuch <htuch@google.com>
Signed-off-by: Fred Douglas <fredlas@google.com>
jpsim pushed a commit that referenced this issue Nov 28, 2022
Description: Based on some testing, if an `Engine` is not free'd before a Python process exits the it will crash on exit. This can happen while globally caching an instance of the `Engine`, for example. This PR exposes a `terminate` method that can be called on exit with [atexit](https://docs.python.org/3/library/atexit.html) for example.
Risk Level: Low
Testing: Pending

Signed-off-by: Cerek Hillen <chillen@lyft.com>
Signed-off-by: JP Simard <jp@jpsim.com>
jpsim pushed a commit that referenced this issue Nov 29, 2022
Description: Based on some testing, if an `Engine` is not free'd before a Python process exits the it will crash on exit. This can happen while globally caching an instance of the `Engine`, for example. This PR exposes a `terminate` method that can be called on exit with [atexit](https://docs.python.org/3/library/atexit.html) for example.
Risk Level: Low
Testing: Pending

Signed-off-by: Cerek Hillen <chillen@lyft.com>
Signed-off-by: JP Simard <jp@jpsim.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants