SSH Port Forwarding / Tunneling
Krishna Chaitanya Bandi
Automation & AI Solutions Architect | Streamlining IT Operations & Business Processes | Passionate about Python, Open-Source and Machine Learning ??
SSH has a lot of tricks up its sleeve. In this 4-Part series, I will share some of the popular use-cases for SSH, beyond its well known use in secure terminal access on remote servers.
SSH Fundamentals - It's core and known purpose
SSH, fundamentally, is a tunnel between a Source and Destination.
Source ?? The place from which you execute ssh command
Destination ?? The place where the tunnel is aimed at
Below is a simple example with a Source and Destination. We will use this example through out this article.
After you establish the tunnel between Source and Destination, you will have a bi-directional tunnel between them.
There are a few options you can pass to SSH daemon that lets you send different types of traffic through that SSH tunnel, and not just limit to terminal commands and stuff.
Once SSH tunnel is established, its bi-directional encrypted and secure channel. You can put whatever you want on one side and get it on the other side.
Three Types of SSH Tunneling
In this article, lets go through all of them using plain and simple english.
Keep this one point in mind while you read this article. SSH tunnel is always initiated by your laptop (in this example).
Which means, the SSH user@remote-server command is run from the local laptop.
Local Port Forwarding
Assume that your remote-server is running some web service on port 8080 locally. Since it is not tied to any external interface, you cannot access it.
If you can SSH into 10.10.10.10 (remote-server), then you are already in. You poked a hole into the server - although this hole is tied to port 22 (SSH Server)
How to communicate to localhost:8080 on the remote server through the SSH connection initiated from your laptop?
Instead of just ssh user@remote-server, you use the following command
ssh -L 9000:127.0.0.1:8080 user@remote-server
Remember you are initiating SSH connection from your local laptop. So, the flag -L applies to your local laptop.
9000 tells your SSH client (on your local laptop) to bind port 9000 to the SSH tunnel. Which means, whetever you throw into the port 9000 on your laptop, will be taken across the SSH tunnel.
And where is this 9000 port traffic taken to? Thats also in the SSH command above. Its given to 127.0.0.1:8080 on the remote-server.
Lets explore this with another example
Lets say there is another server that is connected to the remote-server which is running something on port 8080 (like below).
ssh -L 9000:172.16.10.10:8080 user@remote-server
The logic is still the same. Now, when you are opening the SSH connection, you are telling SSH to deliver traffic from 9000 to 172.16.10.10:8080 on the remote-server.
Since your remote-server knows how to reach 172.16.10.10:8080, its okay.
Remote Port Forwarding
Now lets flip the requirement. Lets say you are running a local web-server on your laptop. This server is not exposed to outside world. Only your laptop can reach it internally, as it is running at localhost:80
领英推荐
Remember, even in this scenario, the SSH connection is initiated from your local laptop.
ssh -R 5000:127.0.0.1:80 user@remote-server
But now, as part of opening that connection, you are asking the SSH server of the remote-server to open port 5000.
Yes, from your local laptop, you are asking remote-server to open port 5000 for you. Let that sink in. This is the critical part.
Okay, remote server opened this port 5000 for you. What to do with this port 5000? Thats also in the SSH command above. You want to forward all the traffic that hits port 5000 on the remote-server to 127.0.0.1:80 on your local laptop.
Wait a second!!! Where am I giving the IP of local laptop in the above command? How does the remote-server know how to talk to the local-laptop in the first place?
Think about it. Your remote-server already has an established SSH connection with local-laptop. So, all it does is ?? put all the traffic that hits port 5000 ?? into the SSH tunnel with local-laptop.
When the traffic pops out on the local laptop, it will be forwarded to 127.0.0.1:80.
Lets explore this with another example
Similar to the example in Local Forwarding, imagine a scenario below
Here, too the logic is same as before.
Remember, SSH connection is still initiated from the local laptop. But now, you want the remote server to open the port 5000 and forward the traffic that hits 5000 towards 192.16.1.1:80 at the local-laptop.
ssh -R 5000:192.16.1.1:80 user@remote-server
Dynamic Tunneling (Socks Proxy)
Sometimes, you are not looking to put specific traffic into the SSH tunnel. You want to put all sorts of traffic into the tunnel and just carry it to the other side and execute it.
Remember, that you are initiating the SSH connection from your laptop only.
ssh -D 7777 user@remote-server
After you establish the SSH connection, your local laptop will also start listening on port 7777.
"-D" refers to dynamic here.
Unlike local port forwarding, you are not planning to forwarding traffic to a specific port or host on the remote-server.
In Dynamic Tunneling, you send everything into port 7777.
What do you mean everything? How can I put traffic on that port?
Good question.
Dynamic tunneling is generally used with Web Browsers. Firefox supports it through SOCKS v4/v5. Google Chrome does not support it. Most people use it with FireFox.
Refer to the below link to understand how to setup SOCKS proxy in the browser.
While you setup SOCKS proxy, you will use the port 7777 (in this example), and tell the browser to send everything from the browser to that port 7777.
And then SSH will send all that traffic to the remote-server. And remote-server will execute that traffic.
In the browser, every query you make is a HTTP action. These actions are transmitted "as-is" to the other side of the tunnel ?? get executed ?? results are transported back.
Above diagram shows the flow of traffic from browser, to the SOCKS port, to the SSH tunnel and then to remote-server.
Remote server executes the GET google.com and then sends the data back to the source (local-laptop) through the same tunnel / port / SOCKS / browser.
Upcoming Posts
This is part-1. In upcoming part-2,3 and 4, I will share some more interesting secrets of SSH. If you want me to cover a specific part of SSH, let me know.