Signup/Sign In

How to Setup SSH Tunneling?

If you are connecting with a different Linux device on a different network then you would have to expose it to the public internet and that may put your system and files at risk.

SSH Tunneling or SSH port forwarding is useful for transporting data via internet services that use an unencrypted protocol, such as VNC or FTP, bypassing firewalls, or accessing geo-restricted content. Any TCP port and all traffic can be tunneled over a secure SSH connection.

SSH forwarding is primarily of three types,

  • Local forwarding: Forwards from client to SSH server, to the destination port.
  • Remote forwarding: Forwards from server to client port, and then on to destination port.
  • Dynamic forwarding: Creates a SOCKS proxy server allowing communication over multiple ports.

SSH Local Port Forwarding

Local forwarding is when we forward a port from the client (i.e. local machine) to the server (i.e. remote machine) and then forward it to the destination.

The client checks for connections on a given port, and when it receives a connection request, it will tunnel the request onto a port on the server. The server then connects to a different destination machine on the specified port.

It is mainly used to connect a remote service on an internal network domain to a machine from the outside like a database. It is also used for remote file share over the internet and through jump servers.

Let's say for example that you are restricted by a firewall to access an application running on a remote network on port 4000. Now, we will forward a local port (i.e. 8000), for local access.

For local forwarding, the ssh command is used with the -L flag, and the command is of the format:

ssh -L [LOCAL_IP:]LOCAL_PORT:DESTINATION:DESTINATION_PORT [USER@]SSH_SERVER
  • [LOCAL_IP:]LOCAL_PORT: IP, and port number of the client. Only ports greater than 1024 can be used.
  • DESTINATION:DESTINATION_PORT: IP, and port number of the destination.
  • [USER@]SSH_SERVER: Username, and server address or IP.

To run this command in the background, we use the -f flag.

Hence, for the example above, we get

ssh -L 8000:server1.example.com:4000 admin@server.example.com

Now we can access server1.example.com:3000, using localhost:8000, in the browser.

Remote Forwarding

Remote forwarding is the opposite of local forwarding. Instead of tunneling a client port, to the server, and on to the destination, we tunnel a server port, to a client, which is forwarded on to the destination.

By default, remote forwarding is disabled in SSH. To enable it, we need to enable it in our SSH config file (sshd_config, for server configs).

Open the SSH config file using your editor.

sudo vim /etc/ssh/sshd_config

Search for GatewayPorts and set it as yes.

GatewayPorts yes

Save the changes, and restart your server.

sudo systemctl restart sshd

Once remote forwarding is enabled, we use the -R flag, and the command is of the following format.

ssh -R [REMOTE:]REMOTE_PORT:DESTINATION:DESTINATION_PORT [USER@]SERVER
  • [REMOTE:]REMOTE_PORT: Remote IP, and port number.
  • DESTINATION:DESTINATION_PORT: Destination IP, and port number.
  • [USER@]SSH_SERVER: Username, and server address or IP.

For example,

ssh 8080:127.0.0.1:3000 admin@server.example.com

Remote port forwarding is used when someone from outside is to be given access to an internal service.

Dynamic Port Forwarding

Local and Remote forwarding allows communication and tunneling only in one direction, but dynamic forwarding can tunnel over multiple ports.

It creates a socket on the local machine that works as a SOCKS proxy server, and by default listens on port 1080. When a server connects to this port, it is forwarded to the remote machine, then to the dynamic machine on a dynamic port.

SOCKS is an internet protocol, defining how a client connects to a server via proxy (SSH in this case). To enable dynamic port forwarding we use the -D flag. The command for dynamic port forwarding is of the following format.

ssh -D [LOCAL_IP:]LOCAL_PORT [USER@]SSH_SERVER
  • [LOCAL_IP:]LOCAL_PORT: Local IP address, and port number.
  • [USER@]SSH_SERVER: Username, and remote IP, or name.

For example, to connect to remote host, by starting a proxy on port 1080, we run

ssh -D 1080 admin@server.example.com

To tunnel an ssh session over the SOCKS proxy on localhost and port 9699

ssh -o "proxyCommand netcat -x 127.0.0.1:9699 -X 4 %h %p" admin@server.example.com

Conclusion

SSH tunneling is used to encrypt and secure a connection, and share data securely, or to access geo-restricted content via proxy.



About the author:
Pradeep has expertise in Linux, Go, Nginx, Apache, CyberSecurity, AppSec and various other technical areas. He has contributed to numerous publications and websites, providing his readers with insightful and informative content.