SSH port forwarding (ssh tunnels)


SSH port forwarding is used for tunneling application ports between machines. It can be used for...


Local Forwarding

The SSH client listens for connections on a configured port, and when it receives a connection, it tunnels the connection to an SSH server. The server connects to a configurated destination port, possibly on a different machine than the SSH server.

Typical uses for local port forwarding include:

Organizations often route incoming SSH access through a jump server, which can be a standard Linux/Unix box or a commercial jump server solution.

Kump servers can allow incoming port forwarding, once the connection has been authenticated. This allows users to use internal resources quite transparently.

In OpenSSH, local port forwarding is configured using the -L option:

This example opens a connection to the my.example.com jump server, and forwards any connection to port 80 on the local machine to port 80 on intra.example.com.

By default, anyone (even on different machines) can connect to the specified port on the SSH client machine. However, this can be restricted to programs on the same host by supplying a bind address:


Remote Forwarding

In OpenSSH, remote SSH port forwardings are specified using the -R option. For example:

    ssh -R 8080:localhost:80 public.example.com

This allows anyone on the remote server to connect to TCP port 8080 on the remote server. The connection will then be tunneled back to the client host, and the client then makes a TCP connection to port 80 on localhost. Any other host name or IP address could be used instead of localhost to specify the host to connect to.

This example would give someone on the outside access to an internal web server.

By default, OpenSSH only allows connecting to remote forwarded ports from the server host. However, the GatewayPorts option in the server configuration file sshd_config can be used to control this. The following alternatives are possible:

    GatewayPorts no

This prevents connecting to forwarded ports from outside the server computer.

    GatewayPorts yes

This allows anyone to connect to the forwarded ports. If the server is on the public Internet, anyone on the Internet can connect to the port.

    GatewayPorts clientspecified

The client can specify an IP address from which connections to the port are allowed. The syntax for this is:

    ssh -R 40.172.1.73:8080:localhost:80 host147.aws.example.com

Only connections from the IP address 40.172.1.73 to port 8080 are allowed.

OpenSSH also allows the forwarded remote port to specified as 0. In this case, the server will dynamically allocate a port and report it to the client. When used with the -O forward option, the client will print the allocated port number to standard output.


Opening Backdoors into the Enterprise

Remote SSH port forwarding is often used to open backdoors into the enterprise. For example from a server on the cloud, log in from the office to that server, specifying remote forwarding from a port on the server to some server or application on the internal enterprise network. Multiple remote forwards may be specified to open access to more than one application.

We would set GatewayPorts yes on the server.

For example, the following command opens access to an internal Postgres database at port 5432 and an internal SSH port at port 2222.

    ssh -R 2222:d76767.nyc.example.com:22 -R 5432:postgres3.nyc.example.com:5432 aws4.mydomain.net


Server-Side Configuration

The AllowTcpForwarding option in the OpenSSH server configuration file must be enabled on the server to allow port forwarding. By default, forwarding is allowed. Possible values for this option are yes or all to allow all TCP forwarding, no to prevent all TCP forwarding, local to allow local forwardings, and remote to allow remote forwardings.

Another option of interest is AllowStreamLocalForwarding, which can be used to forward Unix domain sockets. It allows the same values as AllowTcpForwarding. The default is yes.

For example:

    AllowTcpForwarding remote
    AllowStreamLocalForwarding no

The GatewayPorts configuration option as described above also affects remote port forwardings. Possible values were no (only local connections from server host allowed; default), yes (anyone on the Internet can connect to remote forwarded ports), and client specified (client can specify an IP address that can connect, anyone can if not specified).


See also