Use sshuttle to build a poor man’s VPN

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.

Installing sshuttle

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

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 and the reserved Class B subnet The command above becomes:

$ sshuttle -r username@remotehost

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

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.

Using Software


  1. dac.override

    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.

  2. Brian

    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.

  3. Nick

    Why not do port forwarding on regular SSH and use socks5 proxy?

    • @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.

        • Steven Bakker

          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 ( 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.

            • Brian

              Since sshuttle appears to require root access on both the client and server

              SShuttle does NOT require root access on the remote (server as you put it)

  4. Mehdi

    It is indeed a poor man’s VPN 🙂 Tried it on HomeBrew, keeps crashing.

  5. Brian

    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.

  6. 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.

  7. Oh cool. Looks like sshuttle supports UDP since last I checked some years ago. This article got me to check the man page. Thanks!

  8. Use this rule:
    $IPT -A INPUT -p tcp –dport 22 -m state –state NEW -s -j ACCEPT

  9. 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.

  10. 4e5ty

    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?

  11. Mariusz

    Works great for me. This is something I always wanted to have instead of some home-made scripts with lots of “-L” parameters.

Comments are Closed

The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases. You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora logo is a trademark of Red Hat, Inc. Terms and Conditions