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

tls: add DetectSni middleware #3199

Merged
merged 6 commits into from
Sep 25, 2024
Merged

tls: add DetectSni middleware #3199

merged 6 commits into from
Sep 25, 2024

Conversation

zaharidichev
Copy link
Member

@zaharidichev zaharidichev commented Sep 11, 2024

This change adds a new DetectSni middleware to be used in the outbound stack
in order to extract the SNI extension from the ClientHello of a TLS session and apply
routing decisions based on it.

In contrast to DetectTls this new middleware is concerned with just extracting the SNI
as opposed to terminating the TLS session.

Signed-off-by: Zahari Dichev [email protected]

@zaharidichev zaharidichev requested a review from a team as a code owner September 11, 2024 10:58
Signed-off-by: Zahari Dichev <[email protected]>
Copy link
Member

@olix0r olix0r left a comment

Choose a reason for hiding this comment

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

I'm a little skeptical on modifying the existing behavior--trying to decouple detection and termination, because the termination ends up being highly contingent on the other layer setting it up properly--we end up exposing a bunch of the implementation details outside the module, which is complex.

It seems like we probably need to get something exposed that only reads the SNI. The TLS server module can probably reuse some internals, but it would probably be easier to focus on adding something that does exactly what we need it do and only on that so we don't incur additional type complexity.

@@ -107,27 +84,27 @@ impl<L, P, N> NewDetectTls<L, P, N> {
}
}

impl<T, L, P, N> NewService<T> for NewDetectTls<L, P, N>
impl<T, L, P, N> NewService<(T, Option<ServerName>)> for NewDetectTls<L, P, N>
Copy link
Member

Choose a reason for hiding this comment

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

Using a tuple-target is a bit of an anti-pattern: it's fragile and doesn't really permit any intermediate layers to work. It may be appropriate here if we can bundle it up so that it's opaque to the caller, but it's preferable to use a Param or ExtractParam to get a ServerName from the target.

params: self.params.clone(),
inner: self.inner.clone(),
}
}
}

impl<I, T, L, LIo, P, N, NSvc> Service<I> for DetectTls<T, L, P, N>
impl<I, T, L, LIo, P, N, NSvc> Service<DetectIo<I>> for DetectTls<T, L, P, N>
Copy link
Member

Choose a reason for hiding this comment

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

This no longer detects really, right? Should this be renamed to reflect what it does?

It's also pretty awkward to me that we pass an optional SNI and the local identity here and then at process-time we check whether we should actually do TLS termination.

@zaharidichev
Copy link
Member Author

I'm a little skeptical on modifying the existing behavior--trying to decouple detection and termination

@olix0r Makes sense. I have reverted these commits and pushed a simpler version that just adds a DetectSni middleware that makes use of the bits and pieces in the server module. Also, I have incorporated your feedback about tupled targets and tried to rely on InsertParam.

Not sure whether we want to just move all sni and client hellos internals into their own module that is used by both server and detect_sni or keep it as it is to minimize the change.

One option is to have the following mods:

  • extract_sni - contains the detect_sni function + client hello details + tests
  • server - contains TLS termination logic, etc
  • detect_sni - contains the middleware to detect the sni.

WDYT?

This reverts commit d909be7.

Signed-off-by: Zahari Dichev <[email protected]>
This reverts commit 6c07804.

Signed-off-by: Zahari Dichev <[email protected]>
pub struct DetectSni<T, P, N> {
target: T,
inner: N,
timeout: Timeout,
Copy link
Member

Choose a reason for hiding this comment

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

I'm curious about the timeout handling here and whether this should be instrumented here. On a known TLS connection, what do we do in the face of a timeout? Error? The timeout case exists on the existing detection logic so that we can forward connections as opaque after a timeout elapses, but there's no such fallback logic here, is there? I'd probably have to go back to the higher level draft PR to get a sense of how this fits together, but my gut instinct is that we do not need a timeout here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. So yes, essentially we would error with a SniDetectionTimeoutError if the timeout elapses. Does that make sense here?

@olix0r
Copy link
Member

olix0r commented Sep 25, 2024

Please update the commit message subject and description before merging: this no longer 'splits' TLS detection logic, we're adding a new DetectSni middleware to the TLS crate... The commit message body should include brief description of what this middleware does.

@zaharidichev zaharidichev changed the title chore: split TLS detection logic tls: add DetectSni middleware Sep 25, 2024
@zaharidichev zaharidichev merged commit fa4c8dc into main Sep 25, 2024
15 checks passed
@zaharidichev zaharidichev deleted the zd/split-tls-detection branch September 25, 2024 15:36
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.

2 participants