CalcSnippets Search
DevOps 3 min read

`ssh -L` Port Forwarding Feels Like Magic Until You Realize It Is Just a Clean Tunnel

A practical SSH local port forwarding guide for developers who need private database access, internal dashboards, or remote services available on localhost without exposing them publicly.

Why this command feels magical to newcomers: because the result looks strange at first. A remote service suddenly appears on localhost. Once the tunnel idea clicks, it becomes one of the most useful safe-access tools in development.

What ssh -L actually does

Local port forwarding creates a tunnel from a local port on your machine to a target reachable from the SSH server side. The OpenBSD ssh manual describes -L as specifying local port forwarding. That is the formal definition.

In practical terms, it means:

  1. you connect to an SSH-accessible machine
  2. SSH listens on a local port
  3. traffic sent there is forwarded through the tunnel to the remote target

That lets you access private services without exposing them directly to the internet.

The command pattern

ssh -L 5433:127.0.0.1:5432 user@server

This means:

  1. listen locally on port 5433
  2. forward through the SSH connection
  3. reach 127.0.0.1:5432 from the server side

Now your local machine can talk to the remote database through localhost:5433.

Why this is better than “just opening the port”

Because a lot of internal services were never meant to be internet-facing. Databases, admin panels, internal metrics dashboards, and staging tools are often safer when kept private.

Port forwarding lets you reach them without turning every access need into a firewall exception or public endpoint. That is the operational win: convenient access with a smaller exposure surface.

A very common real-world use case

Suppose Postgres runs on a server and only listens locally there. You want to inspect it from your laptop:

ssh -L 5433:127.0.0.1:5432 deploy@my-server

Then connect locally with:

psql -h 127.0.0.1 -p 5433

Nothing mystical happened. You created a tunnel and pointed your local tool at the tunnel entry point.

Why the host part confuses people

The most common misunderstanding is the right-hand host in local_port:host:remote_port.

That host is resolved from the remote side, not from your laptop. So 127.0.0.1 there means “localhost relative to the SSH server,” not your local machine.

This is exactly why the command is so useful for reaching services bound only inside the remote environment.

A few quality-of-life options

To avoid opening an interactive shell:

ssh -N -L 5433:127.0.0.1:5432 deploy@my-server

-N means do not execute a remote command. That is often what you want for a pure tunnel.

You can also use config aliases from ~/.ssh/config so the tunnel command becomes shorter and less error-prone.

When this is the right tool

Use it when you need:

  1. secure one-off access to a remote private service
  2. local tooling pointed at a remote backend
  3. an internal dashboard or database on your laptop without public exposure

Do not use it as a substitute for good long-term architecture when a real network path or proper service access model is needed. It is a tunnel, not a complete infrastructure strategy.

Final recommendation

If you need a private remote service to appear on localhost, learn ssh -L. Once you understand which side owns which host and port, the command stops feeling magical and starts feeling like a precise, safe workflow tool.

Sources

Keep reading

Related guides