SSH Port Forwarding
SSH port forwarding (tunneling) is a critical technique for DevOps engineers to securely access internal services, databases, and applications across cloud and hybrid environments (AWS, Azure, GCP). This guide covers local, remote, and dynamic forwarding with actionable examples and best practices.
1. Local Port Forwarding
Forward a local port to a remote service through an SSH server. Useful for accessing internal databases, web UIs, or APIs from your workstation.
Syntax:
ssh -L <local_port>:<destination_host>:<remote_port> <user>@<ssh_server>Example 1: Forward local port 5050 to remote 4040 via a bastion
ssh -L 5050:188.171.10.8:4040 user@bastion.hostExample 2: Access a private PostgreSQL database
ssh -L 5432:db1.host:5432 user@remote.host
# Connect locally: psql -h 127.0.0.1 -p 5432Example 3: Forward VNC port and run SSH in background
ssh -L 5901:127.0.0.1:5901 -N -f user@remote.host-N: Do not execute remote command-f: Run SSH in background
Troubleshooting:
Ensure
AllowTcpForwarding yesis set in/etc/ssh/sshd_configon the remote server.
2. Remote Port Forwarding
Expose a local service to a remote network via the SSH server. Useful for sharing local apps or webhooks with remote/cloud systems.
Syntax:
ssh -R <remote_port>:localhost:<local_port> <user>@<remote.host>Example: Expose local port 3000 to remote port 8000
ssh -R 8000:127.0.0.1:3000 -N -f user@remote.hostNow, anyone on
remote.hostcan access your local app atlocalhost:8000.
3. Dynamic Port Forwarding (SOCKS Proxy)
Create a local SOCKS proxy to route traffic through the SSH server. Useful for secure browsing, testing, or accessing internal networks.
Syntax:
ssh -D <local_port> <user>@<ssh_server>Example: Start a SOCKS proxy on port 9090
ssh -D 9090 -N -f user@remote.hostConfigure your browser or CLI tool to use
localhost:9090as a SOCKS5 proxy.
Real-World DevOps Examples
1. Access AWS RDS or Azure SQL via Bastion
ssh -L 5432:<rds-endpoint>:5432 ec2-user@bastion-host2. Forward Kubernetes Dashboard securely
ssh -L 8001:localhost:8001 user@k8s-master
kubectl proxy --address='127.0.0.1' --port=80013. Share a local web app with a remote team
ssh -R 8080:localhost:3000 user@remote.hostBest Practices
Use
-N -ffor background tunnels in automation scriptsAlways restrict forwarding to trusted users/networks
Monitor and audit SSH tunnels in production
Use SSH config (
~/.ssh/config) to simplify complex tunnelsFor persistent tunnels, consider tools like
autosshor systemd services
References
Tip: Kill background SSH tunnels with
pkill -f 'ssh -L'orpkill sshas needed.
Last updated