I use quite a few raspberry pi’s in locations that dont have the ability for me do incoming SSH to update / reboot / maintain them. This is how i set up a reverse SSH tunnel to them, allowing me to access them from anywhere with internet access!
If the site has a proxy, first you’ll need to install a proxy puncher to allow you to bypass it.
sudo http_proxy="http://proxy.ip.address:port" apt-get install corkscrew
Then install screen. Screen allows you to start a process running ‘detached’ from your current shell, so you dont have to be logged in to keep the tunnel up.
sudo apt-get install screen
Create a user for your ssh tunnel. You could just use the default pi user, but i prefer to use a dedicated tunnel user.
sudo adduser --system tunnel
Create tunnel config
sudo -u tunnel mkdir /home/tunnel/.ssh sudo -u tunnel vim /home/tunnel/.ssh/config
Paste the following into the file. This forwards port 22 (ssh) and 80 (http) on the raspberry pi to ports 8022 and 8080 on your VPS.
ProxyCommand corkscrew 127.0.0.1 3128 %h %p Host tunnel Hostname your.vps.hostname Remoteforward 8022 localhost:22 Remoteforward 8080 localhost:80 Port 443 User tunnel ServerAliveInterval 10 ServerAliveCountMax 3
NOTE: If you are not using a proxy, remove the corkscrew line and the port 443 line. The port 443 line above is only needed if you are behind a proxy and firewall that disallows port 22 outgoing. I have set up my SSH daemon on the VPS to listen to port 443 (the https port) as well as the normal 22 as this will manage to punch its way through most proxies.
The ServerAliveInterval and ServerAliveMax variables above basically say “send a packet across the tunnel every 10 seconds. If you don’t get anything back after 3 tries, close the tunnel”
The above config also assumes you have set up a tunnel user on the machine you are SSHing to. If not, either create a tunnel user the same way we did above, or change the user line in the config to the username you will be using on the VPS side.
Generate your RSA key and upload to the VPS
sudo -su tunnel export HOME=/home/tunnel ssh-keygen ssh-copy-id tunnel
At this point, you should be able to SSH to tunnel without typing in any passwords etc.
$ ssh tunnel Linux thinkl33t 3.2.0-4-686-pae #1 SMP Debian 3.2.65-1+deb7u2 i686 $
Set up our shell scripts to automatically start the tunnel.
sudo -su tunnel mkdir /home/tunnel/bin echo 'PATH="$HOME/bin:$PATH"' | tee /home/tunnel/.bashrc
echo '#!/bin/bash' | tee /home/tunnel/bin/monitor_tunnel.sh echo 'APPCHK=$(screen -ls | grep -c tunnel)' | tee -a /home/tunnel/bin/monitor_tunnel.sh echo 'if [ $APPCHK = "1" ]; then' | tee -a /home/tunnel/bin/monitor_tunnel.sh echo ' echo "Starting SSH tunnel"' | tee -a /home/tunnel/bin/monitor_tunnel.sh echo ' screen -mdS tunnel ssh -N tunnel' | tee -a /home/tunnel/bin/monitor_tunnel.sh echo 'fi' | tee -a /home/tunnel/bin/monitor_tunnel.sh echo 'exit' | tee -a /home/tunnel/bin/monitor_tunnel.sh chmod a+x /home/tunnel/bin/monitor_tunnel.sh
The above script checks for an already open screen session with the name ‘tunnel’. If it doesn’t exist, it creates it. If it does exist it just ends. The screen session is launched in a detached state (in the background), and will automatically end when the SSH tunnel falls over.
Set up the crontab to automatically run our monitoring script once a minute
echo '*/1 * * * * /home/tunnel/bin/monitor_tunnel.sh' | crontab
Your tunnel should come up shortly, woo!
To test it out, from your VPS, type
$ ssh localhost -p 8022 parag0n@localhost's password: Linux thinkl33t 3.2.0-4-686-pae #1 SMP Debian 3.2.65-1+deb7u2 i686 $
Brill, you can now SSH in from your VPS… But by default SSH tunnel ports are only available from localhost, so you’d have to log into your VPS every time you wanted to get into the pi. So, lets edit the SSH config file on your local machine!
Host pi Hostname localhost Port 8022 ProxyCommand ssh your.vps.hostname nc %h %p
This will allow you to type in
on your local machine, and will automatically ssh into your VPS, then SSH into localhost. Sorted.