Secure Shell (SSH) is the name of a tool set and a network protocol to exchange data using a secure channel between two networked devices. In general SSH is used to open secure data connections between applications or to access remote hosts via a secure channel.
A lesser known feature is the ability to forward network connections from one host to another one by utilizing a secure channel. This feature is also known as tunneling network connections.
Contents
As a basic principle just keep in mind, that the SSH tools may build tunnels and open up listening ports on local and remote hosts. What exactly to do has to be configured by the proper choice of command line parameters. But the most important fact is the requirement to connect to the remote machine via the SSH protocol. Therefore you are required to key in the credentials and the client has to be able to connect the server.
All configuration variants are starting a SSH connection from the host named Client. This will open up a network tunnel to provide applications from the host Client or its neighbours access to contents on remote servers by utilizing the local end of the tunnel.
To forward connection requests from a local port to a remote application you may build up a tunnel by specifying the local and remote port number while connecting to the remote host. Note, that all data send via network connections are encrypted.

By utilizing the tunnel a number of network connections may be opened and used simultaneously.
1234567891011 |
# common pattern for building up the tunnel# parameters:# localport: starting point of the tunnel at the client side# remoteport: ending point of the tunneled connection$ ssh -L <localport>:localhost:<remoteport> username@server # e.g. forward all HTTP requests via the local port 8877 to the remote # application that is serving at port 8000 to local processes# at the host 'linux-support.com'$ ssh -L 8877:localhost:8000 joedoe@linux-support.com |
You are also allowed to forward a connection from the end of the tunnel (at Server 1) to another server. But this solution will result in data to be transferred unencrypted between Server 1 and Server 2.

By utilizing the tunnel a number of network connections may be opened and used simultaneously.
12345678910111213 |
# common pattern for building up the tunnel# parameters:# localport: starting point of the tunnel at the client side# remoteport: ending point of the connection (at server 2)# server1: ending point of the encypted tunnel# server2: ending point of the connection$ ssh -L <localport>:<server2>:<remoteport> <username>@<server1> # e.g. forward all HTTP requests via the local port 8877 to the remote # application that is serving at port 80 at the host 'linux-support.com'# by utilizing myhopserver as ending point of the encypted tunnel$ ssh -L 8877:linux-support.com:80 joedoe@myhopserver |
When opening a tunnel from your local host, the listening socket will be bound to the loopback interface only. So just the applications at your local host will be allowed to use the tunnel. If you want to allow other users at other computers to use your tunnel just add an additional parameter to your command while opening the network tunnel.
This configuration is valid for both variants of port forwarding explained above. Just replace bind_address with a ip-address or hostname that is assigned to one of your local network interfaces.
123 |
# provide access to your tunnel to other network devices$ ssh -L bind_address:port:host:hostport username@server |
Please note: By executing the command above everybody will be allowed to enter your network tunnel who has access to the specified bind_address! E.g. when accessing the internet without a protecting firewall or router appliance every internet user may be able to access your tunnel!
All configuration variants are starting a SSH connection from the host named Client. This will open up a network tunnel to provide remote applications at the host Server or its neighbours to access contents on local servers by utilizing the remote end of the tunnel.
To forward connection requests from a remote port to a local application you may build up a tunnel by specifying the local and remote port number while connecting to the remote host. Note, that all data send via network connections are encrypted.

By utilizing the tunnel a number of network connections may be opened and used simultaneously.
1234567891011 |
# common pattern for building up the tunnel# parameters:# localport: starting point of the tunnel at the client side# remoteport: ending point of the tunneled connection$ ssh -R <remoteport>:localhost:<localport> username@server # e.g. forward all HTTP requests via the remote port 8877 to the local# application that is serving at port 80 to remote processes# at the host 'linux-support.com'$ ssh -R 8877:localhost:80 joedoe@linux-support.com |
You are also allowed to forward a connection at the end of the tunnel (at Client) to another server within your intranet. But this solution will result in data to be transferred unencrypted between Client and Server 2.

By utilizing the tunnel a number of network connections may be opened and used simultaneously.
12345678910111213 |
# common pattern for building up the tunnel# parameters:# localport: starting point of the tunnel at the client side# remoteport: ending point of the connection (at server 2)# server1: ending point of the encypted tunnel# server2: ending point of the connection$ ssh -R <remoteport>:<server2>:<localport> <username>@<server1> # e.g. forward all HTTP requests via port 8877 at Server 1 to the # application that is serving at port 80 at the host 'srv1-in-intranet'# by utilizing myhopserver as starting point of the encypted tunnel$ ssh -R 8877:srv1-in-intranet:80 joedoe@myhopserver |
When opening a tunnel directing from a remote server to your local host, the listening socket will be bound to the loopback interface only. So just the applications at the remote host will be allowed to use the tunnel. If you want to allow other users at other computers to use your tunnel just add an additional parameter to your command while opening the network tunnel.
This configuration is valid for both variants of port forwarding explained above. Just replace bind_address with a ip-address or hostname that is assigned to one of the network interfaces at your server.
123 |
# provide access to your tunnel to other network devices$ ssl -R [bind_address:]port:host:hostport username@server |
Please note: By executing the command above everybody will be allowed to enter your network tunnel who has access to the specified bind_address! E.g. when forwarding connections from an internet server every internet user may be able access your tunnel and though your intranet servers!
Ssh comes with a build-in feature to run a SOCKS proxy server. Details regarding this operation mode may be found in article Proxy Server with SSH.
A SOCKS proxy server accepts a connection request that will specify the connection target including the hostname and port number to connect. So applications connecting to your proxy server will be able to connect every server and service that would be available when running on the Server at the endpoint of the tunnel.
Related resources:
Related resources: