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

meshtls: Add a boring backend #1351

Merged
merged 95 commits into from
Nov 8, 2021
Merged

meshtls: Add a boring backend #1351

merged 95 commits into from
Nov 8, 2021

Conversation

olix0r
Copy link
Member

@olix0r olix0r commented Nov 2, 2021

This change adds a meshtls-boring proxy feature that can be used to
compile the proxy with an alternate TLS implementation. The
meshtls-rustls feature should be disabled to take advantage of this
alternate backend.

In its current mode, the boring backend is compatible with the existing
identity credentials and algorithms (specifically TLSv1.3 and
ECDSA-P256-SHA256 with CHACHA20-POLY1305-SHA256).

In future changes--once boring has been updated--we can:

  • Improve error handling, especially for SSL errors
  • Relax deny.toml changes needed by bindgen features
  • Add a FIPS mode

Co-authored-by: @arnarpall

@olix0r olix0r changed the title identity: Add a boring-backed identity: Add a boring-backed mTLS implementation Nov 2, 2021
@olix0r
Copy link
Member Author

olix0r commented Nov 2, 2021

Related cloudflare/boring#55

olix0r added a commit that referenced this pull request Nov 3, 2021
In #1351, we add an alternate identity/mtls implementation that uses
`boring`. To setup for that, this change introduces a new `meshtls`
crate that serves as a facade for application crates to depend on,
independently of the actual crypto implementation.

This change does not change any runtime logic and sets up for #1351 to
enable an alternate TLS implementation as a build-time configuration.
In #1351, we add an alternate identity/mtls implementation that uses
`boring`. To setup for that, this change introduces a new `meshtls`
crate that serves as a facade for application crates to depend on,
independently of the actual crypto implementation.

This change does not change any runtime logic and sets up for #1351 to
enable an alternate TLS implementation as a build-time configuration.
hawkw added a commit that referenced this pull request Nov 3, 2021
This branch adds a simple nix-env configuration for building the proxy
locally on NixOS. This does *not* yet introduce a derivation for
*packaging* the proxy as a Nix package, just a nix-env for local
development for Nix users.

Actually packaging the proxy for Nix could be
fun, but it's not really necessary, since the proxy is not currently
distributed as a package for other package managers --- it's distributed
as a docker image. If we were going to actually distribute something as a
Nix package, it would be the Linkerd CLI (which could be worth doing!).

This branch *does* include the necessary configuration to build
`cloudflare/boring`, which is added as a dependency by @olix0r's
PR #1351. I've confirmed that it is possible to build that branch with
these configs, but I opened this as a separate PR against `main` so that
we can merge it separately. Currently, we do have to build `boringssl`
from source, rather than depending on it from nixpkgs, which is kind of
a bummer, but this can be fixed later.
olix0r and others added 17 commits November 8, 2021 15:28
This change adds a `meshtls-boring` proxy feature that can be used to
compile the proxy with an alternate TLS implementation. The
`meshtls-rustls` feature should be disabled to take advantage of this
alternate backend.

In its current mode, the boring backend is compatible with the existing
identity credentials and algorithms (specifically TLSv1.3 and
ECDSA-P256-SHA256 with CHACHA20-POLY1305-SHA256).

In future changes--once `boring` has been updated--we can:
- Improve error handling, especially for SSL errors
- Relax deny.toml changes needed by bindgen features
- Add a FIPS mode

Co-authored-by: Arnar Páll <[email protected]>
@olix0r olix0r marked this pull request as ready for review November 8, 2021 18:36
@olix0r olix0r requested a review from a team November 8, 2021 18:36
@olix0r olix0r changed the title identity: Add a boring-backed mTLS implementation meshtls: Add a boring backend Nov 8, 2021
@olix0r
Copy link
Member Author

olix0r commented Nov 8, 2021

@hawkw @arnarpall This change should be mergeable now (once CI clears). We run our normal end-to-end tests against the boring module and I've tested this branch manually as well.

This change does not include the FIPS functionality being discussed in cloudflare/boring#52; and it sounds like even once that change merges (if it lands in its current state), it will be difficult to build in that mode (as a FIPS-compliant boring library will have to be provided externally).

I haven't taken advantage of any of the recently changed error functionality either. We'll pick that up once boring does a proper crate release.

@arnarpall
Copy link
Contributor

@hawkw @arnarpall This change should be mergeable now (once CI clears). We run our normal end-to-end tests against the boring module and I've tested this branch manually as well.

This change does not include the FIPS functionality being discussed in cloudflare/boring#52; and it sounds like even once that change merges (if it lands in its current state), it will be difficult to build in that mode (as a FIPS-compliant boring library will have to be provided externally).

I haven't taken advantage of any of the recently changed error functionality either. We'll pick that up once boring does a proper crate release.

Truly awesome work.

I believe I could rework my original boring pull request once this one is merged where we hook into the boring build process to enable fips mode without having to to provide it externally. I'd like to get to a point where this is as transparent as possible

Copy link
Contributor

@hawkw hawkw left a comment

Choose a reason for hiding this comment

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

overall, this looks good to me. i had a couple questions and minor nits but nothing stood out as a blocker!

Dockerfile Show resolved Hide resolved
Comment on lines +51 to +53
# boring-sys pulls in an old version via bindgen. See
# https://github.com/cloudflare/boring/pull/55.
{ name = "ansi_term" },
Copy link
Contributor

Choose a reason for hiding this comment

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

nit/tioli: it seems like this might, potentially, be better expressed as a skip-tree entry for bindgen? that way, we still get an error on duplicate deps if they're from another crate.

not actually important, of course.

Copy link
Member Author

Choose a reason for hiding this comment

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

this would also ignore all other bindgen deps, though. I think the skip is narrower.

linkerd/meshtls/boring/src/client.rs Outdated Show resolved Hide resolved
Comment on lines +109 to +112
// XXX(ver) This function reads from the environment and/or the filesystem. This likely is
// at best wasteful and at worst unsafe (if another thread were to mutate these environment
// variables simultaneously, for instance). Unfortunately, the boring APIs don't really give
// us an alternative AFAICT.
Copy link
Contributor

Choose a reason for hiding this comment

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

do you know if this is something that can be fixed upstream in the boring crate, or is it a boringssl behavior that we can't avoid?

Copy link
Member Author

Choose a reason for hiding this comment

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

boring could probably have other constructors that don't load default trust anchors. I don't think it actually matters for us, in practice, though.

Copy link
Contributor

Choose a reason for hiding this comment

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

that's fair; it seems like something that could be worth opening an issue for, but maybe not worth putting effort into implementing?

Comment on lines +117 to +118
// XXX(ver) if we disable use of TLSv1.2, connections just hang.
//conn.set_options(ssl::SslOptions::NO_TLSV1_2);
Copy link
Contributor

Choose a reason for hiding this comment

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

should we report a bug for this upstream?

Copy link
Member Author

Choose a reason for hiding this comment

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

maybe? this is probably a bug in boringssl and not the rust bindings, if it's a bug.

Comment on lines +17 to +18
//! A new SSL context is created for each connection. This is probably
//! unnecessary, but it's simpler for now. We can revisit this if needed.
Copy link
Contributor

Choose a reason for hiding this comment

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

not a blocker at all, just curious: how much do we know about what this actually means? e.g. do we know what a "SSL context" in boring consists of, and what are the implications of creating them?

Copy link
Member Author

Choose a reason for hiding this comment

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

Some allocations + everything in the connector/acceptor constructors (i.e. trust anchors, private key, certs).

linkerd/meshtls/boring/src/server.rs Show resolved Hide resolved
linkerd/meshtls/boring/src/server.rs Outdated Show resolved Hide resolved
linkerd/meshtls/src/server.rs Show resolved Hide resolved
@olix0r olix0r merged commit 50003a4 into main Nov 8, 2021
@olix0r olix0r deleted the ver/boring branch November 8, 2021 21:44
olix0r added a commit to linkerd/linkerd2 that referenced this pull request Nov 9, 2021
This release updates the proxy's `rustls`, `ring`, and `webpki` dependencies.

Additionally, the proxy can now be built to use a `boringssl` backend
instead of the default `rustls` backend, but this functionality is
disabled in default builds.

---

* meshtls: replace build script with `compile_error!` macro (linkerd/linkerd2-proxy#1357)
* ci: Split actions into several workflows (linkerd/linkerd2-proxy#1356)
* ci: Make job names uniform (linkerd/linkerd2-proxy#1358)
* meshtls: allow building without any TLS impls enabled (linkerd/linkerd2-proxy#1359)
* `app-core` should not enable `meshtls-rustls` (linkerd/linkerd2-proxy#1360)
* Restore rustls credential tests (linkerd/linkerd2-proxy#1363)
* build(deps): bump hex from 0.3 to 0.4 (linkerd/linkerd2-proxy#1364)
* ci: Split jobs into 'fast' and 'slow' workflows (linkerd/linkerd2-proxy#1365)
* meshtls: Move TLS e2e tests into the meshtls crate (linkerd/linkerd2-proxy#1366)
* rustls: Tidy std::task imports (linkerd/linkerd2-proxy#1367)
* build(deps): bump serde_json from 1.0.68 to 1.0.69 (linkerd/linkerd2-proxy#1368)
* build(deps): bump libc from 0.2.106 to 0.2.107 (linkerd/linkerd2-proxy#1369)
* meshtls: Add a `boring` backend (linkerd/linkerd2-proxy#1351)
* meshtls-rustls: update to `rustls` 0.20 and `tokio-rustls` 0.23 (linkerd/linkerd2-proxy#1362)
olix0r added a commit to linkerd/linkerd2 that referenced this pull request Nov 9, 2021
This release updates the proxy's `rustls`, `ring`, and `webpki` dependencies.

Additionally, the proxy can now be built to use a `boringssl` backend
instead of the default `rustls` backend, but this functionality is
disabled in default builds.

---

* meshtls: replace build script with `compile_error!` macro (linkerd/linkerd2-proxy#1357)
* ci: Split actions into several workflows (linkerd/linkerd2-proxy#1356)
* ci: Make job names uniform (linkerd/linkerd2-proxy#1358)
* meshtls: allow building without any TLS impls enabled (linkerd/linkerd2-proxy#1359)
* `app-core` should not enable `meshtls-rustls` (linkerd/linkerd2-proxy#1360)
* Restore rustls credential tests (linkerd/linkerd2-proxy#1363)
* build(deps): bump hex from 0.3 to 0.4 (linkerd/linkerd2-proxy#1364)
* ci: Split jobs into 'fast' and 'slow' workflows (linkerd/linkerd2-proxy#1365)
* meshtls: Move TLS e2e tests into the meshtls crate (linkerd/linkerd2-proxy#1366)
* rustls: Tidy std::task imports (linkerd/linkerd2-proxy#1367)
* build(deps): bump serde_json from 1.0.68 to 1.0.69 (linkerd/linkerd2-proxy#1368)
* build(deps): bump libc from 0.2.106 to 0.2.107 (linkerd/linkerd2-proxy#1369)
* meshtls: Add a `boring` backend (linkerd/linkerd2-proxy#1351)
* meshtls-rustls: update to `rustls` 0.20 and `tokio-rustls` 0.23 (linkerd/linkerd2-proxy#1362)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants