If you’re working remotely and have servers on a private network, they are by definition unreachable over the internet. In many cases, you might have a proper VPN using standard, accepted VPN protocols or even something proprietary from one of the traditional vendors. Things like OpenVPN, SSTP, L2TP, PPTP are commonly deployed. Every once in a while however, you encounter a situation where that type of remote connectivity is not available, not problem setup, or…is just down.
I’ve encountered this a few times in the middle of an outage with a client who can’t setup a VPN user on the fly. However, sometimes I’ll have SSH access to something over the internet, or perhaps on another network entirely. In some cases, the box that I can SSH to has access to the private servers I need.
SSHUTTLE – A Poor Man’s VPN
SSH on Linux, Mac, or anything really, even PuTTY on Windows, supports tunneling. You just need to know the flags, options, and ordering of things. It’s not terribly difficult. However, in most of those cases, you’re limited to forwarding one local port to one remote port. In our exercise, I want to route all traffic destined for 10.1.0.0/24 over an SSH connection as if I am the jump server.
This is where SSHUTTLE comes in play, it will take in entire subnets and other options to build and manage all of the local forwarding, routing, and IPTABLES rules to treat this SSH connection as a full blown VPN. It’s in the Ubuntu repositories, so installing it is simple.
sudo apt install sshuttle
Then in order to create the tunnel to fulfill our needs from the example, it’s as simple as this.
sshuttle -r firstname.lastname@example.org 10.1.0.0/24
This will ask you for sudo password, create the SSH session to the jump server. If successful, it will create the necessary IPTABLES rules to forward traffic destined to the subnet we passed in. You can pass in multiple subnets if necessary also, even forward DNS traffic over the tunnel for the jump server to resolve.
Here is an example of the IPTABLES rules it creates after establishing and holding the SSH session. These rules would be created on our local system.
iptables -t nat -N sshuttle-12300 iptables -t nat -F sshuttle-12300 iptables -t nat -I OUTPUT 1 -j sshuttle-12300 iptables -t nat -I PREROUTING 1 -j sshuttle-12300 iptables -t nat -A sshuttle-12300 -j RETURN --dest 127.0.0.1/32 -p tcp iptables -t nat -A sshuttle-12300 -j REDIRECT --dest 10.1.0.0/24 -p tcp --to-ports 12300 -m ttl ! --ttl 42
Now, I can hit any IP address in the 10.1.0.0/24 subnet directly as if I was on the same network.