A system wide ssh proxy with sshuttle

Posted in Command line, Security, Open Source, 1 year ago Reading time: 2 minutes
image

A VPN is useful to mask your external IP address. For example I need it to be able to watch Dutch television programs when I am abroad. I use ProtonVPN for that, they have servers in most countries.

But sometimes you want to mask your IP with a specific other IP. For example, some of the client servers have whitelisting, allowing only my home ip. So when I am not at home, I cannot connect to them. An obvious solution would be to setup my own VPN using OpenVPN or Wireguard and connect to that. But there are much easier solutions using SSH.

It is trivial to setup a SOCKS5 proxy to any server you can reach using SSH. You don't need any special rights, and no other applications besides SSH:

ssh -D8080 -q -N user@host

A breakdown of the options:

  • -D8080 opens local tcp port 8080. All traffic to that port will be forwarded using the SOCKS5 protocol to the remote host
  • -q: "quiet mode" to suppress unneeded output
  • -N means: do not open a shell or execute a command on the remote host. You only need the tunnel after all.

Any application with SOCKS5 support will be able to use this tunnel. For example firefox:

Screenshot of Firefox network proxy settings

The disadvantages of this approach is: you will have to configure every app to use the proxy. And not every app has SOCKS5 support. For example: most terminal programs.

It is not impossible to solve this issue with some custom routes using a few iptables rules. But I am not an iptables wizard and I did not have the time for this. Some googling showed me a easier way: sshuttle

https://github.com/sshuttle/sshuttle

https://sshuttle.readthedocs.io/en/stable/

This looked like the perfect tool for the job. A few python scripts around SSH to do exactly what I wanted.

Installation is easy, using brew install sshuttle for MacOS, or sudo apt install sshuttle for Debian or Ubuntu systems. Then, just set up your SSH based VPN:

sshuttle -r user@host 0.0.0.0/0

With the subnet 0.0.0.0/0 you will set up a global system wide VPN. It is also possible to limit the VPN to specific IPs or subnets.

NB: Forwarding all traffic system wide requires root privileges, so you will need sudo rights, or execute this as root.

You can test whether the VPN is working using the following command:

curl ifconfig.me

This will return your current remote IP. If all's well, this should be the IP of the remote server!

Related posts

image
How to scan QR codes without camera or phone

QR codes are everywhere. Easy to scan with a phone. But what if you want to decode a QR on your laptop instead of your phone, without a camera?

Read more →

image
How to build a complete Mastodon API Client

Mastodon has an extensive API, but unfortunately no openapi spec. It was quite a challenge to build an API client and implement all methods and entities. Here's how I did it.

Read more →

image
Pass, the standard Unix password manager

Many people nowadays are using a password manager, like LastPass, 1Password, Keepass, etc. Not many are familiar with "pass, the unix password manager". That's a shame, because I think it is the best password manager for the tech savvy linux/unix user. Let me tell you why.

Read more →

image
Smart generics in PHP

Type hinting in PHP8 has become powerful but it still has limitations. In this article I discuss some ways to use Generics to overcome some of these limitations.

Read more →