What Is an SSH Tunnel? A Port Forwarding Guide
What is an SSH tunnel and how do you set one up? Local, remote and dynamic port forwarding, secure database and panel access, ~/.ssh/config and autossh.

Contents
An SSH tunnel is a method that lets you securely reach another port or server by passing a connection through an encrypted SSH connection. You can use services such as a database, an admin panel or a monitoring tool without ever exposing them to the internet, using only your SSH access. You don't need to install any extra software; every server you can connect to over SSH is also ready for tunneling.
This guide covers local, remote and dynamic port forwarding, common scenarios, persistent tunnels and security settings. You can find the basics of SSH in our What is SSH? article.
Three types of SSH tunnel
| Type | Parameter | What does it do? |
|---|---|---|
| Local forwarding | -L | Connects a port on your own computer to a service on the server side |
| Remote forwarding | -R | Connects a port on the server to a service on your own computer |
| Dynamic forwarding | -D | Opens a SOCKS proxy on your computer; routes traffic through the server |
The most commonly used is local forwarding.
Local forwarding (-L)
It's used to reach a service on your server that only listens on 127.0.0.1 from your own computer. The syntax:
ssh -L [local_port]:[target_host]:[target_port] user@server
Example: Secure access to a database. MariaDB on the server only listens on 127.0.0.1:3306, and port 3306 is closed to the internet:
ssh -L 3307:127.0.0.1:3306 user@203.0.113.10
While this connection is open, you connect to 127.0.0.1:3307 on your own computer with HeidiSQL, DBeaver or another tool; the connection is forwarded, encrypted, to the database on the server. We cover database settings in our How to install MariaDB and How to install PostgreSQL guides.
Example: Access to a web interface. To open a monitoring panel that runs on port 19999 on the server, and that you don't want to expose, in your own browser:
ssh -L 19999:127.0.0.1:19999 user@203.0.113.10
Then open http://127.0.0.1:19999 in your browser.
Reaching another server behind it: The target address doesn't have to be the server itself. You can also tunnel to another machine your server reaches over a private network:
ssh -L 5433:10.8.0.20:5432 user@203.0.113.10
Remote forwarding (-R)
It works in the opposite direction: it connects a port on the server to a service on your own computer. For example, to temporarily show an application you're developing on port 3000 on your own computer through port 8080 on the server:
ssh -R 8080:127.0.0.1:3000 user@203.0.113.10
By default, the remote port only opens on the server's 127.0.0.1 address. For it to be reachable from outside, the GatewayPorts setting in the server's sshd_config file has to be changed; do this only if you know what you're doing, and only temporarily.
Dynamic forwarding (-D): SOCKS proxy
ssh -D 1080 user@203.0.113.10
This command opens a SOCKS proxy at 127.0.0.1:1080 on your own computer. When you enter this address in your browser's proxy settings, your browser traffic goes out to the internet through your server, encrypted. It's useful on untrusted Wi-Fi networks or for services that only allow access from your server's IP address. Traffic leaving your server is your responsibility; for heavy and continuous use, check your provider's usage rules.
Useful parameters
| Parameter | What does it do? |
|---|---|
-N | Doesn't run a remote command; only opens the tunnel |
-f | Goes to the background once the connection is established |
-v | Gives verbose output; used to find connection problems |
-p 2222 | Specifies the port if SSH runs on a different port |
For a connection that runs in the background and only opens a tunnel:
ssh -f -N -L 3307:127.0.0.1:3306 user@203.0.113.10
Persistent tunnels with ~/.ssh/config
Instead of typing long commands every time, save the tunnels you use often in the ~/.ssh/config file on your own computer:
Host db-tunnel
HostName 203.0.113.10
User user
IdentityFile ~/.ssh/id_ed25519
LocalForward 3307 127.0.0.1:3306
LocalForward 19999 127.0.0.1:19999
ServerAliveInterval 30
Now a single command opens both tunnels:
ssh -N db-tunnel
ServerAliveInterval stops an idle connection from being closed by a router or firewall.
Always-on tunnels: If one server needs to stay connected to another through a permanent tunnel, you can run the autossh tool, which reconnects automatically when the connection drops, as a systemd service. To connect several servers to each other permanently, a VPN such as WireGuard is usually a tidier solution.
Security
- Use key-based login. Tunnels are only as secure as your SSH access. Turn off password login and log in only with a key; the steps are in our What is SSH? article.
- Use the local address. Leave tunnels on
127.0.0.1, as they are by default; that way, other devices on the same network can't use your tunnel. - Turn off unnecessary forwarding. You can turn off forwarding on the server for users who don't use tunnels. In the
sshd_configfile, for a specific user or group:Match User sftp-only AllowTcpForwarding no - Don't expose services. The real benefit of a tunnel is never exposing services such as databases and panels to the internet at all. Make sure these services only listen on
127.0.0.1; we cover port security in our What is a port? article.
Nodesty servers for SSH tunnels
With Nodesty AMD Ryzen 9 9950X VPS and AMD EPYC 7763 VPS plans, you get root access to your Linux server over SSH; you can use your databases, admin panels and monitoring tools securely through SSH tunnels without exposing them to the internet. If your SSH access is cut off, you can always reach your server through the web console in your panel.
Frequently Asked Questions
Can an SSH tunnel replace a VPN?
For secure access to a specific service it's usually enough, and it needs no extra setup. For needs such as routing all of your device's traffic through the server, or permanent access to several services and devices, a real VPN such as WireGuard is a better fit.
I set up a tunnel but can't connect. Why?
The most common reasons are that the local port is already used by another application, the target address is mistyped, or the AllowTcpForwarding option is turned off in the server's SSH settings. Add -v to the ssh command to get verbose output and see at which step the error happens.
Can I set up an SSH tunnel on Windows?
Yes. The OpenSSH client that comes built into current Windows versions runs the ssh commands in this guide as they are. If you use PuTTY, you can define local and dynamic tunnels under Connection → SSH → Tunnels. Tools such as HeidiSQL and DBeaver also have a built-in SSH tunnel option in their settings.
Can other people use my tunnel while it's open?
Not by default. Local tunnels only listen on your own computer's 127.0.0.1 address; other devices on the same network can't reach them. To open the tunnel to other devices you have to specify the bind address explicitly, which isn't recommended in most cases.
My tunnel keeps dropping. What should I do?
Idle connections can be closed by routers and firewalls. Keep the connection alive by adding the line ServerAliveInterval 30 to your ~/.ssh/config file. For tunnels that need to stay open permanently, use the autossh tool, which reconnects automatically when the connection drops.
Can I browse the internet from my server's IP address with a SOCKS proxy?
Yes, with a dynamic tunnel you can route your browser's traffic through your server. This is useful on untrusted networks and for services that require access from a fixed IP address. All traffic leaving your server is your responsibility; follow your provider's usage rules.
About the author
Nodesty Team · Infrastructure & Support
The Nodesty team runs our servers, network and DDoS protection day to day and answers customer support requests around the clock. These guides come from that work.
Related articles

How to Use UFW: An Ubuntu Firewall Guide
How to use UFW on Ubuntu: enabling the firewall safely, port and IP rules, deleting rules, application profiles, rate limiting, IPv6 and Docker.

HTTP Security Headers: HSTS, CSP and More
What are HTTP security headers? HSTS, Content-Security-Policy, X-Content-Type-Options, Referrer-Policy, adding them with Nginx and .htaccess, and testing.

Website Hacked? What to Do, Step by Step
Website hacked? What to do: the signs, first response, passwords, finding malicious files, restoring a clean backup, WordPress cleanup and prevention.