SSH tunneling allows users to securely access network resources over an unsecured network. This is accomplished by creating a secure tunnel through which data can be transmitted between two networked devices.
Local forwarding
Local forwarding is used to securely access a network resource on a remote network from a local device. This is done by creating a tunnel between the local device and the remote network resource. For example, to access a remote database server using local forwarding, the following command can be used:
ssh -L 3306:localhost:3306 user@remote-server.com
This command creates a tunnel from the local machine’s port 3306 to the remote server’s port 3306, which is the default port for MySQL databases. Now, the user can access the remote database server by connecting to the local machine’s port 3306 using a MySQL client.
Remote forwarding
Remote forwarding, on the other hand, is used to securely access a network resource on a local network from a remote device. This is accomplished by creating a tunnel between the remote device and the local network resource. For example, to access a local web server using remote forwarding, the following command can be used:
ssh -R 8080:localhost:80 user@remote-server.com
This command creates a tunnel from the remote server’s port 8080 to the local machine’s port 80, which is the default port for web servers. Now, the user can access the local web server by connecting to http://remote-server.com:8080 from a web browser.
How to make the tunnel port accessible from the outside?
You can use a reverse proxy, like nginx or apache.
Another option is to explicitly specify the bind_address
as 0.0.0.0
in the command:
ssh -R -T 0.0.0.0:8080:localhost:80 user@remote-server.com
To allow the client choose the bind address, you need add the line below to your server's SSH config /etc/ssh/sshd_config
.
GatewayPorts clientspecified
You can use netstat
to confirm that the server is properly listening for remote connections.
sudo netstat -lntp | grep 8080
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1049/nginx: master
tcp6 0 0 :::8080 :::* LISTEN 1049/nginx: master
Dynamic port forwarding
Dynamic port forwarding is a feature of the SSH protocol that allows the client to request a connection to a server-side port from the server. The server then establishes a connection to the requested port and forwards traffic between the client and the server over the established SSH connection.
Dynamic port forwarding is useful for situations where you want to connect to a remote network through a secure tunnel, but you don't know in advance which ports on the remote network you need to access. For example, you might use dynamic port forwarding to access local resources on a remote network, such as a database or web server, without having to set up a specific port forward for each resource.
The -D
argument is used to create port forwarding. By selecting this option, SSH will function as a SOCKS proxy server.
ssh -D 1080 user@remote_server.com
This will establish an SSH connection to remote_server
and bind a local port (in this case, 1080) as a dynamic forward. You can then configure your local web browser or other application to use the dynamic forward as a proxy, and all traffic will be forwarded securely over the SSH connection.
Summary
SSH tunneling provides a secure way to access network resources over an unsecured network.
Local forwarding allows users to securely access a network resource on a remote network from a local device. Most commonly used for accessing secure services such as databases, queues or web apps only accessible trough a company LAN network.
Remote forwarding allows users to securely access a network resource on a local network from a remote device. Â Most commonly used for exposing local development environments such as web apps.
Dynamic forwarding is useful when you want to access everything on the remote machine's network, such as databases, web services, CCTV apps that use various ports for streaming, or simply use the remote server as a proxy for your computer.
All types of tunneling can be useful in different scenarios and can be easily configured using the appropriate command.