Remote Port Forwarding with SSH
Make local services available on the Internet
A problem for many homeworkers is how to make locally available services, such as a website under development, available to a customer on the Internet. This article shows how to achieve this with an SSH-only solution.
Trapped in the local network
Every developer knows the situation: Usually you develop your programs or a website on your home computer, regardless of whether it is a laptop, desktop or a server in the basement. This computer is located in a local network from which connections to the Internet can be made, but not in the opposite direction.
This is prevented by the "Network Address Translation" (NAT) in the home router, which also establishes the connection to the Internet. An address from the Internet is made available to all computers in the local network as soon as they establish a connection to the Internet. Within the local network, the computers work with addresses that are not processed on the Internet.
The advantage of this technology that not all computers in the local network have to be equipped with an address from the Internet is at the same time its greatest disadvantage: they cannot be easily reached from the Internet.
Port forwarding and dynamic DNS
The standard solution in this case is to set up so-called port sharing on the router. This means that connection requests from the Internet that are directed to the Internet address of the router can be forwarded to certain computers in the home network.
The problem with this is that the router's Internet address changes constantly, usually even daily, which in turn can be solved by dynamic DNS (DDNS). However, this can already cause some effort and costs, namely if you want to use your own domain names and not those provided by the DDNS provider.
This effort has not been reduced by the introduction of IPv6 and sometimes - depending on the provider - will be without success.
Another disadvantage: if you are going to work in a network other than your home network, this construction will no longer work.
Forwarding services
This is where providers such as ngrok or localtunnel come into play. Instead of establishing a fixed forwarding from the Internet via the home router to a specific computer in the home network, a connection from the workstation computer to the service provider is established and kept open so that it can also be used in the opposite direction. This way you can set up and use such a connection from anywhere.
Even with these services, however, the domain names used are not freely selectable unless you are willing to pay for this service.
If you don't want that and want to set up an even more advanced solution with your own resources, you will find instructions in this and the related articles that are mainly based on SSH.
However, a prerequisite is that a computer with SSH access is available on the Internet, e.g. a "Virtual Private Server" (VPS) like Lightsail from Amazon Web Services, vServer from HostEurope or similar products from other providers.
Remote port forwarding with SSH
In another article in this blog, local port forwarding is described as a solution when you want to connect your home computer to a service on a computer on the Internet that does not accept connection requests from outside for this service.
Now the problem is exactly the other way around: We want to reach our home computer from a computer on the Internet, e.g. a website that runs on the local computer. Since no connection can be established from the outside, it must be set up by the local computer.
The solution in this case is remote port forwarding, which can be set up with SSH in exactly the same way as local port forwarding, except that instead of the -L
parameter, the -R
parameter is used and its value is in general:
[REMOTEHOST:]REMOTEPORT:LOCALHOST:LOCALPORT
It should be noted here that the REMOTEPORT
on the REMOTEHOST
must not already be occupied, just as the LOCALPORT
of the LOCALHOST
must not already be occupied with the local port forwarding.
In the example used here, a web server is already running on the remote computer that accepts requests on port 80
. Therefore port 8080
is used as REMOTEPORT
.
So if a local website that can be reached on the local computer on the standard port 80
is to be made available on a remote computer on port 8080
, port forwarding should be initiated as follows:
$ ssh -f -N -R 8080:localhost:80 VPS
This means that every request that is sent to port 8080
on the remote computer is "tunneled" through the connection established with SSH to the home computer and port 80
.
The following figure shows this schematically: Port 80
of the home PC on the left cannot be reached directly via the router for the client on the right. However, if you start a remote port forwarding to the VPS on the home PC, port 80
of the home PC can be addressed as port 8080
on the VPS.
An open gateway is required
However, this forwarding has one major disadvantage: The emphasis in the penultimate paragraph is on "request that is sent to port 8080
on the remote computer (VPS)". This port cannot be reached from outside the VPS.
This can be seen very well if you look at the open ports on the VPS, e.g. with the command netstat
:
$ sudo netstat -ltpn
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 27651/sshd: uwe
tcp6 0 0 ::1:8080 :::* LISTEN 27651/sshd: uwe
$
As you can see, the SSH server, which accepts requests on port 8080
, can only be reached via the local network interface 127.0.0.1
, i.e. from within the VPS and not from outside.
You would have to start the browser on the VPS in order to access the website on the home computer via the address http://localhost:8080/
. This is usually undesirable and also impractical. Rather, you want a completely different computer, for example a customer's workstation computer, to be able to access the home computer via the VPS.
The server on the Internet would therefore have to form a so-called "open gateway" and make forwarded ports accessible from the outside, but the standard configuration of an SSH server forbids this with the GatewayPorts no
option.
To allow the SSH server to be used as a gateway, the GatewayPorts
option must be changed to yes
in the corresponding configuration file (usually /etc/ssh/sshd_config
).
After restarting the SSH server, the netstat
command shows the following output:
$ netstat -ltpn
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 27651/sshd: uwe
tcp6 0 0 :::8080 :::* LISTEN 27651/sshd: uwe
$
Now it is possible to use the ssh
tunnel from anywhere.
Alternative solutions
The opening of any forwarded port for all computers on the Internet poses a certain security risk and is therefore not deactivated in the standard configuration of an SSH server without any reason. In addition, it may not be possible to change anything in the SSH server configuration on the VPS. Therefore, it is necessary to consider alternative solutions.
Two options that do not require the configuration of the SSH server as an open gateway are either the combination of remote and local port forwarding or the use of a web server as a reverse proxy.