Hi, I'm Chris

This blog is about programming, linux and other stuff. Please don’t hesitate to contact me if you have any questions or suggestions for improvements! contact

SSH tunnel / port forwarding: simple example

Why ssh port forwarding

If you want to access some service running on a remote machine (in my case a webserver), you usually have to expose the port of that service - otherwise it is not reachable form the outside. However, often you don’t want to expose more ports then necessary to the public and only a specific (small) group - which already has ssh access to the remote machine - needs to access this service. This is where ssh port forwarding (also called ssh tunneling) is useful. An example for this: you want to run a jupyter notebook on a server but - for security reasons - you are not allowed to export the port (e.g. 8000) to the public.

Using ssh port forwarding, the remote service can be accessed from you local machine using an arbitrary address which is then forwarded to the ‘correct’ address/port on the remote machine. That means you can just open up localhost:8000 in your browser and will see the notebook running on a remote machine.

A fast way to setup a file server

For a simple example, lets set up a file server on a on the remote machine and access it via ssh port forwarding on our local machine.

ssh passwordless login

To makes things easier, we want to access the remote machine without using a password. This step is not necessary but makes working with ssh tunnels more convenient.

ssh-copy-id -i ~/.ssh/mykey remoteuser@remotehost

Where mykey is your public key, remoteuser your username on the remote machine, and remotehost the remote machine (e.g., ip address or an alias).

ssh tunnel

First, lets start a service on the remote machine so that there is something we can access. As the remote user run

python3 -m http.server --bind localhost 8000

Notice, that we bind it to localhost and not to the default, hence its only accessible from the same machine.

Now, to be able to access this service on your local machine, run

ssh -N -L localhost:8000:localhost:8000 remoteuser@remotemachine -f

on your local machine.

Lets see what these arguments do:

  • -N Do not execute a remote command.
  • -f Requests ssh to go to background just before command execution.
  • -L localhost:8000:localhost:8000 Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.
  • remoteuser@remotemachine user and host used by ssh to establish the connection

If you don’t use the default port 22 you have to specify the port by -p PORT

Now, you should be able to access the files (in the directory of the remote machine where you started the file server) via http://localhost:8000.

.. to disable the port forwarding, kill the corresponding process.

PS: Keep in mind, the python http module is not a production grade file server and user who have access to your machine are also able to access the services that you run.