diff options
| author | srdusr <[email protected]> | 2026-06-24 14:40:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2026-06-24 14:40:00 +0200 |
| commit | e01afcbf0de00af52fe90959ba77288679e3303d (patch) | |
| tree | 073ff1430af629e28556a6f651ee47f6989376da /PLAN.md | |
| parent | 23c8ab359c2108654d57176e233d2c099b398f31 (diff) | |
| download | mitmux-e01afcbf0de00af52fe90959ba77288679e3303d.tar.gz mitmux-e01afcbf0de00af52fe90959ba77288679e3303d.zip | |
SOCKS5 upstream proxy chaining
Extends -upstream-proxy to accept a socks5://[user:pass@]host:port
prefix, using golang.org/x/net/proxy (already an indirect dependency
via http2, so no new module) rather than hand-rolling the client side
of RFC 1928/1929. parseSOCKS5 is the single place that decides which
kind of upstream a given UpstreamProxy string names; dialViaProxy
(CONNECT/TLS path) and dialUpstreamPlain (plain-HTTP path) both check
it first and fall through to the existing HTTP CONNECT behavior
otherwise. SOCKS5 needs no absolute-form request adjustment on the
plain-HTTP path the way HTTP-proxy chaining does, since it tunnels
straight to the target rather than expecting a proxy-aware request.
Tested against a real, minimal SOCKS5 server built for the test suite
(exercises dialSOCKS5's actual wire behavior, not a mock of the
client library), plus live against a real standalone SOCKS5 relay
process: both a plain HTTP and an HTTPS request through mitmux were
confirmed, via the relay's own log, to have actually traversed it.
Diffstat (limited to 'PLAN.md')
| -rw-r--r-- | PLAN.md | 18 |
1 files changed, 16 insertions, 2 deletions
@@ -190,7 +190,17 @@ Upstream proxy chaining: `-upstream-proxy host:port` (optional `http://` prefix, stripped) routes every outbound connection through another HTTP CONNECT proxy instead of dialing origins directly - chaining mitmux into Burp, a corporate proxy, or any other -CONNECT-speaking proxy. SOCKS5 upstreams aren't implemented. For the +CONNECT-speaking proxy. A `socks5://[user:pass@]host:port` prefix +routes through a SOCKS5 proxy instead (Tor, `ssh -D`, any other SOCKS5 +relay), via golang.org/x/net/proxy - already an indirect dependency +through http2, so no new module. parseSOCKS5 is the single place that +decides which kind of upstream a given UpstreamProxy string names; +dialViaProxy (CONNECT/TLS path) and dialUpstreamPlain (plain-HTTP +path) both check it first and fall through to the existing HTTP-proxy +behavior otherwise. SOCKS5 is transport-level and protocol-agnostic - +the tunnel it hands back behaves exactly like a direct connection to +the target, so unlike HTTP-proxy chaining it needs no absolute-form +request adjustment on the plain-HTTP path either. For the CONNECT/HTTPS path, chaining is transparent below the tunnel: once the CONNECT handshake to the upstream proxy succeeds, TLS and the request/response on top of it are identical to a direct connection, so @@ -210,7 +220,11 @@ genuine passthrough CONNECT proxy (tunnels raw bytes, no MITM) works correctly for both plain HTTP and HTTPS; chaining through a second mitmuxd instance correctly fails with a clear "certificate signed by unknown authority" error recorded in history, -rather than hanging or crashing. +rather than hanging or crashing. SOCKS5 chaining verified the same +way, live, against a real standalone SOCKS5 relay process (not an +in-test mock): both a plain HTTP request and an HTTPS request through +mitmux were confirmed - via the relay's own log, not just mitmux's +success response - to have actually traversed it end to end. This closes every item from the original "worth considering" list. |