Using reverse ssh to access an Intranet host from an external network

  • 2020-05-30 21:58:03
  • OfStack


Recently, I encountered a problem, that is, I need to leave the school in a few days, and I still want to log in a server in the campus network to work. However, I do not have the operation permission of the campus network gateway, so I cannot do port mapping, nor can I obtain the external network ip of the campus network internal host, and the vpn provided by the school itself cannot be used at all. After a lot of research, I finally found a good solution to use reverse ssh(reverse ssh tunnel) for Intranet login.

The working principle of

The reason why many forwarding methods cannot be applied here is that the internal host is actually invisible to the external network, that is to say, the external host cannot access the internal host with the method of 1. So we thought, can we use the internal network host to find the external network host, after finding the internal network host access to the external network channel into the external network host access to the internal network channel? Fortunately, this method does work, which is known as reverse ssh in the most popular sense. It is like sending a letter 1, "although I don't know your address, but you know my address, so you can write to me first, tell me your address, and then I can reply to you. ".


Due to our own ip using computer may not have the network, so we need a server with a fixed outer net ip (literally have a tencent cloud ali cloud of small machine), and then use this server communicate with network machines, we'll need to log in your own server, then reuse this server to access to the network host.

1. Prepare A server with fixed ip and B Intranet machine to be accessed. Both have sshd on and the port number is 22 by default. By the way, do ssh password free login.

2. The Intranet host B actively connects to the server A, and execute the following commands:

$ ssh -NfR 1111:localhost:22 username@servername -p 22

This command means to do port forwarding(-N) in the background instead of actually connecting, do port forwarding(-N), do reverse ssh(-R), and map port 1111 of the remote server to the port connecting the native (B) to the reverse ssh of that server.

Attachment: : it is necessary to strengthen 1 memory here, this port number 1 is easy to get confused accidentally. The parameter commands in the man document look like this:

-R [bind_address:]port:host:hostport

bind_address and the following port refer to the ip and port of the remote host, host and hostport refer to the ip and port of the local machine. Since the ssh command itself requires the ip of the remote host (servername in the previous command), this bind_address can in principle be omitted.

After executing this command, we can see on the server A that his port 1111 has started listening:

$ ss -ant |grep 1111
LISTEN  0  128      *:*

3. In the above operation, port 1111 has been mapped to port 22 of the Intranet host B, now we only need ssh to our own port. Execute in server A:

$ ssh username@localhost -p1111

This successfully logged into the Intranet host.

Function optimization

In fact, there is a problem with the above practice, that is, the reverse ssh may be unstable, and the port mapping between host B and server A may be broken, so the host B needs to re-link, while obviously I can't log in B from far away. A very simple solution is to replace ssh in step 2 with autossh:

$ autossh -M 2222 -NfR 1111:localhost:22 username@servername -p 22

The following parameter is the same as ssh except for the extra parameter of -M. This parameter means to use port 2222 of the machine to listen to ssh and reconnect it whenever it breaks... But as the man documentation also says, this port is also called echo port, and it actually has 1 pair of ports, and the second port is this port number plus 1. So we want to make sure that this port number and this port number plus 1 are not occupied.


Related articles: