When it comes to using a console on a remote computer that is only accessible via the Internet in a secure manner, the SSH program has prevailed over the previously used programs such as telnet or rlogin. An SSH server runs on almost any computer or can run on any computer and there are SSH clients for every operating system, including mobile ones.
The other possibilities that SSH offers are less well known, and this includes above all port forwarding, which comes in two flavours, local port forwarding and remote port forwarding, sometimes also refered to as reverse port forwarding.
This article will start with a simple example for local port forwarding. For that, it is also interesting to know roughly how applications communicate on the Internet.
Application communication on the Internet
A well-known scenario is, for example, a web application on a computer on the Internet. The application is made available by a web server and uses a database for data storage, the database server of which is usually installed on the same computer.
Since the web server only has to communicate with the database server for the application to function, it is sufficient if the database server can only be reached from the same "local" computer. The database server is thus protected against unauthorized requests from outside, because it does not even react to them. The web server, on the other hand, must also be accessible from outside the computer, otherwise nobody could call up and use the application in the browser.
Technically, this is implemented in such a way that the web server can communicate both on the inward and outward network interface, while the database server can only be reached on the inwardly directed interface.
The outwardly directed interface should be accessible here e.g. with the name
remote.example.com or the associated IP address
220.127.116.11, the inward-facing interface with the name
localhost or the associated IP address
In a console on the remote computer, the
netstat program can be used to show which application (
PID/Program name) can be reached on which interface (
Local Address). The address
0.0.0.0 stands for "all interfaces":
$ sudo netstat -ltpn Aktive Internetverbindungen (Nur Server) Proto Local Address Foreign Address State PID/Program name tcp 0.0.0.0:22 0.0.0.0:* LISTEN 531/sshd tcp 127.0.0.1:3306 0.0.0.0:* LISTEN 624/mysqld tcp 0.0.0.0:80 0.0.0.0:* LISTEN 745/apache2 $
The simplified and shortened output shows that the database server (MySQL) can only be reached via the local interface (
127.0.0.1), while, for example, the SSH server and the web server (Apache) can be accessed via all interfaces, i.e. can also be reached from the Internet (
The number after the address is the port used by this application, which can be compared to a channel for a radio. Every application that wants to communicate over the Internet uses one or more ports for this. The applications are assigned certain port numbers by convention, but the applications can also use other port numbers, which must be taken into account when communicating.
The web server could be reached here with the URL
http://remote.example.com:80/ would also be correct, because the web server uses its standard port
80 and in this case, the port does not need to be specified in the address.
Hence, the output of netstat also shows that the web server can be reached on port
80 (via all interfaces), the SSH server on port
22 (also via all interfaces) and the database server on port
3306 (only via the local interface). These are also the standard ports of these applications.
The question now is how you can still establish a connection to the database server, for example from your laptop at home, in order to be able to manage the database with a program on the laptop. The program expects the database server to be administered to be configured with the name of the computer and the port, e.g.
However, this is precisely what is not possible, since the database server cannot be reached via the external interface. Only the web server and the SSH server can be accessed remotely. For the database server it must therefore appear as if our connection request comes from the inward-facing interface on the server.
This is where local port forwarding comes into play. It can be used to forward any free, local port to a remote (and there in turn local) port.
Start local port forwarding
Forwarding is set up through a so-called "tunnel" with the help of an SSH connection on port
22 from the local computer (laptop) to the remote computer (server):
$ ssh -f -N -L 3306:127.0.0.1:3306 remote.example.com
-f parameter puts
ssh in the background while
-N indicates that no command is to be executed on the remote computer.
The most important parameter here, however, is
-L, with which the local port forwarding is set up. The value for the
-L parameter is in general:
First, the local host name or IP (
LOCALHOST) and the port to be used (
LOCALPORT) must be specified, then the remote host name or IP (
REMOTEHOST) and the port to be used there (
REMOTEPORT). Specifying the
LOCALHOST is optional. However, it is important that the
REMOTEHOST address is given at which the service can actually be reached on the server, in our case it is
Port forwarding is set up here from the local port
3306 to the remote port
3306. If the local port
3306 is occupied because there is also a database server running on the local computer, any other free local port should be selected.
Instead of the name
remote.example.com you could also use the IP of the server at the end of the
ssh command. And if the username with which this command is executed on the local computer is not identical to the username on the server,
firstname.lastname@example.org would be used instead of just
user is the username on the remote computer.
The following figure illustrates the principle:
You want to administer the database on the server
remote.example.com from a laptop. The MySQL server can be reached on port
3306, but only from "within" the remote computer. In contrast, the SSH server on port
22 can be reached from inside and outside. Port forwarding is set up from the laptop, which "tunnels" port
3306 from the laptop to the server via SSH and ends at the local port
Thus the database server to be administered would not be configured in the local program with
remote.example.com:3306, but with
Stop local port forwarding
To stop the port forwarding, the process ID is obtained on the local computer and a SIGTERM signal is sent to this process, e.g. as follows:
$ ps -C ssh -o pid=,cmd= 28364 /usr/bin/ssh -f -N -L 3306:127.0.0.1:3306 remote.example.com $ kill 28364