SSH tunnels & transfers

Key takeaways SSH can carry more than a shell — it can tunnel a port securely, so you reach a remote service without opening it to the world. ssh -L brings a remote service to your machine, ssh -R exposes a local one on the remote side, and ssh -D spins up a quick SOCKS proxy. Everything rides one encrypted secure tunnel, so there’s no extra inbound port to expose. And the same connection moves files: scp for one-offs, rsync for efficient directory syncs.

You already know SSH as a way to get a shell on another machine — see the Linux path’s SSH & working remotely lesson. But the encrypted connection SSH builds can carry any TCP traffic, not just your keystrokes. That turns SSH into a general-purpose tunnel: a way to reach a service on the far end (or let the far end reach one on yours) without exposing that service to the open internet.

Local forwarding (-L)

Local forwarding brings a remote service to your machine. You open a port on your own computer, and SSH tunnels anything sent to it across to a destination the remote host can reach:

$ ssh -L 8080:localhost:80 alice@192.168.1.50

Read the -L argument as three parts: 8080 is the port that opens on your localhost, and localhost:80 is the destination as seen from the remote host. So this makes the remote’s port 80 appear on your localhost:8080 — point your browser at http://localhost:8080 and you’re talking to the remote’s web server.

This is perfect for reaching a database or admin panel that only listens on the remote’s localhost — a service deliberately bound so it’s not reachable from the network. You don’t open it up; you tunnel into it. The service still thinks it’s only talking to local connections, because from its point of view it is.

Remote forwarding (-R)

Remote forwarding is the mirror image: it exposes one of your local services on the remote side. You open a port on the remote machine, and connections to it tunnel back to a service on your end:

$ ssh -R 9000:localhost:3000 alice@192.168.1.50

Now anyone who can reach localhost:9000 on the remote host is really talking to localhost:3000 on your machine. This is useful when your machine sits behind NAT — a home router that gives you no public address — and you want a service on it reachable from elsewhere, without configuring port forwarding on the router. The outbound SSH connection does the work that an inbound port rule would otherwise have to.

Dynamic (-D)

Dynamic forwarding doesn’t tunnel one fixed destination — it stands up a quick SOCKS proxy and routes whatever you point at it out through the SSH server:

$ ssh -D 1080 alice@192.168.1.50

Set your browser’s SOCKS proxy to localhost:1080 and every page it loads now exits from the remote machine’s network. It’s a fast, install-nothing way to browse as if you were sitting on the far end — handy for reaching something that’s only visible from inside the remote network.

Why tunnels beat opening ports

The common thread is that everything rides the encrypted SSH connection you already trust. To reach a remote service the naive way, you’d bind it to the network and open an inbound port — another door to the internet, another thing to secure, another target for scanners. A tunnel avoids that entirely: the service stays bound to localhost, and you reach it through SSH’s single, authenticated, encrypted channel. No extra inbound port, no new attack surface.

For occasional access this is lighter and safer than exposing a service directly. When you need many services or always-on access between whole networks, a VPN is the heavier, more permanent tool for the job — an SSH tunnel is the quick, per-service answer.

Copying files

The same SSH connection also moves files, so you don’t need a separate protocol. Use scp (“secure copy”) for a one-off transfer — the syntax mirrors cp, with user@host: in front of the remote path:

$ scp capture.cfile alice@192.168.1.50:/home/alice/    # local  -> remote
$ scp alice@192.168.1.50:/var/log/app.log ./           # remote -> local

Use rsync to sync whole directories efficiently. It compares the two sides and transfers only the parts that changed, so re-running it to update a large folder is fast:

$ rsync -av ./captures/ alice@192.168.1.50:/home/alice/captures/

Reach for scp when copying a file or two, and rsync when keeping directories in step over a slow or repeated transfer.

Quick check: a database on a remote server only listens on that server's localhost. How do you reach it from your laptop securely?

Recap

  • SSH tunnels carry any TCP traffic over its encrypted connection — not just a shell.
  • ssh -L (local) brings a remote service to a port on your machine; great for a database or panel bound to the remote’s localhost.
  • ssh -R (remote) exposes one of your services on the remote side — useful behind NAT without router port forwarding.
  • ssh -D opens a quick SOCKS proxy that routes your browser through the SSH server.
  • Tunnels avoid opening an extra inbound port; a VPN is the heavier alternative for always-on, network-wide access.
  • Move files on the same connection: scp for one-offs, rsync for efficient directory syncs.

Next up: packet capture basics