How does one access the Linux server after NAT through SSH reverse tunnel? (1)
Suppose you are running a Linux server at home, which is behind the NAT router or restricted firewall. Now, you can connect to the home server through SSH when you are not at home. How do you do this? SSH port forwarding is undoubtedly a method. However, if you are dealing with multiple nested NAT environments, port forwarding will become tricky. In addition, because the situation of each ISP is different, for example, the restrictive ISP firewall blocks forwarding ports, or the carrier-level NAT shares IPv4 ports among many users, port forwarding will also be affected.
What is an SSH reverse tunnel?
In addition to SSH port forwarding, another method is SSH reverse tunnel. The concept of SSH reverse tunnel is actually very simple. For this reason, you need to have another host outside the restricted home network, that is, the so-called relay host, where you can connect to the host through SSH. You can use a virtual private server (VPS) instance with a public IP address to create a Relay host. The next step is to build a persistent SSH tunnel from the server on your home network to the public Relay host. With this tunnel, you can "Connect" from the Relay host to the home server (that is why it is called a "reverse" Tunnel ). No matter where you are, or how strict the NAT or firewall restrictions in your home network are, you can connect to the home server as long as you can connect to the relay host.
Create an SSH reverse tunnel on Linux
Let's take a look at how we can build and use an SSH reverse tunnel. Let's assume the following settings. We will build an SSH reverse tunnel from the home server (homeserver) to the relayserver (relayserver) so that we can access the other computer named clientcomputer, connect to the home server through SSH Through the relay server. The public IP address of the relay server is 1.1.1.1.
On the home server, open the SSH connection to the relay server, as shown below.
homeserver~$ ssh -fN -R 10022:localhost:22 relayserver_user@1.1.1.1
Port 10022 is any random port number you can select. Make sure that the port is not used by other programs on the relay server.
The "-R 10022: localhost: 22" option defines a reverse tunnel. It forwards traffic to port 22 on the home server through port 1022 of the relay server.
If you use the "-fN" option, once you have successfully verified your identity and logged on to the SSH server, SSH will go straight to the background. If you do not want to execute any command on the remote SSH server and only want to forward the port, this option is useful in the example in this article.
After running the preceding command, you will directly return to the command prompt on the home server.
Log on to the relay server and verify that 127.0.0.1: 10022 is bound to sshd. If so, it means that the reverse tunnel has been correctly established.
relayserver~$ sudo netstat -nap | grep 10022tcp 0 0 127.0.0.1:10022 0.0.0.0:* LISTEN 8493/sshd
Now, you can log on to any other computer, such as clientcomputer, to the relay server. Then access the home server, as shown below.
relayserver~$ ssh -p 10022 homeserver_user@localhost
Note that the SSH login information/password you entered for localhost should be applicable to the home server, not the relay server, because you log on to the home server through the local endpoint of the tunnel. Therefore, do not enter the logon information/password for the relay server. After successful logon, you are connected to the home server.
Connect directly to the server behind NAT through SSH reverse tunnel
Although the above method allows you to connect to the home server behind the NAT, You need to log on twice, first log on to the relay server, and then log on to the home server. This is because the endpoint of the SSH tunnel on the relay server is bound to the return address (127.0.0.1 ).
But in fact, as long as you log on to the relay server at a time, you can directly connect to the home server behind the NAT. To do this, you need to enable the sshd on the relay server to forward ports from both the return address and external hosts. This can be achieved by specifying the GatewayPorts option in the sshd running on the relay server.
Open/etc/ssh/sshd_conf of the relay server and add the following line.
relayserver~$ vi /etc/ssh/sshd_confGatewayPorts clientspecified
Restart sshd.
Debian-based systems:
relayserver~$ sudo /etc/init.d/ssh restart
Red Hat-based systems:
relayserver~$ sudo systemctl restart sshd
Now you may want to establish an SSH reverse tunnel from the home server, as shown below.
homeserver~$ ssh -fN -R 1.1.1.1:10022:localhost:22 relayserver_user@1.1.1.1
Log on to the relay server and run the netstat command to verify that the SSH reverse tunnel has been successfully established.
relayserver~$ sudo netstat -nap | grep 10022tcp 0 0 1.1.1.1:10022 0.0.0.0:* LISTEN 1538/sshd: dev
Unlike the previous scenario, the tunnel endpoint is 1.1.1.1: 10022 (Public IP address of the relay server) instead of 127.0.0.1: 10022. This means that you can connect to the tunnel endpoint from an external host.
Now, you can run the following commands on any other computer (such as clientcomputer) to access the home server after NAT.
clientcomputer~$ ssh -p 10022 homeserver_user@1.1.1.1
In the preceding command, although 1.1.1.1 is the public IP address of the relay server, homeserver_user must be the user account associated with the home server. This is because the host you actually log on to is a home server rather than a relay server. The latter only forwards your SSH traffic to the home server.