SSH Tunneling
When you need to access a server/client behind a firewall that doesn’t allow port forwarding you can use SSH tunneling to bypass that if an SSH server is running. Pivoting is a sneaky technique that hackers use to access computers, servers, and services behind firewalls. These examples will use OpenSSH. I think most examples don’t explain this well and I’m hoping that this makes it clear.
SSH Commands
-D: [bind_address:]port
-f: runs the SSH client in the background.
-g: use gateway ports
-N: disables a shell prompt after connecting.
-R: reverse option.
-T: disabled pseudo-TTY.
Terms
Jump Server: There’s really nothing special about this other than this is the server that we will be passing through using SSH tunneling.
Local Port Forwarding
Local port forwarding can allow you to access services behind a firewall. For example, if you want to access a website that is not being served in the DMZ local port forwarding will allow you to access that remotely.
This can be tried out on VulnHub: Symfonos 2. This VulnHub has a LibreNMS running on port 8080 behind the firewall.
Website Hosted on Port 8080 Behind Firewall
1 |
ssh -Ngf -L 8080:127.0.0.1:8080 aeolus@192.168.0.18 |
This will forward port 8080 on my local machine (Parrot OS) and allow me to browse the website that is behind the firewall on port 8080 on server 192.168.0.18.

Reverse Port Forwarding
Imagine I want to remotely access my home computer that sits behind a firewall. Instead of enabling ports through the router/firewall an alternative would be to use a jump server (Digital Ocean Droplet) and create a reverse port forwarding through SSH tunneling. This also works with VPNs that don’t allow port forwarding.
To start with I will use a Digital Ocean server as a jump server. Then I will use a Virtual Machine running Parrot OS 4.7 to connect to that jump server to access my home machine (Windows 10). Since my Parrot OS VM will be getting it’s IP from my router this will simulate a real-life example.
Demo: In this example, I will host a website on port 8000 on my laptop and view that website on my Parrot OS VM through a jump server on Digital Ocean. I am using a standard Ubuntu droplet with no modifications.
ssh -R remote_port:local_address:local_port [email protected]
Digital Ocean Droplet’s (Jump Server) IP: 64.225.22.61
On my local machine (laptop), I will connect to the jump server and create a reverse port forwarding tunnel.
1 |
ssh -R 8080:127.0.0.1:8000 root@64.225.22.61 |

On my Parrot OS virtual machine, I will connect to the Digital Ocean jump server using SSH.
1 2 3 4 5 6 |
ssh root@64.225.22.61 # once connected to the jump server I will connect to my local machine through the reverse tunnel curl 127.0.0.1:8080 # this should return the html from the website running on my laptop. |

Exposing it Out with GatewayPorts
At this point, I’m not able to access the website through a browser on my Parrot OS VM.
On the Digital Ocean jump server, you will need to allow port 8080 through the firewall and adjust the SSH configuration.
1 2 |
# allow port 8080 through firewall sudo ufw allow 8080 |
GatewayPorts – This is a configuration in SSH that needs to be enabled for ports to be exposed externally. This is located in the file /etc/ssh/sshd_config.conf

1 2 |
# restart ssh daemon sudo systemctl restart sshd |
On my Windows 10 laptop, I will need to need to restart the SSH tunnel.
1 2 |
# windows 10 home laptop ssh -R 8080:127.0.0.1:8000 root@64.225.22.61 |

SOCKS Proxy
I can create a SOCKS proxy on port 1080 by running a command like below. I tried this out on a Digital Ocean server and it worked really well. I was able to run nmap with proxychains to scan internal ports.
1 |
ssh -D 1080 root@129.168.0.18 |
To do this make sure you only have this line in your /etc/proxychains.conf file.
1 |
socks4 127.0.0.1 1080 |
then you can run nmap against the internal web server by passing it through proxychains. This works better than using the —proxy attribute in nmap.
1 |
proxychains nmap 127.0.0.1 |
Setting up an SSH Server in Parrot OS / Kali
You may find yourself in a situation where you have a reverse shell and need to forward ports to access an internal MySQL database because the MySQL client is not installed. I used this technique on Kioptrix #3.
Installing the SSH service
1 2 3 4 5 6 |
# installing latest ssh server sudo apt update sudo apt install openssh-server # allow through firewall (or specify port if not using default 22) sudo ufw allow ssh |
1 2 3 4 5 6 7 8 9 10 11 |
# check status of ssh server sudo systemctl status ssh # start sshd sudo systemctl start ssh # disable during boot sudo systemctl disable ssh # enable sshd service sudo systemctl enable ssh |
Reverse Port Forward the MySQL Service
I created a user in Parrot OS / Kali and in the reverse shell I was able to tunnel out the MySQL port, and at that point, I could access the internal MySQL server using the credentials I found.
1 2 |
ssh -R 3306:127.0.0.1:3306 sshbot@192.168.0.37 |