SSH port forwarding creates a secure tunnel between the client and server computers. As the connection is encrypted, SSH tunneling is useful for transmitting unencrypted (or non secure) protocols such as POP3, VNC, RDT, etc. SSH port forwarding also allows you to connect computers from two different networks that are not able to communicate with each other directly. In this article, we are going to see how we can use SSH tunnels to forward TCP and UDP packets.
This is going to be our network scenario for this article.
client computer will establish a SSH session to server
server01 and access services (TCP port 80 and UDP port 53) on server
We are also only going to talk about local port forwarding and not remote port forwarding. Local port forwarding lets you connect from your local computer to another server via the SSH server. Remote port forwarding is to connect the other way round – from a server to your computer or to another server via the SSH client.
Tools Required for SSH Port Forwarding
For the CLI based SSH client, we will be using the standard
ssh program – an OpenSSH based SSH client. This is found in all Linux distributions. If you are looking for a CLI based OpenSSH client on Windows, install a copy of Cygwin.
PuTTY will be used as the GUI based SSH client. This is optional and not really required.
SSH only allows TCP port forwarding. To relay UDP packets, we will be using
socat – a multipurpose relay (SOcket CAT). Under UNIX or Linux, install
socat by using the default package installation utility. On Ubuntu, you would need to do something like this:
$ sudo apt-get install socat
Perform a Google search if you are looking for a
socat binary for Windows.
SSH Port Forwarding for TCP
SSH supports forwarding of TCP ports by default, so this is going to be the easiest. We will tunnel port 80 (HTTP) on
server02 to port 8000 on the
On PuTTY, create a new session towards the server.
Next, navigate to Connection->SSH->Tunnels, enter “
8000” on the Source Port field and “
10.0.0.20:80” on the Destination field. Click on the ‘Add’ button and you will see “
L8000 10.0.0.20:80″ appear in the ‘Forwarded ports’ list.
Now save the PuTTY SSH session by navigating to the ‘Session’ category. Once the session is saved, login to the ssh server (
server01) by clicking the ‘Open’ button at the bottom. Login to the server by entering the login credentials when prompted. Port forwarding is now enabled.
To perform the same action from the CLI, execute the
ssh command in the following manner on the
client$ ssh -L 8000:10.0.0.20:80 user@server01
The above command tells the
ssh program to listen on TCP port 8000 on the
client computer and forward it to TCP port 80 on
The SSH tunnel is now established. To test the connection, use a HTTP client (
curl command or your browser) and point it to
http://127.0.0.1:8000. You should be able to get a response from the HTTP server running on
client$ curl http://127.0.0.1:8000
This type of port forwarding will not work for FTP sessions. To tunnel FTP sessions, read this article: SSH Port Forwarding for FTP
SSH Port Forwarding for UDP
UDP port forwarding is a bit more complicated. We will need to convert the packets from UDP to TCP on the SSH client side, tunnel it over the SSH connection and convert it back from TCP to UDP on the SSH server side. We will tunnel UDP port 53 on
server02 to UDP port 53000 on the
client. We will use TCP port 8000 for the SSH tunnel.
The packet flow is shown in the diagram below.
DNS requests sent to UDP port 53000 are relayed to TCP port 8000 on the
client computer. The packet is then tunneled via the SSH connection. On
server01, at the end of the SSH tunnel, the TCP packet on port 8000 is converted back to UDP and gets forwarded to
server02 on UDP port 53. The reply flows back in a similar fashion.
Setup the SSH tunnel on TCP port 8000 by making a SSH connection from the
client computer to
client$ ssh -L 8000:127.0.0.1:8000 user@server01
The above command will instruct
ssh program to listen on TCP port 8000 on the
client computer and forward it to TCP port 8000 on
server01 local interface (127.0.0.1).
Next, configure TCP-UDP relay on
server01$ socat tcp4-listen:8000,reuseaddr,fork udp:server02:53
The above command instructs
socat to listen on TCP port 8000 and redirect it to UDP port 53 towards
Next, we also need to configure a UDP-TCP relay on
client computer using
client$ socat -T15 udp4-recvfrom:53000,reuseaddr,fork tcp:localhost:8000
This time we are telling
socat to listen on UDP port 53000 and redirect it to TCP port 8000 on the loopback interface. The SSH tunnel will deliver the packets on TCP port 8000 to the server (
Once done, we can test the tunnel by performing a simple DNS query on the
client computer. We will need to specify the nameserver IP address of
127.0.0.1 as well as the port number of
53000 to the DNS query tool.
client$ dig @127.0.0.1 -p 53000 google.com