I have a computer with CentOS (computer A) that configured as has an private ip 10.150.5.141 (with restricted firewall), can access internet and my ArchLinux VPS (computer B) with real ip w.x.y.z
How can I make another pc (computer C) that could access computer B to connect to computer A, but computer C cannot connect to computer A directly (because it’s on A’s own private network)?
I know that a tunnel can open local ports to another computer:port, but how to do the opposite?
I want to access computer A using ssh through computer B but computer B cannot access computer A, because the network on computer A is restrictive (can go out, but can’t go in, because I have no access to their router)
I want something like this:
ssh -connect-to w.x.y.z:22 -open-port vvv -forward-to 10.150.5.141 -port 22
so that when I ssh w.x.y.z:vvv from computer C it will forwarded to private network 10.150.5.141:22.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
What you’re looking for is called a reverse tunnel. ssh provides it through the -R switch:
-R [bind_address:]port:host:hostport
Specifies that the given port on the remote (server) host is to
be forwarded to the given host and port on the local side. This
works by allocating a socket to listen to port on the remote side,
and whenever a connection is made to this port, the connection is
forwarded over the secure channel, and a connection is made to host
port hostport from the local machine.
As the OP discovered with their answer the syntax is as follows:
$ ssh -f -N -R vvv:localhost:22 w.x.y.z
Example
I have 2 computers on the network, lappy and remotey. So I run the following command on lappy:
$ ssh -f -N -R 12345:localhost:22 remotey
I can confirm that it’s working:
$ ps -eaf|grep "[l]ocalhost:22" saml 27685 1 0 11:10 ? 00:00:00 ssh -f -N -R 12345:localhost:22 remotey
Now if I ssh separately over to the remote system, remotey and run this command I can see that it’s now accepting connections on port 12345 on the remote system’s local interface:
$ netstat -an|grep :12345 tcp 0 0 127.0.0.1:12345 0.0.0.0:* LISTEN tcp 0 0 ::1:12345 :::* LISTEN
Testing the connection
You can see that the reverse ssh tunnel is working as follows.
-
login to
remotey[<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e491978196a4888594949d">[email protected]</a> ~]$ ssh remotey
-
test out reverse tunnel port
[<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="85f0f6e0f7c5f7e0e8eaf1e0fc">[email protected]</a> ~]$ ssh -p 12345 localhost
-
should now be back on lappy
<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5124223423113d3e32303d393e2225">[email protected]</a>'s password: Last login: Thu Aug 1 17:53:54 2013 /usr/bin/xauth: creating new authority file /home/user/.Xauthority [<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6712140215270b0617171e">[email protected]</a> ~]$
Ports on interfaces other than localhost (lo)?
You might be left scratching your head if you try a command like this and it doesn’t appear to work, or it always binds to a port on the localhost (lo) interface.
For example:
lappy$ ssh -f -N -R remotey:12345:lappy:22 remotey
NOTE: This command says to open up port [email protected] and tunnel any connections to port [email protected]
Then on remotey:
remotey$ netstat -an|grep 12345 tcp 0 0 127.0.0.1:12345 0.0.0.0:* LISTEN
What’s going on is sshd‘s configurations aren’t allowing you to do this. In fact without this feature enabled (GatewayPorts) you won’t be able to bind any ssh tunnel ports to anything except localhost.
Enabling GatewayPorts
remotey$ grep GatewayPorts /etc/ssh/sshd_config #GatewayPorts no
To enable it, edit this file /etc/ssh/sshd_config:
GatewayPorts clientspecified
And restart sshd:
remotey$ sudo service sshd restart
Now try it again and we should see the effect we’re after:
lappy$ ssh -f -N -R remotey:12345:lappy:22 remotey
And double check it this time on remotey:
remotey$ netstat -anp | grep 12345 tcp 0 0 192.168.1.3:12345 0.0.0.0:* LISTEN 9333/sshd
NOTE: In the above we can see that the sshd process now is listening on the interface which has IP address 192.168.1.3, for connections on port 12345.
Testing the connection (part deux)
Now with our altered setup when we test it this time. The primary difference is that we no longer have to connect to localhost!
-
login to
remotey[<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3e4b4d5b4c7e525f4e4e47">[email protected]</a> ~]$ ssh remotey
-
test out reverse connection
[<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c2b7b1a7b082b0a7afadb6a7bb">[email protected]</a> ~]$ ssh -p 12345 remotey
-
should now be back on lappy
<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="17657878635765727a7863726e">[email protected]</a>'s password: Last login: Wed Aug 21 01:49:10 2013 from remotey [<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f683859384b69a9786868f">[email protected]</a> ~]$
References
- How to make a reverse SSH tunnel
- SSH/OpenSSH/PortForwarding
- ssh tunnel via multiple hops
- How does reverse SSH tunneling work?
- ssh all the time
- Reversing an ssh connection
- chaining ssh tunnels
- Create a SSH tunnel inside a chain of SSH tunnels example
- Bypassing corporate firewall with reverse ssh port forwarding
- Reverse port tunnelling
Method 2
Since computer B cannot access computer A, you will need to open a remote tunnel from computer A first.
ssh <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c6b3b5a3b486a5a9abb6b3b2a3b484">[email protected]</a> -R vvv:localhost:22
Method 3
nevermind, i found the answer:
ssh -f -N -R vvv:localhost:22 w.x.y.z
from computer A
EDIT: TL;DR, correct solution:
ssh -f -N -R w.x.y.z:vvv:localhost:22 w.x.y.z
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0