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:
-D8080opens 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
-Nmeans: 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:
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
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:
This will return your current remote IP. If all's well, this should be the IP of the remote server!