-
Notifications
You must be signed in to change notification settings - Fork 271
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 support for SPIFFE TLS Ids #2520
Conversation
Signed-off-by: Zahari Dichev <[email protected]>
/// well. | ||
/// Practically speaking, this could be: | ||
/// - a DNS-like identity string that matches an x509 DNS SAN | ||
/// - a SPIFFE ID in URI form, that matches an x509 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that matches an x509...what?
Dns(linkerd_dns_name::Name), | ||
Uri(http::Uri), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style nit, take it or leave it: consider maybe just moving the bulleted list to comments on the variants?
Dns(linkerd_dns_name::Name), | |
Uri(http::Uri), | |
/// A a DNS-like identity string that matches an x509 DNS SAN. | |
Dns(linkerd_dns_name::Name), | |
/// A SPIFFE ID in URI form, that matches an x509 | |
Uri(http::Uri), |
Dns(linkerd_dns_name::Name), | ||
Uri(http::Uri), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the Id::Uri
variant intended to be SPIFFE-specific? we might want to name the variant something like SpiffeUri
or Spiffe
, to make that clearer, especially if we later support other identity mechanisms that also use URIs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would argue that this type shouldn't make any SPIFFE requirements. That seems like more of an x509-handling concern than a restriction we care about in linkerd's core types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, that's kind of the question I was getting at --- I wasn't sure whether this variant represented a spiffe-specific thing or not.
// TODO support spiffe:// URIs. | ||
if s.starts_with(SPIFFE_URI_SCHEME) { | ||
// TODO: we need to ensure the SPIFFE id is valid | ||
// according to requirements otlined in: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo:
// according to requirements otlined in: | |
// according to requirements outlined in: |
self.0.as_str().into() | ||
match self { | ||
Self::Dns(dns) => dns.as_str().into(), | ||
Self::Uri(uri) => uri.to_string().into(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's quite unfortunate that this allocates (in to_string()
) --- the DNS version just borrows the string. AFAICT there is no way to borrow an underlying string from an http::Uri
, as the parts of the URI may have come from different string slices --- it's intended more as a builder for URIs to be sent in HTTP requests.
i wonder if representing the Uri
variant using http::Uri
is actually the best representation, since we use Id::to_str
a lot, and it's a shame to have to allocate a new String
to format the URI into every time we want to log it or whatever. we could, alternatively, change the representation to store both an http::Uri
and an Arc<str>
or something, so that the formatting of the URI into a string representation only happens once, and subsequent to_str
calls just borrow that? I dunno...
let der = cert | ||
.to_der() | ||
.map_err( | ||
|error| tracing::warn!(%error, "Failed to encode client end cert to der"), | ||
) | ||
.ok()?; | ||
|
||
util::client_identity(&der).map(ClientId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIOLI: might be nicer as
let der = cert | |
.to_der() | |
.map_err( | |
|error| tracing::warn!(%error, "Failed to encode client end cert to der"), | |
) | |
.ok()?; | |
util::client_identity(&der).map(ClientId) | |
match cert.to_der() { | |
Ok(der) => util::client_identity(&der).map(ClientId), | |
Err(error) => { | |
tracing::warn!(%error, "Failed to encode client end cert to der"); | |
None | |
} | |
} |
@@ -1,11 +1,19 @@ | |||
[package] | |||
name = "linkerd-meshtls-test-util" | |||
name = "linkerd-meshtls-util" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, take it or leave it: i might have called this linkerd-meshtls-core
, following the naming scheme we use elsewhere in the project?
@@ -18,7 +19,7 @@ pub struct Metadata { | |||
tagged_transport_port: Option<u16>, | |||
|
|||
/// How to verify TLS for the endpoint. | |||
identity: Option<ServerId>, | |||
identity: Option<(ServerId, ServerName)>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we perhaps change this to store a tls::ClientTls
? This also opens the option to pass through ALPN settings (later).
tls: Option<tls::ClientTls>,
I'd hope this makes the handling of names/ids less verbose throughout most of the app code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would also make sense as a discrete change to help minimize the diff we need to consider for URI handling.
|
||
fn extract_ids_from_cert(cert: &[u8]) -> Result<Vec<Id>> { | ||
use x509_parser::prelude::*; | ||
let (_, c) = X509Certificate::from_der(cert)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this changes our DNSName validation, I think we should make this change discretely from the rest of this PR. I.e. a targetted PR that adds a new linkerd-meshtls-verifier
crate using x509_parser, without URI handling.
This PR adds support for TLS ids that are in SPIFFE format (URI). Notable changes:
llinkerd-meshtls-util
)linkerd_identity::Id
type has been turned into an enum that can be either a DNS URI typeMetadata
type now carries both ServerName and ServerId information