SSH Tunnels and Port Forwarding

SSH does more than open shells. It can forward TCP ports between machines, creating encrypted tunnels through any network that allows SSH. Three flavors — local, remote, and dynamic — solve very different problems.

Local forwarding (-L) — reach a service THROUGH a server

Maps a local port on YOUR machine to a remote port reachable from the SSH server.

ssh -L 8080:localhost:80 user@server.example.com

Now localhost:8080 on your laptop is connected to server:80 via the encrypted SSH tunnel.

Useful examples

# Reach an internal database not exposed to internet
ssh -L 5432:internal-db:5432 user@bastion.example.com
psql -h localhost -p 5432

# Reach an internal admin panel through a jump host
ssh -L 8443:internal-grafana:443 user@bastion.example.com
# Now visit https://localhost:8443

# Tunnel multiple ports at once
ssh -L 5432:db:5432 -L 6379:redis:6379 user@bastion

Remote forwarding (-R) — expose YOUR local service to the server

Maps a port on the SSH server to a port on YOUR local machine. Useful when the server can’t initiate connections back to you (NAT, firewall) but you want it to reach a service on your laptop.

ssh -R 9000:localhost:3000 user@server.example.com

Now anyone on server who connects to localhost:9000 reaches localhost:3000 on YOUR laptop.

Useful examples

# Quickly demo a local dev server to someone on a remote machine
ssh -R 8080:localhost:3000 user@public-server
# They visit localhost:8080 on the server, see your local site

# Reverse SSH for a machine behind NAT
# Run this on the NAT'd machine to give YOU access:
ssh -R 2222:localhost:22 user@public-server
# Then from anywhere: ssh -p 2222 nat-user@public-server
#                     → reaches the NAT'd machine

Allowing remote forwards on the server

By default, remote forwards bind only to localhost on the server. To allow other machines to connect:

# In /etc/ssh/sshd_config on the server:
GatewayPorts yes

# Then bind to 0.0.0.0:
ssh -R 0.0.0.0:9000:localhost:3000 user@server

Dynamic forwarding (-D) — SOCKS proxy

Turns SSH into a SOCKS5 proxy. All traffic configured to use it gets tunneled through the SSH connection.

ssh -D 1080 user@server.example.com

Now configure your browser (or any app) to use localhost:1080 as a SOCKS5 proxy. Every connection goes through the server, encrypted and originating from the server’s IP.

Practical use

# Browse the internet through your VPS
ssh -D 1080 user@vps

# Then in Chrome:
chrome --proxy-server="socks5://localhost:1080"

# Or use a browser extension like SwitchyOmega for per-site control

Background tunnels

Most of the time you don’t want an interactive shell along with the tunnel. Use these flags:

ssh -fNL 8080:localhost:80 user@server

# -f  go to background after auth
# -N  don't execute a remote command (just maintain the tunnel)
# -L  the local forward
# -L can be replaced with -R or -D for the other modes

Persistent tunnels with autossh

SSH tunnels die when the connection drops. autossh automatically reconnects.

sudo apt install autossh

autossh -fN -L 8080:localhost:80 user@server

# Run as a systemd service for production reliability
sudo systemctl enable --now myssh-tunnel.service

Config-file tunnels (cleaner)

Define tunnels in ~/.ssh/config so you don’t have to remember commands:

Host db-tunnel
    HostName bastion.example.com
    User alice
    LocalForward 5432 internal-db:5432
    LocalForward 6379 internal-redis:6379

# Then just
ssh db-tunnel

Common gotchas

  • “Address already in use” — another tunnel or service is on the local port. Pick a different port or kill the conflicting process.
  • “Permission denied” on remote forward — remote sshd needs GatewayPorts enabled to expose the forward beyond localhost.
  • Tunnel drops — use ServerAliveInterval 60 in your SSH config to keep idle tunnels open through NAT.
  • Forgetting -N — without it, you also get an interactive shell, which can confuse scripts.

Security considerations

  • Tunnels can bypass firewalls — both for legitimate use AND for exfiltration. Some corporate environments forbid SSH tunneling.
  • If you forward sensitive services, the LOCAL endpoint is unauthenticated. Anyone on your laptop can connect to the tunneled port.
  • Use ssh-keygen + key-only auth on the server. Password-protected keys for laptops you carry around.

What to learn next

That covers VPN and tunneling. Next big section: network security — common attacks, segmentation, IDS/IPS, and packet capture. Up next.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *