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

Is it possible to use caddy's modules inside L4 routes? #222

Open
stronny opened this issue Jul 24, 2024 · 12 comments
Open

Is it possible to use caddy's modules inside L4 routes? #222

stronny opened this issue Jul 24, 2024 · 12 comments

Comments

@stronny
Copy link

stronny commented Jul 24, 2024

I'm prepared to try my hand at implementing it, but I want to ask first. Basically, I need caddy's reverse_proxy inside L4's route as a handler. This is because I want to pass mTLS fields upwards, and I use tls handler to terminate TLS inside L4, so caddy's http server doesn't see the certificate anymore and I can't think of an easy way to pass them along akin to PROXY protocol. This would also eliminate the need to listen on a separate port to loop a request back from L4 to http, but that's not the main point.

Any thoughts?

@mholt
Copy link
Owner

mholt commented Jul 24, 2024

There's WIP (stalled currently though) that will allow you to pipe your L4 connection directly to your HTTP server without opening another socket: caddyserver/caddy#5040

@stronny
Copy link
Author

stronny commented Jul 24, 2024

This is cool, but will it address the main point? I need to add headers to an HTTPS request that should contain mTLS fields, like subject, will the piping allow for that?

@mholt
Copy link
Owner

mholt commented Jul 24, 2024

I don't see the original post mentioned anything about adding HTTP headers; so you actually want to transfer data from the mTLS handshake to the HTTP headers for an HTTP proxy to send to an upstream?

@stronny
Copy link
Author

stronny commented Jul 25, 2024

Headers would be the way to "pass mTLS fields upwards". Yes, I want to:

  • terminate TLS inside an L4 route
  • add headers to the HTTP request inside the TLS stream
  • reverse proxy it onwards as HTTP

@mholt
Copy link
Owner

mholt commented Aug 9, 2024

That should be possible. When the TLS matcher is used, it sets placeholders. We may need to add the fields you want to the replacer though:

// also add values to the replacer
repl := cx.Context.Value(layer4.ReplacerCtxKey).(*caddy.Replacer)
repl.Set("l4.tls.server_name", chi.ClientHelloInfo.ServerName)
repl.Set("l4.tls.version", chi.Version)

@stronny
Copy link
Author

stronny commented Aug 9, 2024

What do I do with the placeholders though? L4 doesn't have a concept of HTTP as far as I'm aware, right?

@mholt
Copy link
Owner

mholt commented Aug 23, 2024

L4 has the "concept" of it in that it can match HTTP and get info from it, but it doesn't implement HTTP semantics like an HTTP server does.

If you want to manipulate the HTTP request you'll use the HTTP server. The HTTP server provides its own placeholders.

@stronny
Copy link
Author

stronny commented Aug 23, 2024

Yes, but at that point I don't have the SSL information anymore. Once gain, here's the overview of the caddy config:

client --(TLS)--> L4 app --(PROXY protocol)--> HTTP app --(HTTP)--> server

I want the upstream server to receive the information about the client's SSL certificate.

@mholt
Copy link
Owner

mholt commented Aug 23, 2024

I guess it begs the question as to why you need to terminate TLS in the layer4 app then. The HTTP app also supports PROXY protocol... if you terminate TLS there then you should be able to do what you want.

@stronny
Copy link
Author

stronny commented Aug 23, 2024

The PROXY protocol is just a vehicle to pass the client's address upstream, it doesn't leave Caddy. I do a lot of things in L4, so TLS has to stay there.

Besides, it separates the stack layers cleanly, unlike doing everything inside http. It is both aesthetically pleasing, and very useful, the only problem with this separation being that there is no obvious mechanism to pass values around.

@mholt
Copy link
Owner

mholt commented Aug 23, 2024

Can you just not terminate the requests that need HTTP requests manipulated?

I don't have a way to carry data between the apps yet, for a given connection... it's also weird because multiple requests can come in on a single connection, so what happens to the second request? It would already be handed off to the HTTP app at that point.

There would be some questions left to answer before it's clearly feasible.

@stronny
Copy link
Author

stronny commented Aug 23, 2024

The whole connection is using the same mTLS cert, just as it does have the same IP address.

I suppose I can just invent my own protocol, but it seems like an unfortunate solution.

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