These past days I’ve been setting up a Raspberry Pi running some services in my room. I wanted to access them from outside the house’s network but unfortunately, I don’t have access to the router.

I could have set up a VPN client into the Pi but it is running a very minimal OS to which I cannot install packages.

Fortunately, SSH has an option for Remote port forwarding which allowed me to solve this problem.

Local port forwarding⌗

SSH Local port forwarding allows us to redirect queries from localhost:sourcePort to remotehost:onPort. It is specified in the following way:

ssh -L [bind_address:]sourcePort:remotehost:onPort gateway
  • gateway: The SSH connection will be open to that machine
  • remotehost:onPort: gateway will connect to remotehost:onPort
  • sourcePort: SSH will redirect our requests to sourcePort to remotehost:onPort through gateway
  • bind_address: It may be used to bind the connection to a specific address. For example, localhost indicates that the listening port be bound for local use only

Remote port forwarding⌗

SSH Remote port forwarding allows us to forward all connection attempts to sourcePort to remotehost:onPort through gateway.

ssh -R [bind_address:]sourcePort:remotehost:onPort gateway

The parameters behave the same as in Local port forwarding.

There is an excellent answer in Stackoverflow [2] where the difference between local and remote port forwarding are explained.

My setup⌗

For my particular use case, the remote Raspberry Pi (RASPBERRY PI BEHIND ROUTER) executes the following loop after booting up:

while true; do
ssh -N -o ServerAliveInterval=10 -R 2222:localhost:22 pi@RASPBERRY_PI_OPEN
done &

As you may know by now, this SSH command opens a connection to my Raspberry Pi with some ports open globally (RASPBERRY PI OPEN). The SSH command is wrapped with a while true to start a new session if it dies.

Now, from RASPBERRY PI OPEN I can open an SSH connection to RASPBERRY PI BEHIND ROUTER using the following command:

ssh -l user -p 2222 localhost -L 8000:localhost:80
SSH Remote forwarding diagram
SSH Remote forwarding diagram

Besides, I redirect with Local port forwarding the port 80 of RASPBERRY PI BEHIND ROUTER to port 8000 of RASPBERRY PI OPEN so I can access a service running on that port.

The only remaining thing is connecting from my LAPTOP. For this, I also use Local port forwarding to redirect port 8000.

ssh RASPBERRY_PI_OPEN -L 8000:localhost:8000

References 📑⌗

[1]: https://linux.die.net/man/1/ssh

[2]: https://unix.stackexchange.com/a/115906/420543