meshtls: log errors parsing client certs (#2467)

Currently, if errors occur while parsing a client identity from a TLS
certificate, the `client_identity` function in `linkerd-meshtls-rustls`
will simply discard the error and return `None`. This means that we
cannot easily determine *why* a connection has no client identity ---
there may have been no client cert, but we may also have failed to parse
a client cert that was present.

In order to make debugging these issues a little easier, I've changed
this function to log any errors returned by `rustls-webpki` while
parsing client certs.
This commit is contained in:
Eliza Weisman 2023-09-27 11:24:32 -07:00 committed by GitHub
parent 16a75fe1c7
commit e92f325bb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 3 deletions

View File

@ -129,14 +129,26 @@ fn client_identity<I>(tls: &tokio_rustls::server::TlsStream<I>) -> Option<Client
let (_io, session) = tls.get_ref();
let certs = session.peer_certificates()?;
let c = certs.first().map(Certificate::as_ref)?;
let end_cert = webpki::EndEntityCert::try_from(c).ok()?;
let name: &str = end_cert.dns_names().ok()?.next().map(Into::into)?;
let end_cert = webpki::EndEntityCert::try_from(c)
.map_err(|error| tracing::warn!(%error, "Failed to parse client end-entity certificate"))
.ok()?;
let name: &str = end_cert
.dns_names()
.map_err(
|error| tracing::warn!(%error, "Failed to parse DNS names from client certificate"),
)
.ok()?
.next()
.map(Into::into)?;
if name == "*" {
// Wildcards can perhaps be handled in a future path...
return None;
}
name.parse().ok().map(ClientId)
name.parse()
.map_err(|error| tracing::warn!(%error, "Client certificate contained an invalid DNS name"))
.ok()
.map(ClientId)
}
// === impl ServerIo ===