What is this about?
Scenario: You want an SSH connection between 2 computers, called PC_A and PC_C, with PC_A being the initiator. For some reason this is not directly possible but you have a third computer, PC_B, accessible for both PC_A and PC_C. Then you are fine, it's easy to set up your reverse channel!
Note that it is assumed that on both computers the same username is used ($USER should be identical) and the ports used are not blocked.
Acknowledgment: Alexander Klyubin had the idea and provided part of the scripts shown.
Todo for PC_B, the middle computer
The general idea is to have the receiving computer PC_C checking for the presence of a file and, if present, open a connection to PC_B (see below). The following script should be put on PC_B; it creates this file and tries to open the connection to PC_C. After the session ends the file is removed so that PC_C can close the session again.
Later you will log in from PC_A to PC_B and then run the following script (I suggest to call itconnect.sh
) to get into PC_C.
Note that on PC_B there needs to be atmp
and.ssh
directory in the users home directory.
On PC_C executecat ~/.ssh/known_hosts | grep localhost
, which should give you something likelocalhost ssh-rsa AACAB7NymadGcf8AACABIwAACIEA3iF93cGjJ...
Copy this line and put it into the same file (~/.ssh/known_hosts
) on PC_B!
#! /bin/sh if [ "$1" != "-nokill" ]; then echo "Use '$0 -nokill' if this is not the master session and you don't want to close afterwards!" fi echo >tmp/$USER xxx=1 while [ $xxx -eq 1 ]; do a=$(date +%s) ssh -p 54321 localhost b=5 c=`echo $a + $b | bc` d=$(date +%s) $(test $c -le $d) xxx=$? if [ $xxx -eq 1 ]; then echo "A little patience please..." $(sleep 3) fi done if [ "$1" != "-nokill" ]; then rm tmp/$USER echo Session complete and closed. exit fi echo Session complete but access still open.
Todo for PC_C, the receiving computer
Following you find the script
tunnel.sh
which you have to run as a cron job on PC_C so that PC_C can initiate a connection to PC_B when necessary. Note that for checking whether the file exists (the "scp ..." line) you need to place a key on PC_B allowing PC_C to login without a password being asked (see SSH authentication with Keychain and hostkeys for detailed instructions).
Note that in this script you have to replace PC_B with the name or IP of your middle computer!#! /bin/sh scp -q PC_B:tmp/$USER /home/$USER/tmp/ >/dev/null 2>&1 error_code="$?" if [ "$error_code" != "0" ]; then echo "`date`: No need to open the tunnel" #if Tunnel exists kill it TTT=$(ps -efl | grep 54321: | grep -v grep) if [ "$TTT" != "" ]; then DOIT=$(ps -efl | grep 54321: | grep -v grep | egrep -o "$USER *[0-9]+" | egrep -o [0-9]+) echo "POS2 $DOIT" kill -9 $DOIT fi exit fi ps -ef | grep -v grep | grep "ssh -N -R 54321:localhost:22" >/dev/null 2>&1 error_code="$?" if [ "$error_code" == "0" ]; then echo "`date`: Tunnel already up and running" exit fi echo "`date`: Setting up tunnel" ssh -N -R 54321:localhost:22 PC_B &Do not forget to make this file executable (chmod +x tunnel.sh
)!
To run it every minute put the script in $HOME/bin/tunnel.sh and add the cronjob like this:
execute: "crontab -e"
add this line to the cron file: "*/1 * * * * $HOME/bin/tunnel.sh >>$HOME/tmp/tunnel.log 2>&1"