SSH is a very common and widely utilized protocol to securely interact with machines. Many developers and those with technical duties in the wide landscape of software engineering and information technology swear by it every day. However, most SSH users just utilize this protocol to interact with the server via the command line. SSH however is capable of a lot more. This blog will be a humble attempt to explain one such technique called SSH Port Forwarding or SSH Tunnelling.
So, what is it ? Port-Forwarding or Tunnelling ?
First let’s understand the difference between port forwarding and tunnelling.
What is port-forwarding?
Port Forwarding, also known as “port-based forwarding” or “port mapping”, maps an IP address and TCP port to another IP address and another TCP port.
What is tunnelling?
Tunnelling is encapsulating and wrapping packets in layers of headers to form a tunnel. A packet like this will have a header that will indicate the packet’s destination and the protocol it uses. The other part of the packet will contain the actual payload/content. It can be understood as a packet within a packet.
Now, that we know both of them, which one is it ?
Types of SSH port-forwarding?
- Local Port Forwarding
- Remote Port Forwarding
- Dynamic Port Forwarding
Local Port Forwarding
Local port forwarding is useful when you want to use a service that’s local to another system. Though it’s not necessary for the service to be local, in most cases it’s used for that i.e when a direct connection is not possible. This allows us to run services locally and not expose them to the internet while still being able to access it like a regular service.
You can do local port-forwarding by following the syntax below: –
1ssh -L 8080:localhost:8384 [email protected]
Here we have opened our port
8080 and any traffic for port
8080 will be redirected to myinstance’s localhost and port 8384.
You can also open multiple ports in a single command like the following
1ssh -L 8080:localhost:8384 9090:localhost:9494 [email protected]
You can also bind to a particular network interface if its required. Here is how you can achieve it
1ssh -L 192.168.0.200:8080:localhost:8384 [email protected]
This would then bind port
8080 on IP address
192.168.0.200 and will make service of myinstance available on that IP and port.
Remote Port Forwarding
Remote Port Forwarding is useful when you want to expose a service running on your local system to the internet. This could be useful when we are behind a NAT service for instance and want to expose a service that otherwise would be very difficult to manage. To achieve this, we can use the following command –
1ssh -R 8080:localhost:8000 [email protected]
If we have a local service running on port
8000 then we can use the above command and it will open port
8080 on myinstance. Once a user visits port
8080 on myinstance it will forward the traffic back to our local machine on port
A very important configuration parameter to look for when working with Remote Port Forwarding is to check
Here are the possible alternatives to look for in the
sshd_config which is usually found in the
GatewayPortsis set to
no, it would prevent connecting to forwarded ports from any computer outside of the server from connecting to it.
GatewayPortsis set to
yes, it would allow connecting to forwarded ports from any computer outside of the server.
GatewayPortsis set to
clientspecified, only connections from the specified address will be allowed, which would look like below
1ssh -R 220.127.116.11:8080:localhost:8000 [email protected]
Dynamic Port Forwarding
Dynamic Port Forwarding turns an SSH client into a SOCKS proxy server. With the help of system tools like proxychains and modifying our proxy settings in the browser settings we can interact with those services.
It can be done by the following command:
1ssh -D 8080 [email protected]
The above command will open the SOCKS port on
8080 and for applications configured with proxy settings all traffic will pass through myinstance.
Suggested Read : Intercepting Request Which Requires VPN + SOCKS Proxy
Let’s solidify above concepts using real life examples.
Problem: You have a service running in a docker container (
172.20.0.3) on port 8888 on the server (
192.168.0.111). The docker container is not configured to use host networking. You want to interact with that service on your local machine. You also have SSH access to the machine.
We can use SSH Local Port Forwarding in this case which would mean we will tunnel the service running on the server to a port on our local machine. It could be achieved with the following command:
1ssh -L 8080:172.20.0.3:8888 [email protected]
In case you want to bind the service only to a particular network device on your device below command can be utilized.
1ssh -L 192.168.0.222:8080:172.20.0.3:8888 [email protected]
192.168.0.222 is our Local IP address and
172.20.0.3 is IP address of the docker container on the server host.
Problem: We have a service running locally on our system on port
8888. We need to host it on the server for some time to discuss design changes with our colleagues.
With the help of SSH Remote Port Forwarding we can use the below command:
1ssh -R 8080:localhost:8888 [email protected]
Now, the local service running on our local machine’s port
8888 will be able on port
8080 on the server.
Note: For this to work it’s imperative that GatewayPorts is yes in
/etc/ssh/sshd_config file. If not, you will have to make necessary changes by using superuser permissions.
Problem Let’s say you are facing some problems with your Windows PC. A very tech-savvy friend of yours could have the answer to your problem. You don’t like installing third-party solutions on your host. So, how will you give your friend the ability to RDP login to the machine?
With the help of SSH Remote Port Forwarding, we can tunnel our RDP service on the server so our friend will be able to access our PC from the internet. We assume that you have allowed RDP connections to your host, if not you can follow this guide.
Issuing the following command on your Windows host will make RDP service accessible to users who can also access server
1ssh -R 3389:localhost:3389 [email protected]
Now our friend can use a service like Remmina to connect to the machine.
Note: Here it’s assumed that the user and user’s friend can access the server (192.168.0.170) but cannot access each other’s network.
Problem We have compromised a jump server (
10.10.10.123) and during our enumeration we discovered an entirely different subnet range of
172.16.1.1/24. Our objective is now to discover which services are running on the internal network and try to access those services. We also need to configure C2 to accept connection on the victim jump server.
With the help of dynamic port forwarding, we can access internal services by using the jump server as a proxy. To set this thing we can issue the following command:
1ssh -D 1080 [email protected] -i /path/to/my/ssh_key
This will open a SOCKS5 proxy on our localhost and we can then use utilities like proxychains to interact with remote services.
Note: A better alternative to this according to me is, sshuttle you can open an entire subnet range with the help of this utility, and it will work as if the internal network was reachable without a proxy. You can issue the following command to work with it.
1sshuttle -r [email protected] 172.16.1.1/24 --ssh-cmd 'ssh -i /path/to/my/sshkey'
To configure our C2 we can do a Remote Port Forward
1ssh -N -R 127.0.0.1:41000:172.16.1.23:41000 [email protected] -i /path/to/ssh/key
This will now listen for connections on port
41000 on the server
172.16.1.23 and accept connections from our implants and relaying everything back to us.
- This usually requires changes in C2 profile/settings to accommodate the changes.
-Nwill just hang the terminal when trying to SSH into machine and not execute enter a shell.
In conclusion, SSH is a far more capable utility then what its usually utilized for. These abilities are very useful in System Administration, Development and in Penetration Testing environments. A solid understanding of these techniques go hand-in-hand with most things in Information Technology.
Payatu is a research-powered, CERT-In empaneled cybersecurity consulting company specializing in security assessments of IoT product ecosystem, Web application & Network with a proven track record of securing applications and infrastructure for customers across 20+ countries.
Want to check the security posture of your organization? Browse through Payatu’s Service and get started with the most effective cybersecurity assessments.
Have any specific requirements in mind? Let us know about them here and someone from our team will get in touch with you.