Local vs Remote SSH port forwarding
When it comes to the art of SSH tunnelling, there are basically two options where to relay a port to.
You can relay a port from a remote server to your local machine with ssh -L
, hence called local port forwarding. A very basic use-case is if your remote server has a MySQL database daemon listening on port 3306
and you want to access this daemon from your local computer.
The second option is to make your local port available on a remote server (ssh -R
). Remote port forwarding might come in handy if you for example want to make your local web-server available on a port of a public server, so that someone can quickly check what your local web-server provides without having to deploy it somewhere publicly.
It should now be pretty easy to remember: Local and remote port forwarding always refers to where to relay the port to. The SSH command syntax uses the same easy to remember abbreviations: -L
(forward to my local machine) and -R
(forward to my remote machine).
- Local vs Remote
- Tunnel options
- AutoSSH
- SSH Config
TL;DR
Remote MySQL server (remote port 3306) to local machine on local port 5000:
ssh -L 5000:localhost:3306 cytopia@everythingcli.org
Local web-server (local port 80) to remote server on remote port 5000:
ssh -R 5000:localhost:80 cytopia@everythingcli.org
Local port forwarding
(Make a remote port available locally).
In this example we are going to make a remote MySQL Server (Port 3306) available on our local computer on port 5000.
Let’s start with the general syntax of local port forwarding:
ssh -L <LocalPort>:<RemoteHost>:<RemotePort> sshUser@remoteServer
Argument | Explanation |
---|---|
LocalPort |
The port on your local machine where the whole thing should be reachable. |
RemoteHost |
This specifies on which interface inside the remote server (remoteServer ) the daemon is listening on. This can be either 127.0.0.1 , localhost , a specific IP address or even 0.0.0.0 which refers to all interfaces. If you are unsure, simply ssh into the remote machine and check all interfaces for port 3306 by issuing:netstat -an | grep 3306 | grep LISTEN . |
RemotePort |
This is the actual port on the remote machine (remoteServer ) you want to relay to your local machine. In our case (MySQL listens on 3306 by default) it is simply 3306 |
sshUser |
This is the SSH username you have on the remote server |
remoteServer |
The address (IP or hostname) by which your remote server is reachable via ssh |
Now let’s simply forward our remote MySQL server to our local machine on port 5000
.
ssh -L 5000:localhost:3306 cytopia@everythingcli.org
That’s all the magic! You can now simply reach the remote database from your local machine with mysql --host=127.0.0.1 --port=5000
or any other client.
But wait… which local address does it listen on?
Yes, you are right! The complete syntax is:
ssh -L [<LocalAddress>]:<LocalPort>:<RemoteHost>:<RemotePort> sshUser@remoteServer
Argument | Explanation |
---|---|
LocalAddress |
The local address is an optional parameter. If you do not specify it, the remote port will be bound locally to all interfaces (0.0.0.0 ). So you can also only bind it locally to your 127.0.0.1 (on your local machine). |
This is the full example:
ssh -L 127.0.0.1:5000:localhost:3306 cytopia@everythingcli.org
Remote port forwarding
(Make a local port available remotely).
In this example we are going to make our local web-server (Port 80) available on a remote server on Port 5000.
Let’s start with the general syntax of remote port forwarding:
ssh -R <RemotePort>:<LocalHost>:<LocalPort> sshUser@remoteServer
Argument | Explanation |
---|---|
RemotePort |
The port on your remote server (remoteServer ) where the whole thing should be reachable. |
LocalHost |
This specifies on which interface inside your local computer the daemon is listening on. This can be either 127.0.0.1 , localhost , a specific IP address or even 0.0.0.0 which refers to all interfaces. If you are unsure, simply check all interfaces (on your local machine) for port 80 by issuing:netstat -an | grep 80 | grep LISTEN . |
LocalPort |
This is the actual port on your local machine you want to relay to the remote server (remoteServer ). In our case (The web-server listens on 80 by default) it is simply 80 |
sshUser |
This is the SSH username you have on the remote server |
remoteServer |
The address (IP or hostname) by which your remote server is reachable via ssh |
Now let’s simply forward our local web-server to our remote machine on port 5000
.
ssh -R 5000:localhost:80 cytopia@everythingcli.org
That’s all the magic! You can now simply reach your local webserver via http://everythingcli.org:5000.
But wait… which remote address does it listen on?
Yes, you are right! The complete syntax is:
ssh -R [<RemoteAddress>]:<RemotePort>:<LocalHost>:<LocalPort> sshUser@remoteServer
Argument | Explanation |
---|---|
RemoteAddress |
The remote address is an optional parameter. If you do not specify it, the remote port will be bound remotely (on remoteServer ) to all interfaces (0.0.0.0 ). So you can also only bind it remotely to a specific interface. |
This is the full example:
Assuming the IP address of everythingcli.org is 109.239.48.64 and you only want to bind it to this IP.
ssh -R 109.239.48.64:5000:localhost:80 cytopia@everythingcli.org
But wait… it doesn’t work
By default, the listening socket on the server will be bound to the loopback interface only. This may be overridden by specifying RemoteAddress
. Specifying a RemoteAddress
will only succeed if the server’s GatewayPorts option is enabled (on the remote server):
$ vim /etc/ssh/sshd_config
GatewayPorts yes
Some more details
Ports below 1024
Every system user can allocate ports above and including 1024 (high ports). Ports below that require root privileges.
So If you want to relay any port to a port to for example 10, you must do that like so:
As you allocate a low port on your local machine, you must either do that as root (locally) or with sudo (locally):
sudo ssh -L 10:localhost:3306 cytopia@everythingcli.org
As you allocate a low port on the remote server, you will need to ssh into the machine as root:
ssh -R 10:localhost:80 root@everythingcli.org
_
Pingback: Links 10/1/2016: Linux Mint 17.3 “Rosa” Xfce and KDE Released | Techrights
Pingback: Local and remote (SSH) port forwarding | 0ddn1x: tricks with *nix
Pingback: SSH tunnelling for fun and profit: Tunnel options
Pingback: SSH tunnelling for fun and profit: Autossh
Pingback: SSH tunnelling for fun and profit: SSH Config
Pingback: SSH Basics and the SSH Config File – Richard Skumat's Blog
Pingback: Oku – Hesap, Kitap ve Hayat
Pingback: Creating a local socks proxy for Firefox – Richard Skumat's Website
Pingback: pwncat - Netcat on Steroids with Firewall, IDS/IPS Evasion, Bind and Reverse Shell, Self-Injecting Shell and Port Forwarding Magic — SkyNet Tools