sshuttle v0.78.5 releases: Transparent proxy server

sshuttle: where transparent proxy meets VPN meets ssh

A transparent proxy server that works as a poor man’s VPN. Forwards over ssh. Doesn’t require admin. Works with Linux and MacOS. Supports DNS tunneling.

sshuttle is the only program that solves the following common case:

  • Your client machine (or router) is Linux, FreeBSD, or MacOS.
  • You have access to a remote network via ssh.
  • You don’t necessarily have admin access on the remote network.
  • The remote network has no VPN, or only stupid/complex VPN protocols (IPsec, PPTP, etc). Or maybe you are the admin and you just got frustrated with the awful state of VPN tools.
  • You don’t want to create an ssh port forward for every single host/port on the remote network.
  • You hate openssh’s port forwarding because it’s randomly slow and/or stupid.
  • You can’t use openssh’s PermitTunnel feature because it’s disabled by default on openssh servers; plus it does TCP-over-TCP, which has terrible performance (see below).

sshuttle is not exactly a VPN and not exactly port forwarding. It’s kind of both, and kind of neither.

It’s like a VPN since it can forward every port on an entire network, not just ports you specify. Conveniently, it lets you use the “real” IP addresses of each host rather than faking port numbers on localhost.

On the other hand, the way it works is more like ssh port forwarding than a VPN. Normally, a VPN forwards your data one packet at a time, and doesn’t care about individual connections; ie. it’s “stateless” with respect to the traffic. sshuttle is the opposite of stateless; it tracks every single connection.

You could compare sshuttle to something like the old Slirp program, which was a userspace TCP/IP implementation that did something similar. But it operated on a packet-by-packet basis on the client side, reassembling the packets on the server side. That worked okay back in the “real live serial port” days because serial ports had predictable latency and buffering.

But you can’t safely just forward TCP packets over a TCP session (like ssh) because TCP’s performance depends fundamentally on packet loss; it must experience packet loss in order to know when to slow down! At the same time, the outer TCP session (ssh, in this case) is a reliable transport, which means that what you forward through the tunnel never experiences packet loss. The ssh session itself experiences packet loss, of course, but TCP fixes it up and ssh (and thus you) never know the difference. But neither does your inner TCP session, and extremely screwy performance ensues.

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.

Changelog v0.78.5

* doas support as replacmeent for sudo on OpenBSD.
* Added ChromeOS section to documentation (#262)
* Add –no-sudo-pythonpath option

* Fix forwarding to a single port.
* Various updates to documentation.
* Don’t crash if we can’t look up peername
* Fix missing string formatting argument
* Moved sshuttle/tests into tests.
* Updated bandit config.
* Replace path /dev/null by os.devnull.
* Added coverage report to tests.
* Fixes support for OpenBSD (6.1+) (#282).
* Close stdin, stdout, and stderr when using syslog or forking to daemon (#283).
* Changes pf exclusion rules precedence.
* Fix deadlock with iptables with large ruleset.
* docs: document –ns-hosts –to-ns and update –dns.
* Use subprocess.check_output instead of run.
* Fix potential deadlock condition in nft_get_handle.
* auto-nets: retrieve routes only if using auto-nets.


sudo pip install sshuttle
git clone
cd sshuttle
sudo ./ install


Forward all traffic:

sshuttle -r username@sshserver

  • Use the sshuttle -r parameter to specify a remote server.
  • By default, sshuttle will automatically choose a method to use. Override with the sshuttle –method parameter.
  • There is a shortcut for for those that value their wrists:
    sshuttle -r username@sshserver 0/0

If you would also like your DNS queries to be proxied through the DNS server of the server you are connected to:

sshuttle –dns -r username@sshserver 0/0

The above is probably what you want to use to prevent local network attacks such as Firesheep and friends. See the documentation for the sshuttle –dns parameter.


Copyright 2016, Brian May