TIL: Reverse port forwarding with ssh
Today I learned (btw. this is what the abbreviation in the post title stands for) that it’s not only possible to map a port from a remote machine to your local one but also the other way arround.
I’ve used the forward-version many times to access a service on a computer in my home-network by using my public accessible ssh server as gateway:
ssh -L 1234:192.168.178.1:80 mydyndns.example.com
This maps the webserver from my home-router to http://127.0.0.1:1234/ on my local machine using the
-L option. You can also send the ssh session to background and don’t run a command (as your default shell) on the remote system using the
-N options if you like.
To map a service from my local machine to a (public accessible) remote machine it’s nearly the same syntax, but using the
-R option instead:
ssh -R 1234:127.0.0.1:80 mypublicserver.example.com
This maps the webserver from my local machine (port 80) to the remote host
mypublicserver.example.com. But for now it’s not yet possible to access the webserver through http://mypublicserver.example.com:1234/ because the forwarded port is only bind to loopback by default and therefore only accessible on the remote machine itself.
To archive the bind to the public avaiable ip address we need to:
1) Allow the bind to other interfaces than loopback:
echo 'GatewayPorts clientspecified' >> /etc/ssh/sshd_config
2) Specify the ip address we want to bind the port to on the remote host:
ssh -R 203.0.113.42:1234:127.0.0.1:80 mypublicserver.example.com
Now your local service is accessible via http://203.0.113.42:1234/ (as long your ssh session is not closed).
Have fun with this quick tip :) For me it was very handy to allow someone from outside my network to control my little fun project running on my arduino ethernet board and turn off and on 3 LEDs.