sshuttle claims that it solves much discussed problem of TCP-over-TCP meltdown.
sshuttle assembles the TCP stream locally, multiplexes it statefully over an ssh session, and disassembles it back into packets at the other end. So it never ends up doing TCP-over-TCP. It’s just data-over-TCP, which is safe.
But from the point of view of a program it maintains a TCP connection to a target server with all that comes with it (read exponential timeouts), which is layered about other TCP session since SSH doesn't yet just work on udp
. This very much looks like TCP-over-TCP.
What is the trick here? Is the problem really solved by sshuttle?
I tried reading source code, but so far didn't find the answer.
More importantly, how exactly do they do it? If one wants to reimplement it in barebones, where one should look for inspiration?
sshuttle
client sets up firewall rules(iptables in Linux, that's whysshuttle
client need root privilege) to redirect certain outgoing TCP connections to a local port(12300 by default), you can see this process when starting sshuttle:And remove iptables nat rules when sshuttle exits,
the TCP contents are picked up and multiplexed over the ssh connection to the
sshuttle
server, then de-multiplexed into connections again. The functiononaccept_tcpin
in client.py do the mux:You can see how the data is packed in ssnet.py.
I've seen the same strategy(I mean setting up firewall rules) in redsocks which aims at redirecting any TCP connection to SOCKS or HTTPS proxy.