SSH Tunnels: Configuration and Practical Use Cases
The Complete Guide to SSH Port Forwarding, SOCKS Proxies, and Secure Remote Access
In today's interconnected digital landscape, secure remote access is no longer optional — it's a fundamental requirement for developers, system administrators, and IT professionals managing servers, databases, and distributed applications. While Secure Shell (SSH) is already the gold standard for encrypted remote communication, its tunneling capabilities unlock an entirely different level of power and flexibility.
SSH tunneling allows you to securely forward network traffic between systems, bypass restrictive firewalls, access services on private networks, and even encrypt your entire internet connection — all through a single, encrypted SSH connection. Whether you're a developer needing to reach a blocked database, a sysadmin exposing a local app for remote testing, or a security-conscious user browsing over public Wi-Fi, SSH tunnels are one of the most versatile and underutilized tools in your arsenal.
This comprehensive guide covers everything you need to know: how SSH tunnels work, the three core forwarding methods, real-world use cases, configuration file shortcuts, and best practices for running stable, secure tunnels on a VPS Hosting environment.
What Is an SSH Tunnel?
An SSH tunnel is a mechanism for transmitting arbitrary network data over an encrypted SSH connection between two endpoints. Rather than exposing services directly to the internet — which introduces significant security risks — SSH tunneling wraps that traffic inside an encrypted channel, making it invisible to eavesdroppers, firewalls, and network-level attackers.
At its core, an SSH tunnel works by:
- Establishing an encrypted SSH connection between a client and a server
- Binding a local or remote port to that connection
- Forwarding all traffic sent to that port through the encrypted tunnel to its destination
SSH tunnels operate in three primary modes, each serving distinct use cases:
| Tunnel Type | Direction | Primary Use Case |
|---|---|---|
| Local Port Forwarding | Local → Remote | Access remote services from your local machine |
| Remote Port Forwarding | Remote → Local | Expose local services to a remote server |
| Dynamic Port Forwarding | Local → Any | Full SOCKS proxy for routing all traffic |
Let's explore each method in depth, with practical commands and real-world scenarios.
1. Local Port Forwarding (-L)
What Is Local Port Forwarding?
Local port forwarding is the most widely used form of SSH tunneling. It allows you to bind a port on your local machine and forward all traffic sent to that port through the SSH connection to a specified destination — typically a service running on the remote server or accessible from it.
Think of it as creating a secure, encrypted pipe from your laptop directly into a remote network, allowing you to interact with services as if you were physically present on that network.
How It Works
When you initiate a local SSH tunnel:
- Your SSH client opens a listening port on your local machine
- Any connection made to that local port is forwarded through the encrypted SSH session to the remote SSH server
- The remote SSH server then connects to the specified destination host and port
- Data flows bidirectionally through this encrypted channel
Syntax
ssh -L [local_port]:[destination_host]:[destination_port] [user]@[ssh_server]Real-World Example: Accessing a Firewall-Protected Remote Database
One of the most common scenarios: you need to connect to a PostgreSQL database running on a remote server, but the database port (5432) is blocked by a firewall for security reasons. Rather than opening that port to the public internet, you can tunnel through SSH.
ssh -L 5432:localhost:5432 user@remote-serverBreaking down this command:
-L 5432:localhost:5432 — Instructs SSH to listen on local port 5432 and forward traffic to localhost:5432 as seen from the remote server
user@remote-server — The SSH user and server you're connecting through
Once the tunnel is active, open your database client and connect to localhost:5432 — you're now securely communicating with the remote PostgreSQL instance through an encrypted channel.
Additional Local Forwarding Examples
Accessing a remote web application on a private port:
ssh -L 8080:localhost:80 user@remote-server
Now browse to http://localhost:8080 on your local machine to access the web server running on port 80 of the remote host.
Accessing an internal service not directly reachable:
ssh -L 8080:internal-service.local:80 user@remote-server
Here, internal-service.local is a host accessible from the remote server but not from your local machine. The SSH server acts as a relay, giving you access to services deep within a private network.
2. Remote Port Forwarding (-R)
What Is Remote Port Forwarding?
Remote port forwarding is essentially the reverse of local port forwarding. Instead of pulling a remote service to your local machine, you're pushing a local service out to a remote server. This is invaluable when you need to expose something running on your local machine — behind NAT, a corporate firewall, or a home router — to users on a remote server or the broader internet.
How It Works
Your SSH client connects to the remote SSH server
The remote server opens a listening port on its interface
Any connection made to that remote port is forwarded back through the SSH tunnel to your local machine
Your local machine handles the connection as if it came directly from a local client
Syntax
ssh -R [remote_port]:[local_host]:[local_port] [user]@[ssh_server]
Real-World Example: Sharing a Local Development Server
You're building a web application locally on port 3000 and want to demo it to a colleague or client without deploying it. Using remote port forwarding, you can make your local app accessible via the remote server's public IP.
ssh -R 8080:localhost:3000 user@remote-server
Breaking down this command:
-R 8080:localhost:3000 — Instructs the remote server to listen on port 8080 and forward incoming connections back to localhost:3000 on your local machine
user@remote-server — The remote SSH server acting as the relay
Now anyone with access to the remote server can visit http://remote-server:8080 and interact with your local development application in real time.
> Important Note: For remote port forwarding to bind on all interfaces (not just localhost on the remote server), you may need to enable GatewayPorts yes in the remote server's /etc/ssh/sshd_config file.
Additional Remote Forwarding Example
Exposing a local development server for team review:
ssh -R 4000:localhost:3000 user@remote-server
Colleagues accessing http://remote-server:4000 will be served your local app running on port 3000 — no deployment, no DNS changes, no firewall rules required.
3. Dynamic Port Forwarding (-D)
What Is Dynamic Port Forwarding?
Dynamic port forwarding transforms your SSH client into a fully functional SOCKS proxy server. Unlike local and remote forwarding — which tunnel traffic to a single predefined destination — dynamic forwarding allows you to route traffic to any destination through the SSH server. This makes it exceptionally powerful for encrypting all internet traffic, bypassing geo-restrictions, and securing connections on untrusted networks.
How It Works
Your SSH client opens a SOCKS proxy listener on a local port
Any application configured to use that SOCKS proxy sends its traffic through the SSH tunnel
The remote SSH server forwards that traffic to its final destination on your behalf
From the perspective of external servers, all traffic appears to originate from the SSH server's IP address
Syntax
ssh -D [local_socks_port] [user]@[ssh_server]
Real-World Example: Bypassing Network Restrictions on Public Wi-Fi
You're at a coffee shop or hotel, connected to a public Wi-Fi network with restricted or monitored traffic. By routing your browser through a dynamic SSH tunnel to your VPS Hosting server, all traffic becomes encrypted and unrestricted.
ssh -D 8080 user@remote-server
Breaking down this command:
-D 8080 — Opens a SOCKS5 proxy on your local machine at port 8080user@remote-server — The SSH server that will relay your trafficConfiguring your browser to use the SOCKS proxy:
- Firefox: Settings → Network Settings → Manual proxy configuration → SOCKS Host:
127.0.0.1, Port:8080, SOCKS v5 - Chrome (via command line):
google-chrome --proxy-server="socks5://127.0.0.1:8080"Once configured, all browser traffic is encrypted and routed through your SSH server — invisible to local network monitoring and firewall restrictions.
Additional Dynamic Forwarding Example
Routing all traffic through a secure SOCKS proxy on port 9090:
ssh -D 9090 user@ssh-serverConfigure any SOCKS5-compatible application — browsers, torrent clients, messaging apps — to use localhost:9090 as its proxy, and all traffic will be securely tunneled through your SSH server.
Keeping SSH Tunnels Alive: Essential Flags
By default, SSH tunnels can drop due to inactivity or network interruptions. Use these flags to create more stable, persistent tunnels:
ssh -L 5432:localhost:5432 -N -f -o ServerAliveInterval=60 -o ServerAliveCountMax=3 user@remote-server| Flag | Purpose |
|---|---|
-N | Do not execute a remote command — only forward ports |
-f | Run SSH in the background after authentication |
-o ServerAliveInterval=60 | Send a keepalive packet every 60 seconds |
-o ServerAliveCountMax=3 | Disconnect after 3 missed keepalive responses |
-C | Enable compression (useful for slow connections) |
Simplifying SSH Tunnels with the Configuration File
If you use SSH tunnels regularly, typing long commands every time becomes tedious and error-prone. The SSH configuration file (~/.ssh/config) lets you define named connection profiles with all forwarding settings pre-configured.
Creating the SSH Config File
Open or create ~/.ssh/config and add your tunnel configurations:
Host remote-db
HostName remote-server.example.com
User your-username
IdentityFile ~/.ssh/id_rsa
LocalForward 5432 localhost:5432
ServerAliveInterval 60
ServerAliveCountMax 3
Host dev-proxy
HostName ssh-server.example.com
User your-username
DynamicForward 9090
ServerAliveInterval 60
Host expose-local
HostName remote-server.example.com
User your-username
RemoteForward 8080 localhost:3000Using Your Configured Tunnels
With the config file in place, establishing a tunnel is as simple as:
# Connect to remote database via local port forwarding
ssh remote-db
# Start SOCKS proxy for secure browsing
ssh dev-proxy
# Expose local development server remotely
ssh expose-localNo more memorizing complex command strings — your tunnel configurations are saved and reusable.
Practical SSH Tunneling Use Cases
Use Case 1: Secure Access to a Remote Database
Your production database should never be exposed to the public internet. Use local port forwarding to access it securely through SSH:
ssh -L 5432:localhost:5432 -N -f user@remote-serverConnect your database client (pgAdmin, DBeaver, MySQL Workbench) to localhost:5432 — you're now securely connected to the remote database without exposing any ports publicly.
This approach works seamlessly on Dedicated Servers where you have full control over firewall rules and SSH configuration.
Use Case 2: Accessing Internal Services on a Private Network
Your remote server has access to internal services (monitoring dashboards, admin panels, internal APIs) that aren't publicly accessible. Reach them from your local machine:
ssh -L 8080:internal-monitoring:80 user@remote-serverBrowse to http://localhost:8080 to access the internal monitoring dashboard through the secure tunnel.
Use Case 3: Sharing a Local Development Environment
You're building a web app locally and need stakeholder feedback before deployment. Use remote port forwarding to share it instantly:
ssh -R 4000:localhost:3000 user@remote-serverShare the URL http://remote-server:4000 with your team — they can access your local development server in real time without any deployment overhead.
Use Case 4: Encrypted Browsing on Untrusted Networks
At a conference, airport, or hotel? Protect your traffic from snooping with a dynamic SOCKS proxy:
ssh -D 9090 -N -f user@your-vpsConfigure your browser to use localhost:9090 as a SOCKS5 proxy. All traffic is now encrypted and routed through your trusted server.
Use Case 5: Bypassing Corporate Firewall Restrictions
If your workplace blocks access to certain development tools, repositories, or services, dynamic port forwarding through an external SSH server can restore access:
ssh -D 8080 -N -f user@external-serverRoute your traffic through the SOCKS proxy to bypass restrictive corporate firewall rules.
SSH Tunneling Security Best Practices
SSH tunnels are powerful, but they must be configured carefully to avoid introducing new security risks:
1. Use SSH Key Authentication
Disable password authentication and use SSH key pairs for all tunnel connections:
# Generate a strong SSH key pair
ssh-keygen -t ed25519 -C "tunnel-key"
# Copy public key to remote server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote-serverThen disable password authentication in /etc/ssh/sshd_config:
PasswordAuthentication no
PubkeyAuthentication yes2. Restrict SSH Access by IP
In /etc/ssh/sshd_config, limit which IP addresses can establish SSH connections:
AllowUsers user@192.168.1.0/243. Use Non-Standard SSH Ports
Changing the default SSH port from 22 reduces automated brute-force attacks:
Port 22224. Limit Tunnel Permissions
If a user should only be able to create tunnels (not execute commands), restrict their shell access:
Match User tunnel-user
AllowTcpForwarding yes
X11Forwarding no
PermitTTY no
ForceCommand /bin/false5. Monitor Active Tunnels
Regularly audit active SSH connections and forwarded ports:
# List active SSH connections
ss -tnp | grep ssh
# Check who is connected
who
last6. Pair SSH Tunnels with SSL Certificates
For web-facing services exposed through SSH tunnels, always use SSL Certificates to add an additional layer of encryption and establish trust with end users.
Automating SSH Tunnels with systemd
For production environments where tunnels need to be persistent and automatically restart after failures, use systemd to manage them as services.
Creating a systemd Service for an SSH Tunnel
Create /etc/systemd/system/ssh-tunnel-db.service:
[Unit]
Description=SSH Tunnel to Remote Database
After=network.target
[Service]
User=your-username
ExecStart=/usr/bin/ssh -N -L 5432:localhost:5432
-o ServerAliveInterval=60
-o ServerAliveCountMax=3
-o ExitOnForwardFailure=yes
-i /home/your-username/.ssh/id_ed25519
user@remote-server
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable ssh-tunnel-db
sudo systemctl start ssh-tunnel-db
sudo systemctl status ssh-tunnel-dbYour SSH tunnel will now start automatically on boot and restart immediately if it drops.
SSH Tunneling on AlexHost Infrastructure
Running SSH tunnels on a reliable, high-performance server is critical for stability and security. AlexHost's infrastructure is purpose-built for exactly this kind of workload:
- NVMe SSD Storage — Ultra-low latency for tunnel connections and data forwarding
- Full Root Access — Complete control over SSH configuration, firewall rules, and system settings
- DDoS Protection — Your tunnel endpoints remain protected against volumetric attacks
- 99.9% Uptime SLA — Persistent tunnels stay connected without unexpected interruptions
- Privacy-Focused Jurisdiction — AlexHost operates under Moldova's privacy-friendly laws
Whether you need a lightweight VPS Hosting plan for personal tunneling, a VPS with cPanel for managed environments, or a Dedicated Servers solution for enterprise-grade tunnel infrastructure, AlexHost has the right plan for your needs.
For teams managing multiple services and domains, combining SSH tunnels with Domain Registration and Email Hosting on the same infrastructure simplifies your entire stack while keeping everything secure under one roof.
Troubleshooting Common SSH Tunnel Issues
Tunnel Drops Frequently
Cause: Network inactivity timeouts or NAT session expiry.
Fix: Add keepalive settings to your SSH config or command:
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=5 -L 5432:localhost:5432 user@remote-server"Bind: Address Already in Use" Error
Cause: The local port you're trying to bind is already occupied.
Fix: Find and kill the process using the port:
lsof -ti:5432 | xargs kill -9Or choose a different local port for your tunnel.
Remote Port Forwarding Only Binds to Localhost
Cause: Default SSH behavior restricts remote forwarding to 127.0.0.1 on the server.
Fix: Add GatewayPorts yes to /etc/ssh/sshd_config on the remote server and restart SSH:
sudo systemctl restart sshd"Connection Refused" When Connecting Through Tunnel
Cause: The destination service isn't running, or the port/hostname in your tunnel command is incorrect.
Fix: Verify the service is running on the remote host:
ssh user@remote-server "ss -tnlp | grep 5432"SSH Tunnel Fails to Start in Background (-f flag)
Cause: Authentication failure or incorrect host configuration.
Fix: Test the connection interactively first (without -f and -N), resolve any authentication issues, then add the background flags.
Summary: SSH Tunnel Types at a Glance
| Feature | Local (`-L`) | Remote (`-R`) | Dynamic (`-D`) |
|---|---|---|---|
| Direction | Local → Remote | Remote → Local | Local → Any |
| Use Case | Access remote services locally | Expose local services remotely | Full SOCKS proxy |
| Destination | Fixed host:port | Fixed host:port | Any destination |
| Proxy Type | TCP port forward | TCP port forward | SOCKS4/5 |
| Best For | Database access, internal tools | Dev sharing, NAT traversal | Secure browsing, bypassing restrictions |
Conclusion: Master SSH Tunneling for Secure, Flexible Remote Access
SSH tunneling is one of the most powerful and underappreciated features of the SSH protocol. With just a single command, you can:
- Securely access remote databases and internal services without exposing ports to the internet
- Share local development environments with remote colleagues instantly
- Encrypt all internet traffic through a trusted SOCKS proxy
- Bypass restrictive firewalls on corporate or public networks
- Build persistent, automated tunnel services using systemd
The key to reliable SSH tunneling is a stable, high-performance server to anchor your connections. AlexHost's VPS Hosting plans provide the full root access, NVMe performance, DDoS protection, and uptime guarantees that demanding tunnel workloads require — at competitive prices with privacy-first infrastructure.
Start implementing SSH tunnels today and transform the way you manage secure remote access across your entire infrastructure.
*Have questions about configuring SSH tunnels on AlexHost servers? Our technical support team is available 24/7 to help you get set up.*
