Using a reverse SSH tunnel to access a RaspberryPi


I’ve got a few Alexa devices around the house, and a few RaspberryPi lying around so I decided it could be interesting to try to make them work together. The first step I could think of was to figure out a way to be able to connect to my RaspberryPi from AWS. I wanted to stay in the Free Tier from AWS, so a lot of options were not available to me. I do have access to a shared server where I can run SSHd and PHP, so I decided to leverage those. Here is how I ended up using a reverse SSH tunnel to access a RaspberryPi.

Why use a reverse SSH Tunnel

When playing with this experiment, I wanted something that was somewhat secure. I did not want to open ports to my personal router and use a service like no-ip. A Reverse SSH Tunnel allows me to not open any ports on my home router.

Basically, a Reverse SSH Tunnel opens a port on the remote host and forwards any traffic on that port to a port on the machine that established the SSH connection. My hosted server’s network configuration prevents all non-HTTP(s) connections to it. This setup allows me to have a small PHP script with some kind of access-key that forwards connections directly to the tunnel.

The Setup

As always, I posted my code on one of my GitHub repository.  In the case of this project, it lives here and is split into two major scripts: and Both of these are controlled by environment variables and are explained in sample.env.

Using this script is quite simple:

  1. Copy the sample.env file somewhere
  2. Edit the file to put in values that make sense for your setup
  3. Add the script execution to your crontab

I set up my crontab to run the script every minute. In order to edit the crontab for your current user, simply run crontab -e. Once this is done, your favorite editor will show up. You’ll need to add a line at the end of the file, in my case, I used the following:

The first part,  */1 * * * *, controls when to run the script. In the current case, it will run the script every minute. The rest of the line is the command to execute. In my case, I want to source the content of a file into my environment, execute the script, and keep a log of what happened.

The command is therefore split into three parts:

  1. . /home/someuser/sshforever.env: sources the environment file
  2. /home/someuser/bin/ executes the script
  3. > /home/someuser/tunnel.log 2>&1: redirects both STDOUT and STDERR to a log file

Doing things this way prevents you from using a password to connect to the SSH server. You should set up your connection using a public/private key pair.

A few related links

Tagged . Bookmark the permalink.

Leave a Reply