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

Listener filter to terminate HTTP CONNECT #19077

Closed
liverbirdkte opened this issue Nov 22, 2021 · 9 comments
Closed

Listener filter to terminate HTTP CONNECT #19077

liverbirdkte opened this issue Nov 22, 2021 · 9 comments
Labels
area/http area/listener enhancement Feature requests. Not bugs or questions. stale stalebot believes this issue/PR has not been touched recently

Comments

@liverbirdkte
Copy link
Contributor

Title: Listener filter to terminate HTTP CONNECT

Description:
Envoy has CONNECT support for tunneling raw TCP traffic. I have a new use case, when Envoy is used as forward proxy for HTTPS upstreams, expect Envoy terminates initial CONNECT request and subsequent downstream TLS connection. This makes extra filters like security check work for downstream traffic.

The TLS termination part with mimic cert is covered by #18928.

We still need a way to terminate CONNECT request. Currently this could be done with two listeners work together, first one terminates CONNECT and forwards traffic to second listener which does TLS termination. But this approach has some drawbacks of efficiency and resource consumption, I know lambdai is working on improving this with internal connection, but it seems virtual connection supporting SSL requires lots of work.

I'm wondering if we could handle this case in a single listener by adding a listener filter to terminate HTTP CONNECT request. The new listener filter detects if incoming request is a CONNECT, sets related stats(e.g., requested server name) and does CONNECT termination by replying with a HTTP response to client.

Thanks

@liverbirdkte liverbirdkte added enhancement Feature requests. Not bugs or questions. triage Issue requires triage labels Nov 22, 2021
@kyessenov
Copy link
Contributor

kyessenov commented Nov 22, 2021

This would be useful to also impose a stronger security posture by limiting HTTP processing to just CONNECT instead of exposing cross-cutting HCM features.

Why do you think internal connection has problems with TLS? It's possible to layer TLS in CONNECT in TLS with internal connection. On the other hand, listener filters do not support termination of outer TLS (see #18035).

@RyanTheOptimist RyanTheOptimist added area/http area/listener and removed triage Issue requires triage labels Nov 22, 2021
@RyanTheOptimist
Copy link
Contributor

cc: @alyssawilk

@liverbirdkte
Copy link
Contributor Author

liverbirdkte commented Nov 25, 2021

@kyessenov I got the impression that SSL support is not in the initial version of internal connecion from #11725, please correct me if I got something wrong.

Let me describe this listener filter with more details. Actually there are two scenarios for this TLS termination use case, Envoy as a sidecar and forward proxy, the only difference between these two scenarios is whether the initial CONNECT request exists. I'm looking for an Envoy configuration to cover two scenarios in a single listener.
The configuration may look like this:

listener_filters:
- name: envoy.filters.listener.connect_terminator
  name: envoy.filters.listener.tls_inspector
filter_chains:
- filter_chain_match:
     server_names = ["google.com"]
  filters:
  - name: envoy.filters.network.http_connection_manager
      ...
    http_filters:
      ...

If incoming request is CONNECT, connect terminator sets server names with request url, terminates CONNECT and skip.
If incoming request is TLS ClientHello, connect terminator does nothing but leaves the request to tls inspector.

@alyssawilk
Copy link
Contributor

Yep, one could have a listener filter that removes HTTP/1.1 CONNECT headers similar to how we strip proxy proto, though it's obviously not going to work for HTTP/2 and HTTP/3

@liverbirdkte
Copy link
Contributor Author

@alyssawilk why is this not gonna work for HTTP/2 and HTTP/3, too complex for a listener filter?

@alyssawilk
Copy link
Contributor

Yeah. HTTP/1.1 CONNECT has one logical stream per connection - you strip the initial connect request and everything behind it is TCP payload. HTTP/2 has many streams on one connection, and you would need to basically reimplement the HCM as a listener filter

@liverbirdkte
Copy link
Contributor Author

@alyssawilk, thanks for the comments. If it's fine to have this listener filter, I could start with some code to terminate HTTP/1.1 CONNECT.

@github-actions
Copy link

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or "no stalebot" or other activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale stalebot believes this issue/PR has not been touched recently label Dec 31, 2021
@github-actions
Copy link

github-actions bot commented Jan 7, 2022

This issue has been automatically closed because it has not had activity in the last 37 days. If this issue is still valid, please ping a maintainer and ask them to label it as "help wanted" or "no stalebot". Thank you for your contributions.

@github-actions github-actions bot closed this as completed Jan 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/http area/listener enhancement Feature requests. Not bugs or questions. stale stalebot believes this issue/PR has not been touched recently
Projects
None yet
Development

No branches or pull requests

4 participants