Fun with SSH Tunnels to a Raspberry Pi

I was listening to a podcast by Scott Hanselman that talked about not waisting your key strokes. Essentially when you are helping someone with a problem, you think about how those keystrokes could be shared more widely to help others. I was explaining to a collegue some uses of a raspberry pi and did just that.


If there is one thing I would recommend to everyone who wants to improve their internet experience and protect their children online, it would be to setup a pi-hole. The speed, privacy and protection they provide is awesome.

Once you have a raspberry pi running in your home network that is always on you can put it to other uses. One thing I like to do is have ssh open so I can connect to it from anywhere and use it as an entry point into my network using tunnels to access devices that aren't open to the internet. This allows me to do the following:

  • Whitelist something that is blocked on the pi-hole that is affecting someone at home, such as a false positive
  • Remote desktop my home computers (PC and MAC)
  • View WiFi enabled web cam
  • Access NAS storage device

Note: I do have a VPN which is the primary entry point, but it's good to have another way in should VPN traffic be blocked by the network I am on or something goes wrong with the VPN software/certificates.

Setting up ssh

First ensure your public keys are over on your server/pi by copying the contents of your ~/.ssh/id_rsa.pub file on your computer (mac in my case_ to the ~/.ssh/authorized_keys file on your pi.

A super quick way to do this is use $ ssh-copy-id username@raspberrypi

Check it works by ssh $ ssh username@raspberrypi if all works well without prompting for a password it's time to disable password authentication, this will prevent others accessing it by guessing your password/bruteforce or whatever.

$ sudo vi /etc/ssh/sshd_config

Ensure the following values are set as:

ChallengeResponseAuthentication no

PasswordAuthentication no

UsePAM no

PermitRootLogin no

Configure the firewall

Port forward port 22 from your firewall to your raspberry pi. If possible it would be a good idea to setup somekind of dynamic DNS solution so you can access your home by name. I have used crabdance.com previously which will give you a nice name like vixdigital.crabdance.com which will point to the IP of your house. Your router may have other dynamic DNS capabilities like dyndns built in though so you should check those out.

You want to be forwarding a port from your router to the internal IP address of your raspberry pi on port 22.

Local Tunnels

These sweet things allow you to map a port on your local machine, the one you are sitting at, to anything inside your remote network at home.

Lets say I want to use this tunnel to connect to my synology NAS that is inside my home network which I usually access by typing synology.localdomain:5000 when I am in my house.

I find myself on a public wifi and I want to access it from there:

ssh -L 9000:synology.localdomain:5000 pi@vixdigital.crabdance.com

Creating a SSH tunnel to my Synology NAS Device

Now I browse to http://localhost:9000 and a tunnel is created from port 9000 locally, through the tunnel where it then maps to http://synology.localdomain:5000 inside my network.

Accessing Synology NAS through the SSH Tunnel

Lets access the pi-hole so I can unblock a false positive for the family:

Creating a SSH tunnel to my ph-hole
Accessing Pi-hole through the SSH Tunnel

What about accessing that webcam? Easy:

Creating a SSH tunnel to my Webcam
Accessing Pi-hole through the SSH Tunnel

I think you get the gist by now that using ssh tunnels is pretty neat.

Remote Tunnels

These are awesome too, it's the same but in reverse, but lets have a use case for them so we know how they can be used.

Lets say you have a friend who wants to give you access to something in their network. They could be in a coffee shop, a friends house or another environment where they can't just open up ports so you can have a play with their latest hello world app they just built in node.js running on port 3000

They ssh into your server and you access it that way, this bypasses NAT, inbound firewall rules and tears down the moment they kill the ssh tunnel.

Lets see it in action from my machine to home.

$ ssh -R 9000:localhost:3000  pi@vixdigital.crabdance.com

This will ssh into the pi as before but creates a reverse tunnel, meaning anyone browsing to the pi inside my home network on port 9000 will be accessing my machine on port 3000.

Accessing my hello world app running on my local machine

If you want to see some real voodoo take a look at this. I now create another tunnel. A remote one exposing my localhost:3000 to 9000 on my remote pi. And then another one, exposing my local port 4000 to my remote pi on port 9000.

SSH Tunneling to my Tunnel

Now I can access my hello world app that is running on port 3000 locally as normal, or port 4000 via one tunnel to port 9000 on the pi and back through the other tunnel from the pi to my local machine. 🤯

Accessing an SSH Tunnel through an SSH Tunnel

Hopefully this port will convince you that tunnels are cool, having a pi running at home allows you to do some pretty cool things as well as running a pi-hole which you absolutely should do. It should also open your eyes to some of the ways people get around security re-inforcing that paremeter based security with firewalls isn't enough on it's own.