Skip to content

Instantly share code, notes, and snippets.

@tjunussov
Last active March 14, 2025 08:36
Show Gist options
  • Save tjunussov/284cc843c88a670e6bb9cb325370b7c9 to your computer and use it in GitHub Desktop.
Save tjunussov/284cc843c88a670e6bb9cb325370b7c9 to your computer and use it in GitHub Desktop.

Using SSH to set up a VPN

If you're a roaming user or you're trying to link a satellite office to the main network, SSH can handle the job. Other solutions exist, and SSH isn't perfect, but this is probably the simplest trick out there.

OpenSSH since version 4.3 has the ability to set up TUN/TAP tunnels. I'm sure most of you have set up port-forwarding via SSH, but this is a little different than that. Instead of forwarding one TCP port to a host on the other side of the target SSH server, TUN/TAP lets you route between networks as if both networks are on the same LAN. We're setting up an IP tunnel here using TUN, but you could just as easily set up a layer-2 bridge between two LANs by using the TAP interface instead.

Let's say you're on a laptop in a coffee shop and want to reach your home or office network. Your home LAN is on a 192.168.0.0/24 subnet. Bear in mind that the router at home needs to have "PermitTunnel yes" in /etc/ssh/sshd_config, and "Tunnel yes" and "TunnelDevice any:any" should be listed in /etc/ssh_config on your laptop. Also, the tun driver needs to load on both your laptop and the router. By the way, your router at home has the external IP address 1.2.3.4.

On the laptop, log in to your router at home as root:

ssh -w0:0 1.2.3.4

which creates a tunnel between your laptop and the router at home. After you've logged in to the router, run the command

ifconfig tun0 10.2.2.2 netmask 255.255.255.252

on the router, which will give the an IP address to the far end of the tunnel. At this point, you don't have to do anything else on the router.

Back on your laptop, you have to set an IP address on your end of the tunnel, and set up routing to your LAN at home:

ifconfig tun0 10.2.2.1 netmask 255.255.255.252 route add -net 192.168.0.0/24 dev tun0

At this point you should be able to ping any IP on your LAN at home, from your laptop. Congrats, your VPN is set up and you're good to go.

If you were trying to set up a remote office, the only thing you'd need to do is set up a route on the main office router to reach hosts on the satellite LAN. Also, you could run autossh from /etc/rc.local, which would bring up the VPN at boot, and it would be restarted automatically in the event the ssh connection dropped for some reason.

So, how does it work? SSH allows you to set up a virtual interface, as noted, which functions as a tunnel with two endpoints. You place an IP address at each end of the tunnel, then set up a route at one or both ends to tell hosts each end how to reach hosts on the other end. Routed traffic passes through the tunnel, all nice and encrypted via SSH. Assuming everything is configured correctly and the tun0 interface comes upon both ends, you can construct a scriptable VPN with only four or five commands.

@Fuseteam
Copy link

Fuseteam commented Dec 9, 2024

hmmm makes me wonder if it's sshd that needs it or if the user that needs it......i mean if root login works—

@tondmn
Copy link

tondmn commented Mar 14, 2025

IMO, this should be two separate commands:
$ sudo ifconfig tun0 10.2.2.1 netmask 255.255.255.252
$ sudo route add -net 192.168.0.0/24 dev tun0

The rest of this recipe works as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment