How to make an SSH tunnel publicly accessible?
Solution 1
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.
Solution 2
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.
Solution 3
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
Solution 4
You can also use a double forward if you won´t or can change /etc/ssh/sshd_config.
First forward to temporary port (e.g. 10080) on loopback device on the remote machine, then use local forward there to redirect port 10080 to 80 on all interfaces:
ssh -A -R 10080:localhost_or_machine_from:80 [email protected] "ssh -g -N -L 80:localhost:10080 localhost"
Solution 5
Use the "gateway ports" option.
ssh -g -R REMOTE_PORT:HOST:PORT ...
In order to use that, you probably need to add "GatewayPorts yes
" to your server's /etc/ssh/sshd_config
.
Related videos on Youtube
Comments
-
Trevor Rudolph over 1 year
Referring back to this question, I am executing the below via OpenSSH (Client: Mac OS X 10.6 | Server: Linux Mint), however the port that is being tunneled is not working publicly:
ssh -R 8080:localhost:80 -N [email protected]
- The purpose is so the local port can be opened on the remote computer
- It seems as if the remote side binds only on
localhost
, instead of to all interfaces - It works when opening the port on
localhost
on the remote computer, but when trying to access the public IP of the remote computer from my local computer, the port doesn’t seem to be open
How would I make the tunnel public on the IP for anyone to access?
-
Admin about 11 yearsWhat does public IP mean? If you are trying to connect to a local computer thru the router and via the Internet, most routers will not allow such loopback.
-
Trevor Rudolph about 11 yearsdoesn't seem to be working... it starts up but i cant connect remotely
-
snapshoe about 11 yearsTry running
netstat -elnpt
from a separate tty to figure out what ports are bound to what address. Without-g
, a port should be bound to127.0.0.1:PORT
. With-g
, it should be bound to0.0.0.0:PORT
, which makes it accessible remotely. -
Trevor Rudolph about 11 years
-
Trevor Rudolph about 11 years
GatewayPorts=clientspecified
orGatewayPorts clientspecified
-
Trevor Rudolph about 11 yearsand do i add that to the client or remote?
-
snapshoe about 11 yearsalready answered in the answer-- on website.com
-
Trevor Rudolph about 11 yearsOH MY GOD IT WORKED!!!!! I have done exactly that 1 million times!! I just forgot that
*
in bash will give files and i needed\*
-
Stefan Seidel about 11 yearsYeah, that's exactly why I always prefer
0.0.0.0
- it's IPv4 only, but it'll do most of the time :) -
Trevor Rudolph about 11 years
fe80::1
hahaha -
Trevor Rudolph about 11 yearsjk :D yea but 0.0.0.0 is good, but can you use 127.0.0.1? or is that too local and nonbinding
-
Stefan Seidel about 11 yearsWell, actually
[::]
should work for all v4+v6!127.0.0.1
means loopback, i.e. you're back to square one ;) -
Trevor Rudolph about 11 yearsyea, i thought as much, but 0.0.0.0 will bind directly to the ipv4 interface so its not device specific
-
Trevor Rudolph about 11 yearsand
[::]
is only ipv6 right? How can it be used in ipv4? -
Stefan Seidel about 11 yearsNo,
[::]
means0:0:0:0:0....:0
and is essentially the IPv6 equivalent of0.0.0.0
- but since IPv4 is basically a subset of IPv6 (e.g.::ffff:10.120.78.40
is an IPv4-mapped IPv6 address), it'll mean the port is accessible both via IPv6 and IPv4. -
Trevor Rudolph about 11 yearswell yea, i actualy jsut researched ipv6 for a half hour and now instead or
\*:
im using[::0]:
-
Trevor Rudolph about 11 yearsand instead of
localhost
im using[::1]
works like a charm -
Giovanni Luisotto almost 10 yearsI like the fact that I don't have to deal with the sshd configuration and that I can do all of it without sudo. Plus I learn that socat exists. Thanks!
-
Daniil Iaitskov almost 8 yearsI used -L instead of -R and it also works
-
Sunry over 7 yearsGatewayPorts yes solved my problem.
-
Michael Schubert over 7 yearsThis actually works to bypass forwarding rules!
-
Phil_1984_ over 7 yearsGatewayPorts = yes (on the remote sshd config) fixed it for me too
-
E.T over 7 yearsActually this worked. What I do is that I use an EC2 instance as a forwarder to my REST server. This way, I don't need to stick my server in the DMZ and I don't need a public IP. Funny enough, with the first EC2 instance I created, ssh -R remote_port:localhost:port xxx@ec2xxx worked just fine but then I had to create another instance later on for some reason and from that point on, I was always getting: connection refused. Used tcpdump to look at what I was getting and there wasn't much info. -g plus GatewayPorts yes did the trick.
-
Grezzo almost 7 yearsLove this solution. Great workaround when you don't want the change the config on the machine
-
karser over 6 years"GatewayPorts yes" made my day, thanks @StefanSeidel
-
php_nub_qq over 5 yearsYOU ARE A FING HERO
-
Michał Politowski about 5 yearsNote that GatewayPorts yes actually makes the bind_address irrelevant: "The argument may be [...], yes to force remote port forwardings to bind to the wildcard address"
-
Owl City about 5 yearsBy defautl "GatewayPorts" argument is not exist. Thank you pro!
-
Jaime almost 5 years+up you go good sir. I tried to tell ssh to bind to 0.0.0.0 without success.. then saw the * syntax, tried that, no dice. I imagine it may be some sort of security feature on sshd config or something that isn't allowing it. Finally saw this post and
socat
worked awesome. Super useful, putting this in my back pocket ;] -
surj over 4 years
GatewayPorts yes
in my~/.ssh/config
worked well in macOS -
oliora about 4 yearsThank you for the answer! It make sense to add a note that user needs to restart
sshd
after the configuration update. -
Shankara Narayana almost 4 yearsI was tripping for almost 30 mins because I did not read the entire answer. Gateway Ports yes worked
-
Henning over 3 yearsNever add "GatewayPorts" after a "Match" command (even if it is not indented) or you will go crazy! (cert from the manpage: "Only a subset of keywords may be used on the lines following a Match keyword")
-
Adam F over 2 yearsIt works, I have no idea WHY it works
-
Gloomy over 2 yearsCan you expand on "clientspecified, or, in rare cases, to yes"? Why should it generally not be yes (which seems to be what everyone is doing)?