Technical Playground

Fun With SSH Port Forwarding

SSH Port forwarding is a pretty magical bit of functionality – if you have SSH access to / from a device, you can work your way through most anything.

Some basic terminology:

  • Port forwarding – setting up a port and sending the traffic to a specific destination on either end of the SSH connection
  • Local forwarding – Setting up a listening port on a local interface (often the loopback) that forwards traffic to a destination accessible by the remote system. Can also be shared with other devices on the local network.
  • Remote forwarding – Setting up a listening port on an interface on the remote end of the SSH connection (i.e., the SSH server end.)
  • Dynamic forwarding – a local SOCKS proxy that forwards all traffic remotely so it looks like the connections are coming from the SSH server itself, not the local system.

So here are some basic “recipes” I use often with my SSH connections. Note these are all using the typical Linux / Mac SSH client (OpenSSH.) PuTTY is capable of most of these setups as well.

  • RDP based port forwards

Sometimes I need to connect to Windows RDP services across an SSH connection. If I setup a local listening port (3389 or others), I can forward that to the server in question. For example

ssh -L3389:rdpserveripaddress:3389 user@sshhost 

Once connected to the SSH server I can open an RDP client and connect to the local host on port 3389. Any traffic is automatically forwarded to the rdpserver on 3389 and the connection is active.

  • Dynamic forwarding

If you’re connected to an guest network (i.e., a coffee shop wifi network) you may not want your traffic visible to anyone monitoring the connection. An easy way to remedy this is with Dynamic port forwarding. This is configured with a simple -D option:

ssh -D 5544 user@sshhost

Once connected, you’d setup your web browser to use a SOCKS5 proxy on port 5544 on the localhost. Any web traffic would then be passed along to the SSH tunnel and the traffic sent back to you.

  • Remote forwarding to gain access to a fire walled server

SSH remote forwarding is somewhat rarely used but it can be incredibly powerful for gaining access to the inside of a network. This can be used to bypass firewalls, NAT, etc. One method I use to setup a simple SSH capable device (OpenWRT router, Beaglebone, Raspberry Pi, etc) and have it make an SSH connection outside to a server on the internet. Once connected, it sets up a remote port forward to listen on a port on the remote system that forwards traffic back to the local SSH server. In other words:

ssh -R 2222:localhost:22 user@sshhost

Now anyone with access to sshhost can run the command “ssh -p 2222 localhost” to access the local ssh server.

  • Remote forwarding for local web server testing

In a similar vein to the SSH access, you may want to allow a client access to a web server you’re running remotely. There are some services that do this, but sometimes it’s helpful to create something completely in your control.

ssh -R 8080:localhost:80 user@sshhost

This would give anyone accessing the remote server on port 8080 access to the local setup.

  • Internet of Things devices shared via remote forwarding

A final option would be to use a locally connected IoT device sharing its interface to the world over a remote SSH port forward. This works exactly the same as the other port forwarding except the traffic is going to a different destination on the local network vs the SSH client itself.

ssh -R 8088:IoTDeviceIP:80 user@sshhost

Now anyone accessing 8088 on the sshhost now has access to the local IoT device. This works fantastically well for any device that may be mobile / etc – it can connect from wherever it is, and in whatever network configuration (as long as it can reach the SSH host) and provide access to any local services.

Note that you may need to allow GatewayPorts in your SSH server configuration.

  • Updating forwarding options on an existing connection

Sometimes I want to add more forwarding options after I’ve already opened a connection. Pressing “~C” will open the SSH command prompt where you can do any of the following:


  -L[bind_address:]port:host:hostport    Request local forward
  -R[bind_address:]port:host:hostport    Request remote forward
  -D[bind_address:]port                  Request dynamic forward
  -KL[bind_address:]port                 Cancel local forward
  -KR[bind_address:]port                 Cancel remote forward
  -KD[bind_address:]port                 Cancel dynamic forward

This makes it very easy to add or remove forwarding configurations.