If you are dev in Uganda, you are the one am writing this for. That's because most of us work on our localhost machines that are usually hooked to mobile internet. ISPs in Uganda provide dynamic private IPs to dongles, modems, and MiFis of their customers. So in most cases, your development box is running on a NATed private IP which means you can't share your 'hello world' app with your friends. You need to subscribe to an expensive fixed-line internet package to be given a public IP.

So how do you turn your modem-connected local laptop into a server accessible from anywhere in the world? That's the problem I had to think about when a developer friend of mine was stuck with his Apache configs and needed remote help. I had to ssh into his localhost which beautifully happened to the the magnificent pi.

So for starters, you need to be running on a Unix/Linux system. That's because we shall to create SSH tunnels using Openssh package.

Secondly you need access to at least one cloud server or any server with a public IP. You should at least have a minimal box on Linode, Digital ocean, AWS, Google cloud or any of the several tens of VPS providers. This cloud box will help us create an SSH tunnel between your localhost and the cloud.

In summary, you need;

  • cloud-box
  • private-box(pi)
  • desktop/laptop

So lets say Peter has is running his ruby-on-rails app on his little pi and he wants me to check out something. The pi is connected to the internet via WiFi from his MiFi provided by say MTN Uganda. Peter usually SSHes into his Pi via port 2200 from his laptop using putty on Windows or his Ubuntu desktop. He does this; ssh -p 2200 [email protected] or using private ip ssh -p 2200 [email protected]. Now Peter wants me to remotely access his Pi from my home and I can't ssh -p 2200 [email protected].

So here's what I did or what you should do.

on private-box(pi)

If SSH is configured to run on port 2200. Make sure port 2200 is running.

lsof -i :2200

You should get something similar to;

sudo lsof -i :22
sshd     1682   root    3u  IPv4  13659      0t0  TCP *:ssh (LISTEN)
sshd     1682   root    4u  IPv6  13661      0t0  TCP *:ssh (LISTEN)

Now run

ssh -f -R 2225:localhost:2200 [email protected] -N

-f Fork into background after authentication.
-R Forward a remote port to local address.
-N Do not execute a shell or command.

Peter or myself should be able to ssh into the cloud box as user "user" through the default port 22. If it's through another port, then use -p option to specify. This will prompt to login password, but it can be automated by created passwordless ssh using public keys.

on cloud-box

Now on the public VPS server, make sure GatewayPorts yes on /etc/ssh/sshd_config.

Make sure port 2225 is running. This port was created by the SSH tunnel.

lsof -i :2225

Make sure port 2225 is open on firewall if it's blocked.

Since I have access to the cloud VPS, I can connect to Peter's pi from cloud-box like;

ssh -p 2225 [email protected]

This will automatically forward ssh traffic to port 2200 on the Pi. Really awesome!

connnect to pi from remote desktop/laptop

If I don't want to connect to Peter's Pi via cloud box as showed above, I can connect to the Pi from my local desktop at home or from any internet-connected device around the world. It makes it seem like the Pi is some server running on a public IP on the cloud.

ssh -p 2225 [email protected]

What this does is, it connect to the cloud-box on port 2225 and then tunneled to the pi on port 2200. And that's it.

Please note that the connection can only be sustained for as long as the tunnel is running. If it disconnects like for instance if he reboots his pi, that's it. I can't remote into Peter's PI anymore. Peter can run the

ssh -f -R 2225:localhost:2200 [email protected] -N
``` command has a service using things like supervisor, upstart, systemd or any other similar process monitoring or daemonizing tools. 

Further reading: