How to make a SSH tunnel publicly accessible?
If you check the man page for ssh, you'll find that the syntax for -R
reads:
-R [bind_address:]port:host:hostport
When bind_address
is omitted (as in your example), the port is bound on the loopback interface only. In order to make it bind to all interfaces, use
ssh -R \*:8080:localhost:80 -N [email protected]
or
ssh -R 0.0.0.0:8080:localhost:80 -N [email protected]
or
ssh -R "[::]:8080:localhost:80" -N [email protected]
The first version binds to all interfaces individually. The second version creates a general IPv4-only bind, which means that the port is accessible on all interfaces via IPv4. The third version is probably technically equivalent to the first, but again it creates only a single bind to ::
, which means that the port is accessible via IPv6 natively and via IPv4 through IPv4-mapped IPv6 addresses (doesn't work on Windows, OpenBSD). (You need the quotes because [::]
could be interpreted as a glob otherwise.)
Note that if you use OpenSSH sshd
server, the server's GatewayPorts
option needs to be enabled (clientspecified
, or, in rare cases, to yes
) for this to work (check file /etc/ssh/sshd_config
on the server). Otherwise (default value for this option is no
), the server will always force the port to be bound on the loopback interface only.
Edit:
-g
works for local forwarded ports, but what you want is a reverse/remote forwarded port, which is different.
What you want is this.
Essentially, on example.com
, set GatewayPorts=clientspecified
in /etc/ssh/sshd_config
.
--- previous (incorrect) answer ---
Use the -g option. From ssh's man page:
-g Allows remote hosts to connect to local forwarded ports.
Here's my answer for completion:
I ended up using ssh -R ...
for tunneling, and using socat
on top of that for redirecting network traffic to 127.0.0.1
:
tunnel binded to 127.0.0.1:
ssh -R mitm:9999:<my.ip>:8084 me@mitm
socat:
mitm$ socat TCP-LISTEN:9090,fork TCP:127.0.0.1:9999
Other option is to do a local-only tunnel on top of that, but i find this much slower
mitm$ ssh -L<mitm.ip.address>:9090:localhost:9999 localhost