Skip to content

SSH Port Forwarding

SSH Port Forwarding is a method to transport additional data streams within an existing SSH session. SSH tunneling helps achieve security use cases such as remote web service access without exposing port on the Internet, accessing server behind NAT, exposing local port to the Internet, etc.

Local SSH port forwarding

Local port forwarding creates a tunnel from the client host port to the SSH server port.

Use the following command to configure local port forwarding:

ssh -L [LOCAL_IP:]LOCAL_PORT:DESTINATION:DESTINATION_PORT [USER@]SERVER_IP

The options used are the following:

  • [LOCAL_IP:]LOCAL_PORT: The local host IP address and port number. When LOCAL_IP is omitted, the ssh client binds on the localhost.
  • DESTINATION:DESTINATION_PORT: The IP or hostname and the port of the destination host.
  • [USER@]SERVER_IP: The remote SSH user and server IP address.

Info

Reserved ports
Port numbers 0-1023 are called Well-known Ports and are reserved for common TCP/IP applications.
Port numbers 1024-49151 are called Registered Ports and are assigned by IANA (Internet Assigned Numbers Authority) for specific service upon application by a requesting entity. You can check registered ports in the following list.
Port numbers 49152-65535 are called The Dynamic and/or Private Ports, and cannot be registered with IANA.
You can check which ports are free or busy on your system by checking the /etc/services file.

Example

Consider as an example that PostgreSQL database on remote server listens on port 5432, which is inaccessible from the Internet. Using SSH local port forwarding, the client connects to the remote server to forward the client's local port 5432 to the server's local port 5432, with the following command:

ssh -L 5432:127.0.0.1:5432 user@<remote_db_server>

By default, an interactive session is created for you when you command local port forwarding. To prevent interactive sessions, you can use the -N flag that tells SSH to not to execute remote commands.

Remote SSH port forwarding

Remote port forwarding, also known as reverse tunneling, allows you to forward a port on the remote (ssh server) host to a port on the local (ssh client) host.

Use the following command to configure remote port forwarding:

ssh -R [REMOTE:]REMOTE_PORT:DESTINATION:DESTINATION_PORT [USER@]SERVER_IP

The options used are the following:

  • [REMOTE:]REMOTE_PORT: The IP and the port number on the remote SSH server. An empty REMOTE means that the remote SSH server will bind on all interfaces.
  • DESTINATION:DESTINATION_PORT:The IP or hostname and the port of the destination host.
  • [USER@]SERVER_IP: The remote SSH user and server IP address.
Example

For example, this method can be used if a client runs a web server on port 3000 but cannot expose this web server to the public Internet as the client host is behind NAT. The remote server, on the other hand, can be reachable via the Internet. The client can SSH into this remote server. In this situation, client can expose the webserver on port 3000 to the Internet, configuring a reverse tunneling with the following command:

ssh -R 80:127.0.0.1:3000 user@<remote_server_ip>

After that, when users visit port 80 of the remote server as http://<remote_server_ip>, the request is redirected back to the client's local server (port 3000) via SSH tunnel where the local server handles the request and response.

By default, the remote port forwarding tunnel will bind to the localhost of the remote server. To enable it to listen on the public interface (for a scenario like above example), set the SSH configuration GatewayPorts yes in /etc/ssh/ssh_config.

Dynamic SSH port forwarding

Dynamic port forwarding allows you to create a socket on the local (ssh client) host, which acts as a SOCKS proxy server. When a client connects to this port, the connection is forwarded to the remote (ssh server) host, which is then forwarded to a dynamic port on the destination host.

This type of port forwarding is used if the ports are unknown beforehand or traffic wants to be relayed to an arbitrary destination.

Use the following command to configure dynamic port forwarding:

ssh -D [LOCAL_IP:]LOCAL_PORT [USER@]SERVER_IP

The options used are the following:

  • [LOCAL_IP:]LOCAL_PORT: The local host IP address and port number. When LOCAL_IP is omitted, the ssh client binds on localhost.
  • [USER@]SERVER_IP: The remote SSH user and server IP address.
Example

An example of dynamic port forwarding is to tunnel the web browser traffic through an SSH server.

To do so, the following command will create a SOCKS tunnel on port 9090:

ssh -D 9090 -N -f user@remote.host