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 for transparent SNI proxying #6

Open
mediocregopher opened this issue Jul 24, 2023 · 4 comments
Open

Support for transparent SNI proxying #6

mediocregopher opened this issue Jul 24, 2023 · 4 comments

Comments

@mediocregopher
Copy link

This is more of a PR than an issue, since I've implemented the code already, but it's in a separate server:

https://code.betamike.com/micropelago/tokio-rustls/commit/18fd688b335430e17e054e15ff7d6ce073db2419

Implement TransparentConfigAcceptor

The goal of the TransparentConfigAcceptor is to support an SNI-based
reverse-proxy, where the server reads the SNI and then transparently
forwards the entire TLS session, ClientHello included, to a backend
server, without terminating the TLS session itself.

This isn't possible with the current LazyConfigAcceptor, which only
allows you to pick a different ServerConfig depending on the SNI, but
will always terminate the session.

The TransparentConfigAcceptor will buffer all bytes read from the
connection (the ClientHello) internally, and then replay them if the
user decides they want to hijack the connection.

The TransparentConfigAcceptor supports all functionality that the
LazyConfigAcceptor does, but due to the internal buffering of the
ClientHello I did not want to add it to the LazyConfigAcceptor, since
it's possible someone wouldn't want to incur that extra cost.

I'm very much open to feedback on these changes. I'm relatively new to rust, and would not be surprised if I overcomplicated this a bit. In particular the types I added to common seem like stuff that should already exist in some standard crate somewhere, but I couldn't find them, and probably my implementation is lacking. Also the API I've introduced generally seems kind of ugly to me... there's probably some way to clean it up some.

@quininer
Copy link
Member

It looks like all you need is a reader that caches the bytes read, which doesn't need to be in tokio-rustls, you can put it in your own crate.

@mediocregopher
Copy link
Author

@quininer can you describe a bit more how that would work? From what I understand of how the LazyConfigAcceptor works, once accept has returned here I'm not able to get the raw IO stream back (via take_io), which means it's not possible with the existing API to get back the raw IO stream while also having access to the ClientHello.

Maybe I could pass a RefCell into the LazyConfigAcceptor though... that could work as a one-off solution. But is this not a use-case the crate would want to support in a cleaner way?

@quininer
Copy link
Member

quininer commented Jul 26, 2023

@mediocregopher see tokio-rs/tls#144 (comment)

We can access &mut IO via Accept, but it would be nice to provide an into_inner to StartHandshake as well.

@mediocregopher
Copy link
Author

mediocregopher commented Jul 27, 2023

Thanks, that makes sense. I've made a new branch with that change here: https://code.betamike.com/micropelago/tokio-rustls/commit/3d462a1d97836cdb0600f0bc69c5e3b3310f6d8c

and moved all the rest of the AsyncRead wrapping code into my application.

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

No branches or pull requests

2 participants