SSH Cheatsheet
Port Forwarding and Tunneling
Use this SSH reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Tunnel Types at a Glance
| Type | Flag | Direction | Use case |
|---|---|---|---|
| Local forwarding | -L | Local port → Remote service | Access a remote DB locally |
| Remote forwarding | -R | Remote port → Local service | Expose local service through server |
| Dynamic (SOCKS) | -D | Local SOCKS proxy → anywhere | Route browser traffic via SSH host |
Local Port Forwarding (-L)
ssh -L [local_addr:]local_port:dest_host:dest_port user@gateway
Traffic to localhost:local_port on your machine is forwarded through gateway to dest_host:dest_port (as seen from gateway).
# Access a remote MySQL (port 3306) locally on port 3307 ssh -L 3307:localhost:3306 user@dbserver mysql -h 127.0.0.1 -P 3307 -u root -p # Access an internal service through a bastion ssh -L 8080:internal-app.private:80 user@bastion # Bind to a specific local address (share with LAN) ssh -L 0.0.0.0:8080:internal:80 user@bastion # Background tunnel (no shell) ssh -fNL 5432:db.internal:5432 user@bastion
Remote Port Forwarding (-R)
ssh -R [remote_addr:]remote_port:dest_host:dest_port user@gateway
Traffic arriving at remote_port on gateway is forwarded back to dest_host:dest_port on your side.
# Expose local dev server (port 3000) on remote port 8080 ssh -R 8080:localhost:3000 user@public-server # Let others on the remote server reach your local port # (requires GatewayPorts yes in /etc/ssh/sshd_config on the server) ssh -R 0.0.0.0:8080:localhost:3000 user@public-server # Background ssh -fNR 9000:localhost:9000 user@public-server
Dynamic (SOCKS5) Proxy (-D)
ssh -D [bind_addr:]local_port user@gateway
Opens a SOCKS5 proxy on local_port. Configure your browser/app to use 127.0.0.1:PORT as SOCKS5 proxy.
# SOCKS5 proxy on localhost:1080 ssh -D 1080 user@gateway # Background ssh -fND 1080 user@gateway # Test: curl through the proxy curl --socks5 127.0.0.1:1080 https://example.com
Flags for Tunnel-Only Connections
| Flag | Effect |
|---|---|
-N | Don't run a remote command (no shell) |
-f | Fork to background after authenticating |
-q | Quiet — suppress banners |
# Canonical background tunnel invocation ssh -fNq -L 5432:db:5432 user@bastion
Config File Tunnels
Persistent tunnels belong in ~/.ssh/config, but OpenSSH doesn't auto-restart them. Use autossh for that.
Host db-tunnel
HostName bastion.example.com
User ubuntu
LocalForward 5432 db.internal:5432
LocalForward 6379 redis.internal:6379
ServerAliveInterval 30
ExitOnForwardFailure yesssh -fNq db-tunnel
autossh — Auto-Restart Tunnels
# Install brew install autossh # macOS apt install autossh # Debian/Ubuntu # Persistent local forward autossh -M 0 -fNq -L 5432:db:5432 user@bastion
-M 0 disables the monitoring port (use ServerAliveInterval instead).
Checking Active Tunnels
# List listening ports ss -tlnp | grep ssh # Linux lsof -iTCP -sTCP:LISTEN | grep ssh # macOS # Close a named tunnel via control socket ssh -S ~/.ssh/cm-user@bastion -O cancel -L 5432:db:5432 user@bastion
X11 Forwarding
Forwards a remote GUI application to your local display.
ssh -X user@host xclock # basic (untrusted) ssh -Y user@host xclock # trusted (needed for some apps)
Server must have X11Forwarding yes in /etc/ssh/sshd_config.