Open In App

How to Create SSH Tunneling or Port Forwarding in Linux?

Last Updated : 30 Jan, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

SSH is a secure shell standard client utility for Linux. It is used to establish secure connections to remote (or even local) ssh servers. But some programs are not designed flexible enough to be processed by ssh trivial way: the program can work with local connections only or some related network addresses be hard to code defined.  That is why SSH contains several options to redirect secure traffic to match use cases like that. Let’s go from case to case to see how does it work.
 

Forwarding  port at localhost

First case: we have an application that is hardcoded to connect to the localhost server with a specified port. Our goal is to use a remote server with another port instead. Another point here is: transmit data secure (encrypted) way. Code for localhost test from client and server-side followed next.

Local redirecting overview:
 

redirecting schema

At this schema, the server runs on the remote host at port 9000. But our client application expects it at localhost port 5000 only. Let’s expect it hardcoded in-app code. 

Forwarding  port at localhost script body:

#!/usr/bin/env bash
nc -l 9000 &
PID0=$!
ssh alexey@localhost -L 5000:localhost:9000 sleep 4 &
PID1=$!
sleep 1
echo done | nc -N localhost 5000
sleep 1
kill -9 $PID0 $PID1 2> /dev/null

 Forwarding  port at localhost script executing console:

script body area in yellow rectangle, output followed next to the rectangle

At the first string we create a TCP server at port 9000 in background mode (look that command ends with ‘&’ symbol). Next, we store server PID (process identity) at the local variable PID0. Then we run an ssh session to our own host with options that redirect connections incoming to local port 5000 to remote host 9000.  -L option syntax: -L <local host port>:<remote host>:<remote host port to redirect connections from localhost port>. We run a session with the “sleep 4” command in background mode to turn on redirecting for 4 seconds and end the session then. Next, we store the PID of the ssh session to the PID1 variable. Next line we sleep for 1 second to be sure that the server starts and the ssh session started. Next line we send “done” text to port 5000 by using of nc command and close the session with -N. Next, we sleep for 1 second to process traffic redirection over a secure tunnel and get “done” at the output. Then sanity kill of run server and ssh tunneled session followed. As you can see it is possible to use any <remote server> against <localhost> in this script – to be able to work with remote server secure way. Even if the client app is not designed to work with it.

Forwarding  port at the remote host

In case of remote servers have no “white” address and works over NAT (network address translation) we still need to have a secure tunnel. But remote destinations in this case can be not detected. Instead is possible to arrange a secure connection to a well-known central host. And redirect ports at the central host for these clients to connect peer over NAT. The difference is to make port 5000 at remote host available to redirect to local port 9000 at our host. 
 

redirecting schema

Forwarding  port at remote host  script body:

#!/usr/bin/env bash
nc -l 9000 &
PID0=$!
ssh alexey@localhost -L 5000:localhost:9000 sleep 4 &
PID1=$!
sleep 1
echo done | nc -N localhost 5000
sleep 1
kill -9 $PID0 $PID1 2> /dev/null

Forwarding  port at remote host script executing console:

script body area in yellow rectangle, output followed next to the rectangle

All actions at the script are equal to the previous case. But the meaning of redirection is different. We redirect remote host port 5000 to localhost port 9000 and create a secure tunnel to pass connections from remote host port 5000 to localhost port 9000. That makes it available to work in a secure way even with hosts over NAT.

Ssh interface tunneling
 

secured apps interconnections description

Another option to use ssh is to expose the IP address of securely connected peer by tunneling interfaces using at ssh. We expose IP address over tun interface at localhost to work with the server on the remote host. Example next will discover details.

Ssh interface tunneling script:

#!/usr/bin/env bash
(ssh -tt root@192.168.144.207 -w 2:2 << EOF
ifconfig tun2 10.1.1.1/24 pointopoint 10.1.1.2 up
nc -l 10.1.1.1 9000
EOF
) 2>/dev/null | grep ok &
PID=$!
sleep 1
ifconfig tun2 10.1.1.2/24 pointopoint 10.1.1.1 up
echo ok | nc -N 10.1.1.1 9000

Ssh interface tunneling script executing console:

script body area in yellow rectangle, output followed next to the rectangle

In the first string, we create an ssh connection to the remote host. It is very important to be root on running the script: it will create virtual tunneling (tun) interfaces at the system. Only root able to make it legal. Option -w has following syntax: -w <tun interface index on localhost, tun interface index on remote port>. These particular interfaces are mapped to each other secure way – session comes to localhost tun interface at port be secure redirected to remote host mapped tun interface at the same port. Next string we use ifconfig utility to set up some internal addresses for remote tun-s and turn it on. Second address (pointopoint) points to peer ip to be used on tunneling. Next string we start the nc TCP server on port 9000. Please pay attention to the ip address for the server: it matches to address of the corresponding tun interface. Next string we ignore the errors and select only ok containing message if any. The rest of the script strings are used on the local side. We sleep for 1 second to be sure in tunnel completeness. Next, we set IP addresses for our local tun interface to match peer ip address parameters (first and second addresses match at peer and localhost). Same command we turn interface up. The next command starts tcp client that establishes a connection to the local tun interface on specific port and sends an “ok” message. As we can remember – the server started at another host at the same port. Last string at script: we kill ssh with tunnel and server. If you have several servers on the same address – this approach can be useful cause it needs to be set up just one time for several ports. 


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads