httptoolkit / mockttp

Powerful friendly HTTP mock server & proxy library
https://httptoolkit.com
Apache License 2.0
757 stars 85 forks source link

TLS passthrough upstream proxying #174

Open mtsvetanoff opened 3 weeks ago

mtsvetanoff commented 3 weeks ago

Greetings.

Some context:

  1. TLS passthrough is enabled for all hostnames
  2. All requests are configured to go through an upstream proxy

In these circumstances one would expect that a request would not be modified by Mockttp, but it will still respect the upstream proxy configuration.

But it appears that when TLS passthrough is enabled then the requests are not being routed through an upstream proxy.

Is there a way I could configure Mockttp to behave in the expected way?

Regards

pimterry commented 3 weeks ago

Request rules (including passthrough rules with proxy configuration) are applied only to traffic that's actually intercepted (because rules can match requests by their content, and make modifications to that content etc) and TLS passthrough skips interception entirely, so your rule is being ignored here.

Right now, there's no possible way to proxy traffic that's passed through unintercepted. If you want to forward to an upstream proxy, you'll need to intercept the traffic and use a passthrough rule.

Although it's not currently supported in Mockttp, it is technically possible to proxy unintercepted traffic like this in most cases, but not all. The issue is that with TLS passthrough, the only info we have on the real destination of the traffic is the server name indication (SNI) in the TLS handshake, which is just a hostname without a port (unlike when we intercept an actual request, which has a Host header that does actually include the port). If the request came from a CONNECT tunnel then that tunnel will have the port info, so that's fine, but if you're passing through direct requests (acting as a transparent proxy) then that won't be the case, and you'll have to just guess the port.

If this is something you're interested in, contributions are welcome, it would definitely be possible to add a proxy field to the TLS passthrough option to configure this there (assuming the destination port to be 443 anywhere it's not otherwise available). We already have proxy logic that could probably be reused to power this. Note the HTTP Toolkit Pro is free for all open-source contributors to anything in this GitHub org.

mtsvetanoff commented 3 weeks ago

The request should be a CONNECT one, because Mockttp is set as a --proxy-server argument for Chrome which creates a tunnel. I assume by "direct requests" you mean directly sending a GET/POST request to Mockttp? If so then that's not the case here.

Unfortunatelly I am not familiar with the innerworkings of the library and could not contribute such an update as much as I want to.

I am currently using a different library in the exact same setup which works fine (so should be achievable) but lacks functionality. However without the upstream proxy + TLS passthrough both working, switching to Mockttp is impossible.

pimterry commented 3 weeks ago

I assume by "direct requests" you mean directly sending a GET/POST request to Mockttp? If so then that's not the case here.

Exactly. That is generally the case for lots of other interception scenarios though unfortunately (e.g. VPN-powered interception on Android, or Frida-based traffic redirection) so it does need consideration for Mockttp itself.

Unfortunately I am not familiar with the inner workings of the library and could not contribute such an update [...] However without the upstream proxy + TLS passthrough both working, switching to Mockttp is impossible.

Fair enough. Unfortunately though this isn't supported right now, and I'm unlikely to have time to work on that anytime soon, so you'll need to either dig into Mockttp's internals and contribute it yourself, pay somebody else to do so, or use a different library I'm afraid.

The feature certainly makes sense though, and I'd be happy to review & merge a PR for this if anybody is interested in contributing. We can keep this open in case anybody else wants this feature and is interested in opening a PR in future.

mtsvetanoff commented 3 weeks ago

Got it. It will likely take me ages to implement it on my own, although I will give it a shot. Leaving the issue open.

Thank you for your response and work on this amazing library!