Nowadays, business networks often use a VPN (virtual private network) for secure communications with workers. However, the protocols used can sometimes make performance slow. If you can reach reach a host on the remote network with SSH, you could set up port forwarding. But this can be painful, especially if you need to work with many hosts on that network. Enter sshuttle — which lets you set up a quick and dirty VPN with just SSH access. Read on for more information on how to use it.
The sshuttle application was designed for exactly the kind of scenario described above. The only requirement on the remote side is that the host must have Python available. This is because sshuttle constructs and runs some Python source code to help transmit data.
The sshuttle application is packaged in the official repositories, so it’s easy to install. Open a terminal and use the following command with sudo:
$ sudo dnf install sshuttle
Once installed, you may find the manual page interesting:
$ man sshuttle
Setting up the VPN
The simplest case is just to forward all traffic to the remote network. This isn’t necessarily a crazy idea, especially if you’re not on a trusted local network like your own home. Use the -r switch with the SSH username and the remote host name:
$ sshuttle -r username@remotehost 0.0.0.0/0
However, you may want to restrict the VPN to specific subnets rather than all network traffic. (A complete discussion of subnets is outside the scope of this article, but you can read more here on Wikipedia.) Let’s say your office internally uses the reserved Class A subnet 10.0.0.0 and the reserved Class B subnet 172.16.0.0. The command above becomes:
$ sshuttle -r username@remotehost 10.0.0.0/8 172.16.0.0/16
This works great for working with hosts on the remote network by IP address. But what if your office is a large network with lots of hosts? Names are probably much more convenient — maybe even required. Never fear, sshuttle can also forward DNS queries to the office with the –dns switch:
$ sshuttle --dns -r username@remotehost 10.0.0.0/8 172.16.0.0/16
To run sshuttle like a daemon, add the -D switch. This also will send log information to the systemd journal via its syslog compatibility.
Depending on the capabilities of your system and the remote system, you can use sshuttle for an IPv6 based VPN. You can also set up configuration files and integrate it with your system startup if desired. If you want to read even more about sshuttle and how it works, check out the official documentation. For a look at the code, head over to the GitHub page.
Photo by Kurt Cotoaga on Unsplash.
Could not get it to work on rawhide -> rawhide. OSerror: socket operation on non-socket or something, and also something about a deprecated python module. I was able to connect to my ISP’s shell server with it though (not sure if theyre happy about that) . With -vvv it tells you quite a bit about the network topo/connections on the server.
Due to some latency mitigation sshuttle is also pretty slow. It unfortunately doesn’t seem to be able to balance between latency and throughput so you have to choose one or the other. If you want throughput there is a cmdline option to disable the latency control.
Why not do port forwarding on regular SSH and use socks5 proxy?
Paul W. Frields
@Nick, the docs on the sshuttle site describe cases in which that is less performant. Check them out.
Vernon Van Steenkist
Didn’t find the word Socks in the sshutlle documentation. Please explain. Firefox, Thunderbird and others support an ssh created Socks5 proxy natively. Plus ssh created Socks5 procured work with any ssh server including Microsoft, Mac etc. without any additional software on the host.
If I understand it correctly, this is more than a proxy. It can tunnel all TCP traffic for particular hosts/ports over the VPN. This is different than a Socks5 proxy that only works from your browser, and has to be explicitly configured as such in your browser.
As the manpage (https://sshuttle.readthedocs.io/en/stable/manpage.html#discussion) says:
“Unlike most VPNs, sshuttle forwards sessions, not packets. That is, it uses kernel transparent proxying (iptables REDIRECT rules on Linux) to capture outgoing TCP sessions, then creates entirely separate TCP sessions out to the original destination at the other end of the tunnel.”
Vernon Van Steenkist
With proxychains, you only have to do one Socks 5 configuration. However, my main point is that ssh created Socks 5 proxies require no additional server side software and do not require root access and work with ssh servers on any platform. sshuttle is not an option if you do not have root access and Python on the server and want to re-direct TCP traffic.
Since sshuttle appears to require root access on both the client and server if you want to re-direct all traffic, including UDP, and additional software, why not just use openvpn instead? Openvpn can tunnel over an ssh created Socks 5 proxy and with a static key, has extremely fast connect times.
In addition, Python consumes a lot of CPU and memory resources whereas ssh proxies and openvpn can be efficiently run on routers with 32Mb of RAM and 8MB disk drives.
SShuttle does NOT require root access on the remote (server as you put it)
It is indeed a poor man’s VPN 🙂 Tried it on HomeBrew, keeps crashing.
Because then every client needs to be socksified either directly or through a shim library which is just more work. Sshuttle is transparent to all clients.
Stuart D Gathman
Addressing some of the previous comments:
I’m guessing the python code sent to the remote is not python3 compatible, and that is why it doesn’t work on rawhide.
socks is a fine product, but is not an alternative to sshuttle, which transparently redirects all TCP sessions.
The main limitation of sshuttle is that it only redirects TCP. Apps using UDP (e.g. VOIP) are out of luck. But for TCP, it is slick as a whistle.
When do I use sshuttle? When I find myself on one of those locked down WiFi setups that only let you “browse the web”. They do not let you connect on port 22, for instance. In preparation, you need to set up a server where you can login via SSH on port 443. The article should have mentioned this preparation. There is an HTTPS proxy that can distinguish between SSH and HTTPS, so you can use the same port for both.
Another possibility to escape is a web proxy allowing you to CONNECT to port 22 on a server where you have a login.
Stuart D Gathman
Oh cool. Looks like sshuttle supports UDP since last I checked some years ago. This article got me to check the man page. Thanks!
Use this rule:
$IPT -A INPUT -p tcp –dport 22 -m state –state NEW -s 0.0.0.0/0 -j ACCEPT
Unfortunately, this doesn’t work on Windows 10 or on its Windows Subsystem for Linux. Something about modprobe access denied or access to its iptables via WSL. But no issue on my Fedora Workstation.
is possible using this together with iodine?
some iodine server need ip but cant use them in this same time.
meybe sshutle will be answer?
Works great for me. This is something I always wanted to have instead of some home-made scripts with lots of “-L” parameters.